中断 2》上下半部

2020阅读 0评论2015-06-13 lsxuan驱动
分类:嵌入式

0>  概述:

    中断分成上下半部目的只有1个:使cpu快速处理完中断。
    其实质是把一些事情放到上半部快速执行完, 另一些事情放到下半部,cpu有空了再执行。

实现中中断下半部的方法:

                                    1》 小任务机制     --->tasklet_struct

                                    2》 工作队列机制---->workqueue_struct 

Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

1>  tasklet:

struct tasktlet_struct

{

        stucut tasklet_struct *next;

        unsigned long state;

        atomic_t count;

        void (*fun) (unsigneg long);   //中断下半部函数

        unsigned long date;              

}

1》 1.定义并初始化:DECLARE_TASKLET(name , fun, date); 

                                    @name:tasklet名字。

                                    @fun:下半部函数。

                                    @date:传给fun的参数。

    2. 先定义后初始化:
                                       struct tasklet_struct tsk        

                                       void tasklet_init ( struct taskle_struct *t,     //&tsk

                                                                     void (*fun) (unsigned long),   //下半部函数

                                                                     unsigned long date    //传给下半部函数的参数

                                       )

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

 2》调度下半部:
                         /*将初始化的tasklet加到一个链表中, cpu空闲时调度它, 从而调用下半部函数*/

                          void tasklet_schedule(struct tasklet_struct *tasklet);

                                      

NOTE: tasklet工作在中断上下文,所以不可睡眠。in_interrupt()函数判断。

Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

2>工作队列

 typedef     void (*work_func_t)(struct work_struct *work);

struct work_struct {

         atomic_long_t data;

         struct list_head entry;

         work_func_t func;   //下半部函数

 #ifdef CONFIG_LOCKDEP

         struct lockdep_map lockdep_map;

 #endif

 };

1》 共享队列:使用内核提供的共享的默认工作队列system_wq

/linux-3.5/include/linux/workqueue.h

    1》 》定义:struct work_struct wk;

    2》》初始化:INIT_WORK(struct work_struct *work, //&wk

                                                     void (*fun)(void *)  //下半部函数

                                                );  

    3》》调度下半部:
/*将初始化的work_struct 添加到系统队列system_wq中, cpu空闲时调work_struct,从而调下半部函数*/

        int   schedule_work(struct work_struct *work)

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

2》创建队列:   使用自己定义的队列

/linux-3.5/include/linux/workqueue.h

    1>> 创建队列:

struct workqueue_struct *my_wq;

my_wq = create_workqueue(“lsx_wq”);

    2>>  定义并初始化 work_struct:  //与分步初始化一样

 #define DECLARE_WORK(n, f)                       \

        struct work_struct n = __WORK_INITIALIZER(n, f)

    3>> 调度下半部:
/*将初始化的work_struct 添加到我们队列my_wq中, cpu空闲时调work_struct,从而调下半部函数*/

                         int queue_work(

                                                struct workqueue_struct *wq,    //my_wq,自己的队列

                                                     struct work_struct *work     //初始化的work_struct n

                        );

 

 

 


 

 


上一篇:中断 1》 初识
下一篇:锁 1>互斥锁