- 论坛徽章:
- 0
|
1.tasklet
tasklet是为了方便得处理中断下半部事宜而设计的.一般使用如下:
定义一个tasklet:
DECLARE_TASKLET(tasklet_name,tasklet_func,data);
//定义一个tasklet结构tesklet_name,与tasklet_func(data)函数相关联
static void tasklet_func(unsigned long data)
{
//do the bottom half stuff here.........
}
在中断处理函数中,只需要做如下调用,就可以使tasklet在适当的时候调用:
tasklet_schedule(&tasklet_name);
DECLARE_TASKLET_DISABLED(name,function,data); //与DECLARE_TASKLET类似,但等待tasklet被使能
tasklet_enable(struct tasklet_struct *); //使能tasklet
tasklet_disble(struct tasklet_struct *); //禁用tasklet
tasklet_init(struct tasklet_struct *,void (*func)(unsigned long),unsigned long);
//类似DECLARE_TASKLET()
tasklet_kill(struct tasklet_struct *); // 清除指定tasklet的可调度位,即不允许调度该tasklet
2.在驱动中实现下半部的另外一种做法,可以利用工作队列(work queue)
work queue机制允许我们将要延后执行的任务在放在工作队列中,然后延后在由work queue产生的一个线程
中运行.
第一步:创建一个工作队列
struct workqueue_struct * wq = create_workqueue("my_work_queue");
随着我们创建一个工作队列,会有cpu个内核线程产生,名为 my_work_queue/0, my_work_queue/0....
如果只想创建一个内核线程,则使用create_signalthread_workqueue();
第二步:创建一个工作
struct work_struct my_work;
INIT_WORK(&my_work, (void (*)(void *))my_work_func, data)
第三步:为了执行工作,需要把工作放到工作队列当中去.(比如工作是一个下半部,我们可以在中断里面做这件
事情)
queue_work(my_work_queue, my_work);
queue_delayed_work(my_work_queue, my_work, 20);
注意,没必要为每一个用途都创建一个work_queue,内核中已经有一些创建好的work_queue供大家使用,例如名字为"event"的work_queue.
2.timer
Linux内核中定义了一个timer_list结构,我们在驱动程序中可以利用之:
struct timer_list {
struct list_head list;
unsigned long expires; //定时器到期时间
unsigned long data; //作为参数被传入定时器处理函数
void (*function)(unsigned long);
};
下面是关于timer的API函数:
增加定时器
void add_timer(struct timer_list * timer);
删除定时器
int del_timer(struct timer_list * timer);
修改定时器的expire
int mod_timer(struct timer_list *timer, unsigned long expires);
使用定时器的一般流程为:
(1)timer、编写function;
(2)为timer的expires、data、function赋值;
(3)调用add_timer将timer加入列表;
(4)在定时器到期时,function被执行;
(5)在程序中涉及timer控制的地方适当地调用del_timer、mod_timer删除timer或修改timer的expires
timer是linux内核中利用时钟中断来实现的定时器,可以方便得在内核中实现轮询
使用方法如下:
创建一个定时器:
static struct timer_list my_timer;
init_timer(&my_timer);
my_timer.function = my_timer_func;
my_timer.data = my_data;
然后指定timer的timeout值,然后将启动记时
cmmb_timer.expires = jiffies + HZ/50;
add_timer(&cmmb_timer);
如果需要轮询,则需要在my_timer_func返回前再
cmmb_timer.expires = jiffies + HZ/50;
add_timer(&cmmb_timer);
3.waitqueue
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/59615/showart_494670.html |
|