Samsung_tiny4412(驱动笔记07)----spinlock,semaphore,atomic,mutex,completion,interrupt

发布者:EternalBliss最新更新时间:2025-01-15 来源: cnblogs关键字:Samsung  tiny4412 手机看文章 扫描二维码
随时随地手机看文章

        }

        ...

六. interrupt接口:

    1. 查看系统中断处理信息: cat /proc/interrupts

    2. 申请并注册中断处理函数:

        static inline int __must_check request_irq( unsigned int irq, irq_handler_t handler,

                                      unsigned long flags, const char *name, void *dev_data);

    3. 释放中断,并取消中断处理函数:

        void free_irq(unsigned int irq, void *dev_data);

    4. 代码执行环境:

        1. 中断上下文:         in_interrupt(); ---> 判断执行环境是否是中断上下文

            1. 软中断上下文:   in_softirq();   ---> 判断执行环境是否是soft irq

            2. 外部中断上下文: in_irq();       ---> 判断执行环境是否是硬件中断处理环境

        2. 进程上下文.

    5. 共享中断方法:

        1. request_irq()指定共享标志 IRQF_SHARED;

        2. request_irq()最后一个参数不能传递NULL,传递当前驱动全局变量地址;

    6. 将系统gpio编号转换成对应的外部中断: gpio_to_irq();

    7. spinlock中断中使用Demo:

        ...

        struct test_s {

            struct file_operations fops;

            spinlock_t lock;

            int major;

        };

        typedef struct test_s test_t;

        ...

        int critical(const char *s, spinlock_t *lock)

        {

            int i;

            unsigned long flag;

            static int cnt = 0;

        

            /*spin_lock(lock);*/

            /*local_irq_disable();*/

            /*local_irq_save(flag);*/

            /*spin_lock_irq(lock);*/

            spin_lock_irqsave(lock, flag);

        

            for(i = 0; i < 3; i++)

            {

                printk('count = %d, %s', cnt++, s);

                mdelay(1000);

            }

        

            spin_unlock_irqrestore(lock, flag);

            /*spin_unlock_irq(lock);*/

            /*local_irq_restore(flag);*/

            /*local_irq_enable();*/

            /*spin_unlock(lock);*/

        

            return 0;

        }

        

        static irqreturn_t irq_handler(int irq, void *arg)

        {

            test_t *p = arg;

        

            critical('irqn', &p->lock);

        

            return IRQ_HANDLED;

        }

        

        static ssize_t test_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)

        {

            int ret;

            char kbuf[count + 1];

            test_t *p = file->private_data;

        

            ret = copy_from_user(kbuf, buf, count);

            if(ret)

                return -EFAULT;

            kbuf[count] = '';

        

            if(critical(kbuf, &p->lock))

                return -EAGAIN;

        

            return count;

        }

        ...

        int __init test_init(void)

        {

            int ret;

        

            spin_lock_init(&test.lock);

        

            ret = register_chrdev(test.major,

                    DEV_NAME, &test.fops);

            if(ret > 0)

            {

                test.major = ret;

                printk('major = %dn', test.major);

                ret = 0;

            }

        

            ret = request_irq(IRQ_EINT(26), irq_handler,

                              IRQF_TRIGGER_FALLING,

                              'key1', &test);

            if(ret)

                unregister_chrdev(test.major, DEV_NAME);

        

            return ret;

        }

        ...


