Linux驱动开发-中断分层机制_工作队列 笔记 7
2016-08-29 11:46
721 查看
中断分层机制_工作队列
1.工作队列概念:a) 任务推后执行 b) 被推后的任务由“内核线程”执行 c) 允许重新调度和睡眠 d) 这些被推后的工作组成一个双向链表,既称为工作队列
2.运行机制
注释:
1.每个CPU都有独立的工作队列 2.每个工作队列形成一个双向链表 3.执行时由内核的一个线程去处理,执行的时机不确定;只有在线程觉得CPU有能 力处理时才去去工作队列的内容去执行
3.工作队列的相关结构
struct work_struct { atomic_long_t data; /*原子类型数据*/ struct list_head entry; /*链表入口*/ work_func_t func; /*工作函数*/ #ifdef CONFIG_LOCKDEP struct lockdep_map lockdep_map; #endif }; struct workqueue_struct;/*好多成员*/
4.工作队列实现过程和相关函数:
法一:交给内核创建默认工作队列
a) 定义工作队列
struct work_struct xx_wq;
b) 定义工作函数
static work_func_t work_fun(unsingend int xxx)
c) 初始化工作队列,将工作队列与处理函数绑定
INIT_WORK(&xx_wq, work_fun);
d) 提交工作到默认队列;既工作的创建由内核自行处理
schedule_work(&xx_wq);
法二:手工创建工作队列
a) 定义工作队列
struct work_struct work; /*定义工作*/
workqueue_struct* wq; /*定义的队列*/
b) 定义工作函数
static work_func_t work_fun(unsingend int xxx)
c) 创建名字为 “mywork” 的工作队列
wq = create_workqueue(“mywork”);
d) 初始化工作队列
INIT_WORK(&xx_wq, work_fun);
e) 提交工作队列
int queue_work(wq, $work);
5.工作队列在中断分层技术的应用
/*1.定义结构体*/ struct work_struct xx_wq; /*2.编写底半部函数,既工作函数*/ void xxx_do_work(unsigned long x) { ... } /*4.中断处理顶半部*/ static irqreturn_t xxx_interrupt(int irq, void *dev_id) { ... /*提交工作 并启动调度*/ schedule_work(&xx_wq); ... } /*5.模块加载*/ module_init(xxxx) { ..... /*申请中断*/ /*初始化工作队列,将工作队列与处理函数绑定,这个可以在open函数初始化*/ INIT_WORK(&xx_wq,xxx_do_work); ...... } /*6.模块卸载*/ module_exit(yyyy) { /*释放中断*/ }
工作队列模块测试
/* author : hntea date: 2016/3/14 function : key interrupt work test */ #include<linux/module.h> #include<linux/init.h> #include<linux/miscdevice.h> #include<linux/fs.h> #include<linux/types.h> #include<linux/io.h> #include<linux/interrupt.h> #define DEV_MINIR 11 /*自己随便取咯*/ #define DEV_NAME "key" /*自己随便取咯,该设备名会在 /dev目录下生成相应的设备文件*/ #define KEY_GPH0CON 0xE0200C00 /*key_1 /key_2 EXIT0/1*/ /*定义 work */ struct work_struct work1; /****************************************** 函数名: key_hardinit 函数功能:硬件初始化 ******************************************/ void key_hardinit(void) { unsigned int *key_ioconfig = 0; unsigned int *irq_mask = 0; unsigned int *irq_enable = 0; unsigned int temdata = 0; /*GPIO初始化 32位寄存器*/ key_ioconfig = ioremap(KEY_GPH0CON,4); /*按键1和2设置成外部中断*/ temdata = ioread32(key_ioconfig); temdata &= (~0xff); temdata |= 0xff; iowrite32(temdata,key_ioconfig); /*中断控制初始化*/ } /****************************************** 中断底半部用工作队列实现 ******************************************/ /*定义服务函数,任务提交后只执行一次*/ static void my_work1(struct work_struct *work) { printk("I am work1\n"); printk("I am work1,extern interrupt rase!\n"); } /* 函数名: key_interrupt 函数功能:中断服务函数入口 */ static irqreturn_t key_interrupt (int irq, void *dev_id) { /*1、顶部,硬件操作*/ /*2、底部,交个工作队列来处理*/ schedule_work(&work1); return 0; } /* 函数名: key_open 函数功能:文件操作 */ int key_open(struct inode *inode, struct file *filp) { key_hardinit(); return 0; } /* 函数名: 函数功能:文件操作 */ struct file_operations key_fop ={ .open = key_open, }; struct miscdevice key={ .minor = DEV_MINIR , .name = DEV_NAME, .fops = &key_fop, }; static int keyInit(void) { int ret = 0; /*1、注册设备文件*/ ret = misc_register(&key); /*2、注册中断号,IRQF_TRIGGER_FALLING中断号在 : linux/arch/arm/mach-s5pv210/include/mach/irqs.h文件中有定义*/ ret = request_irq(IRQ_EINT0,key_interrupt,IRQF_TRIGGER_FALLING, DEV_NAME, 0); /*3.初始化工作*/ INIT_WORK(&work1,my_work1); printk("ret val is:%d\n",ret); if(ret < 0) { printk("EXINT0 request fail!\n"); }else{ printk("EXINT0 request sucess!\n"); } return 0; } static void keyExit(void) { int ret = 0; /*注销中断*/ free_irq(IRQ_EINT0, 0); /*注销混杂设备*/ ret = misc_deregister(&key); /*注销设备*/ } MODULE_LICENSE("GPL"); MODULE_AUTHOR("Hntea"); module_init(keyInit); module_exit(keyExit);
相关文章推荐
- Linux驱动开发-中断分层机制笔记 6
- linux驱动开发之输入子系统编程(一)使用工作队列实现中断下半部
- Linux驱动开发-8、中断分层机制_软中断
- Linux驱动开发六:按键中断+poll机制
- Linux2.6中断下半部分的三种实现机制---软中断/tasklet/工作队列
- 按键驱动程序设计---混杂设备、中断分层处理、工作队列、阻塞型驱动
- Linux驱动开发-中断处理模型笔记 5
- Linux 驱动之中断下半部之工作队列
- linux驱动学习之工作队列机制
- Linux2.6中断下半部分的三种实现机制---工作队列 .
- Linux设备驱动开发详解--笔记10--中断与时钟
- 【嵌入式Linux学习七步曲之第五篇 Linux内核及驱动编程】中断服务下半部之工作队列详解
- Linux2.6中断下半部分的三种实现机制---工作队列
- Linux下驱动:分层、分离机制学习笔记
- Android深度探索:HAL与驱动开发学习笔记--工作队列
- 《Linux设备驱动开发详解》-- Linux中断处理底半部机制(tasklet、工作队列和软中断)
- 【Linux开发】linux设备驱动归纳总结(六):3.中断的上半部和下半部——工作队列
- linux驱动开发学习--对中断和内核定时器的学习笔记
- linux 触摸屏驱动中断下半部实现-工作队列
- Linux中断分层工作队列学习