linux 底半部 软中断_Linux内核提供了三种不同形式的中断底半部实现机制:软中断、tasklet和工作队列。...

感谢博主讲的关于为什么需要中断底半部,什么是中断底半部

下半部运行时是允许中断请求的,而上半部运行时是关中断的

头文件:

/**

*工作的数据类型是结构体类型

*/

struct work_struct {

atomic_long_t data;

struct list_head entry;

work_func_t func;

#ifdef CONFIG_LOCKDEP

struct lockdep_map lockdep_map;

#endif

};

/**

*功能:将_func指向的工作处理函数,赋值给_work结构体中的fun函数指针,即创建工作结构,给工作结构填充一个处理函数。

*_work的类型是 struct work_struct

*_func的类型是函数指针,typedef void (*work_func_t)(struct work_struct *work);

*/

INIT_WORK(_work, _func)     这是个宏定义

在大多数情况下, 并不需要自己建立工作队列,而是只定义工作, 将工作结构挂接到内核预定义的事件工作队列中调度, 在kernel/workqueue.c中定义了一个静态全局量的工作队列static struct workqueue_struct *keventd_wq,keventd_wq由内核自己维护,创建,销毁。这样work马上就会被调度,一旦其所在的处理器上的工作者线程被唤醒,它就会被执行。

/**

*功能:调度工作结构, 将工作结构添加到全局的事件工作队列keventd_wq

*/

bool schedule_work(struct work_struct *work);static void work_handler(struct work_struct *work)

{

printk("--%s--%s--&d--\n",__FILE__,__func__,__line__);

}

struct work_struct wq;

INIT_WORK(&wq,work_handler);  //这个放到内核模块加载函数中

schedule_work(&wq);           //这个放到中断处理函数中去

Tasklet    头文件:struct tasklet_struct

{

struct tasklet_struct *next;

unsigned long state;

atomic_t count;

void (*func)(unsigned long);  //处理函数

unsigned long data;              //给处理函数的参数

};

/**

*功能:定义并初始化一个struct tasklet_struct结构体类型的变量,并绑定中断处理函数(也可以说是底半部函数)

*name:数据类型是struct tasklet_struct

*func函数指针指向一个void (*func)(unsigned long);的处理函数

*data给处理函数的参数

*/

#define DECLARE_TASKLET(name, func, data)   struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(0), func, data }//这是个宏,完成了定义及初始化

/**

*功能:调用自己的中断处理程序

*/

void tasklet_schedule(struct tasklet_struct *t);

你可能感兴趣的:(linux,底半部,软中断)