首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

linux 中断机制的处理过程(4)

linux 中断机制的处理过程(4)

使用tasklet作为下半部的处理中断的设备驱动程序模板如下:
/*定义tasklet和下半部函数并关联*/
void my_do_tasklet(unsigned long);
DECLARE_TASKLET(my_tasklet, my_tasklet_func, 0);
/*中断处理下半部*/
void my_do_tasklet(unsigned long)
{
  ……/*编写自己的处理事件内容*/
}
/*中断处理上半部*/
irpreturn_t my_interrupt(unsigned int irq,void *dev_id)
{
……
tasklet_schedule(&my_tasklet)/*调度my_tasklet函数,根据声明将去执行my_tasklet_func函数*/
……
}
/*设备驱动的加载函数*/
int __init xxx_init(void)
{
……
/*申请中断, 转去执行my_interrupt函数并传入参数*/
result=request_irq(my_irq,my_interrupt,IRQF_DISABLED,"xxx",NULL);
……
}
/*设备驱动模块的卸载函数*/
void __exit xxx_exit(void)
{
……
/*释放中断*/
free_irq(my_irq,my_interrupt);
……
}
工作队列的实现
工作队列work_struct结构体,位于/include/linux/workqueue.h

typedef void (*work_func_t)(struct work_struct *work);
struct work_struct {
      atomic_long_t data; /*传递给处理函数的参数*/
#define WORK_STRUCT_PENDING 0/*这个工作是否正在等待处理标志*/              
#define WORK_STRUCT_FLAG_MASK (3UL)
#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
      struct list_head entry;  /* 连接所有工作的链表*/
      work_func_t func; /* 要执行的函数*/
#ifdef CONFIG_LOCKDEP
      struct lockdep_map lockdep_map;
#endif
};
这些结构被连接成链表。当一个工作者线程被唤醒时,它会执行它的链表上的所有工作。工作被执行完毕,它就将相应的work_struct对象从链表上移去。当链表上不再有对象的时候,它就会继续休眠。可以通过DECLARE_WORK在编译时静态地创建该结构,以完成推后的工作。
#define DECLARE_WORK(n, f)                                 \
      struct work_struct n = __WORK_INITIALIZER(n, f)
而后边这个宏为一下内容:
#define __WORK_INITIALIZER(n, f) {                      \
      .data = WORK_DATA_INIT(),                            \
      .entry      = { &(n).entry, &(n).entry },                    \
      .func = (f),                                        \
      __WORK_INIT_LOCKDEP_MAP(#n, &(n))                   \
      }
其为参数data赋值的宏定义为:
#define WORK_DATA_INIT()       ATOMIC_LONG_INIT(0)
这样就会静态地创建一个名为n,待执行函数为f,参数为data的work_struct结构。同样,也可以在运行时通过指针创建一个工作:
INIT_WORK(struct work_struct *work, void(*func) (void *));
这会动态地初始化一个由work指向的工作队列,并将其与处理函数绑定。宏原型为:
#define INIT_WORK(_work, _func)                                        \
      do {                                                        \
             static struct lock_class_key __key;                 \
                                                              \
             (_work)->data = (atomic_long_t) WORK_DATA_INIT();  \
             lockdep_init_map(&(_work)->lockdep_map, #_work, &__key, 0);\
             INIT_LIST_HEAD(&(_work)->entry);                 \
             PREPARE_WORK((_work), (_func));                         \
      } while (0)
继承事业,薪火相传
返回列表