Chinaunix首页 | 论坛 | 博客
  • 博客访问: 429280
  • 博文数量: 123
  • 博客积分: 2686
  • 博客等级: 少校
  • 技术积分: 1349
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-23 22:11
文章分类
文章存档

2012年(3)

2011年(10)

2010年(100)

2009年(10)

我的朋友

分类: LINUX

2010-07-09 11:18:13

一、Linux中断处理程序框架
Linux将中断处理程序分为2部分:top half, bottom half. top half 完成尽可能少的比较紧急的功能,往往只是简单地读取寄存器中的中断标志位并清除中断标志后进行“登记中断”的工作,将bottom half处理程序挂到该设备的bottom half 执行队列中去。bottom完成中断事件的绝大多数任务,几乎完成中断处理程序的所有工作。

二、中断编程
在linux设备驱动中,使用中断的设备需要申请和释放对应的中断,分别使用内核提供的request_irq()和free_irq()函数。

1.申请IRQ

typedef irqreturn_t (*irq_handler_t)(int, void *);

int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev);


2.释放IRQ

void free_irq(unsigned int irq, void *dev_id);


3.屏蔽中断

void disable_irq(int irq);

void disable_irq_nosync(int irq);

void enable_irq(int irq);

//屏蔽本cpu内的所有中断

void local_irq_save(unsigned long flags);

void local_irq_disable(void);


三、底半部机制
Linux系统实现底部的机制主要有tasklet,工作队列和软中断

1. tasklet
void my_tasklet_func(unsigned long);//定义一个处理函数


/*定义一个tasklet结构my_tasklet,与my_tasklet_func函数关联, data 是传入my_tasklet_func函数的参数*/

DECLEAR_TASKLET(my_tasklet,my_tasklet_func, data);

在需要调度bottom half的时候,调用函数:

tasklet_schedule(&my_tasklet);


2. 工作队列

struct work_struct my_wq;/*定义一个工作队列*/

void my_wq_func(unsigned long);/*定义一个处理函数*/

/*通过INIT_WORK()可以初始化这个工作队列执行函数并将工作队列与处理函数绑定*/

INIT_WORK(&my_wq, (void (*)(void *)) my_wq_func, NULL);

在需要调度工作队列的时候,调用函数:

schedule_work(&my_wq);


3. 软中断

在linux内核中,用softirq_action结构体表征一个软中断,这个结构体中包含软中断处理函数指针和传递给该函数的参数。使用open_softirq()函数可以注册软中断对应的处理函数,而 raisesoftirq()函数可以触发一个软中断。


区别:软中断和tasklet仍然运行于中断上下文,而工作队列则运行于进程上下文。因此,软中断和tasklet处理函数中不能睡眠,而工作队列处理函数中允许睡眠。local_bh_disable() ,local_bh_enable()是内核中用于禁止和使能软中断和tasklet底半部机制函数。



阅读(844) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~