七. 按键驱动大致写法:

    #include <linux/module.h>

    #include

    #include

    #include

    #include

    #include

    #include

    

    #define DEV_NAME    'test'

    

    struct timer_list timer;

    struct btn_desc {

        int gpio;

        int num;

        char *name;

    };

    

    int ev_key = 0;

    char key_state[] = {0, 0, 0, 0};

    DECLARE_WAIT_QUEUE_HEAD(wq);

    

    struct btn_desc btn[] = {

        { EXYNOS4_GPX3(2), 0, 'key1' },

        { EXYNOS4_GPX3(3), 1, 'key2' },

        { EXYNOS4_GPX3(4), 2, 'key3' },

        { EXYNOS4_GPX3(5), 3, 'key4' }

    };

    

    void timer_main(unsigned long data)

    {

        ev_key = 1;

        wake_up_interruptible(&wq);

        printk('timer_main.n');

    }

    

    static irqreturn_t irq_handler(int irq, void *arg)

    {

        struct btn_desc *key = arg;

    

        key_state[key->num] = 1;

    

        mod_timer(&timer, jiffies + 20);

    

        return IRQ_HANDLED;

    }

    

    static int test_open(struct inode *inode, struct file *file)

    {

        int i, irq, ret;

    

        for(i = 0; i < ARRAY_SIZE(btn); i++)

        {

            //irq = IRQ_EINT(26+i); //irq可以通过这种方法获得

            irq = gpio_to_irq(btn[i].gpio);

            ret = request_irq(irq, irq_handler, IRQF_TRIGGER_FALLING | IRQF_SHARED,

                        btn[i].name, &btn[i]);

            if(ret)

                break;

        }

    

        if(ret)

        {

            for(--i; i >= 0; i--)

            {

                irq = gpio_to_irq(btn[i].gpio);

                free_irq(irq, &btn[i]);

            }

            return ret;

        }

    

        return 0;

    }

    

    static int test_close(struct inode *inode, struct file *file)

    {

        int i, irq;

    

        for(i = 0; i < ARRAY_SIZE(btn); i++)

        {

            irq = gpio_to_irq(btn[i].gpio);

            free_irq(irq, &btn[i]);

        }

    

        return 0;

    }

    

    static ssize_t test_read(struct file *file, char __user *buf, size_t count, loff_t *pos)

    {

        int ret;

    

        if(count > ARRAY_SIZE(key_state))

            count = ARRAY_SIZE(key_state);

    

        while(!ev_key)

        {

            if(file->f_flags & O_NONBLOCK)

                return -EAGAIN;

[1] [2] [3] [4]
关键字:Samsung  tiny4412 引用地址:Samsung_tiny4412(驱动笔记07)----spinlock,semaphore,atomic,mutex,completion,interrupt

上一篇:Samsung_tiny4412(驱动笔记08)----jiffies,timer,kthread,workqueue,tasklet
下一篇:Samsung_tiny4412(驱动笔记06)----list_head,proc file system,GPIO,ioremap

推荐阅读最新更新时间:2026-03-15 03:39

Samsung_tiny4412(驱动笔记01)----linux 3.5,U-Boot,Busybox,SD卡启动环境搭建
/*********************************************************************************** * * linux 3.5,U-Boot,Busybox,SD卡启动环境搭建 * * 声明: * 1. 本系列文档是在vim下编辑,请尽量是用vim来阅读,在其它编辑器下可能会 * 不对齐,从而影响阅读. * 2. 以下所有的shell命令都是在root权限下运行的; * 3. minicom(U-Boot)指的是用minicom连接开发板做为U-Boot的终端; * 4. 文中在需
[单片机]
Samsung_tiny4412(驱动笔记03)----字符设备驱动基本操作及调用流程
/*********************************************************************************** * * 字符设备驱动基本操作及调用流程 * * 声明: * 1. 本系列文档是在vim下编辑,请尽量是用vim来阅读,在其它编辑器下可能会 * 不对齐,从而影响阅读. * 2. 以下所有的shell命令都是在root权限下运行的; *******************************************************************************
[单片机]
Samsung_tiny4412(驱动笔记04)----volatile,container_of,file_operations,file,inode
/*********************************************************************************** * * volatile,container_of,file_operations,file,inode * * 声明: * 1. 本系列文档是在vim下编辑,请尽量是用vim来阅读,在其它编辑器下可能会 * 不对齐,从而影响阅读. * 2. 本文的结构体的注释主要是参考网络上的解释,几乎无任何个人理解,主要是为后续 * 代码编辑提供参考. ***********************
[单片机]
tiny4412学习笔记-将uboot、zImage、文件系统烧到emmc中
1、首先还是要将u-boot写入SD卡中从SD卡启动。 使用读卡器将SD插入电脑中,使用umount卸载u盘, fdisk -l显示其挂载点为 /dev/sdb1 切换到/home/bunfly/images/uboot_tiny4412/sd_fuse/tiny4412目录下,执行./sd_fusing.sh /dev/sdb 拨动最右边开关选择从SD卡启动。 附加编译过程:   1.进入开发板提供的源码文件包,解压uboot源码包。   cd /home/bunfly/source_code/   tar xf uboot_tiny4412-20130729.tgz   2.进入uboot文件夹,更改uboot中t
[单片机]
<font color='red'>tiny4412</font>学习<font color='red'>笔记</font>-将uboot、zImage、文件系统烧到emmc中
tiny4412 解决内核编译版本号问题
内核版本: linux-3.5 开发板: tiny4412 作者:彭东林 邮箱:pengdonglin137@163.com 问题: 由于我使用 git 管理内核代码,导致编译完成后内核版本变成了如下形式: Linux version 3.5.0-FriendlyARM-g5291689 自带的 ko 文件只认识 Linux version 3.5.0-FriendlyARM,所以导致 ko 加载失败。 解决办法一 重新把驱动模块编译一遍 解决办法二 Make menuconfig --- General setup --- Automatically append version information to
[单片机]
Tiny4412 支持 adb reboot-bootloader
硬件版本: Tiny4412ADK + S700 4GB u-boot 版本: u-boot-2010-12 linux版本: Linux-3.0.8 版本一 支持 adb reboot bootloader patch:http://pan.baidu.com/s/1i3KfCI5 版本二 支持按住K1键,然后开机,进入fastboot模式 patch: http://pan.baidu.com/s/1hqgmnQ0
[单片机]
tiny4412 串口驱动分析一 --- u-boot中的串口驱动
开发板:tiny4412ADK+S700 4GB Flash 主机:Wind7 64位 虚拟机:Vmware+Ubuntu12_04 u-boot:U-Boot 2010.12 Linux内核版本:linux-3.0.31 Android版本:android-4.1.2 我们以tiny4412为例分析串口驱动,下面我们从u-boot开始分析,然后再分析到Linux。 串口初始化 关于这部分代码流程参考件: tiny4412 u-boot 启动.pdf ,这里主要分析函数:uart_asm_init 在初始化串口驱动之前已经进行了系统时钟以及内存的初始化。下面的代码取自board/samsung/tiny441
[单片机]
<font color='red'>tiny4412</font> 串口<font color='red'>驱动</font>分析一 --- u-boot中的串口<font color='red'>驱动</font>
tiny4412学习(四)之移植linux-设备树(1)设备树基础知识及GPIO中断
硬件平台:tiny4412 系统:linux-4.4 文件系统:busybox-1.25 编译器: arm-none-linux-gnueabi-gcc(gcc version 4.8.3 20140320) uboot:友善自带uboot. 一、DTS引入 1.什么是DTS?为什么要引入DTS? DTS即Device Tree Source设备树源码,DeviceTree是一种描述硬件的数据结构,它起源于OpenFirmware (OF)。 在Linux2.6中,ARM架构的板极硬件细节过多地被硬编码在arch/arm/plat-xxx和arch/arm/mach-xxx,比如板上的platform设备、resource、i
[单片机]
<font color='red'>tiny4412</font>学习(四)之移植linux-设备树(1)设备树基础知识及GPIO中断
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved