虽说职位是linux驱动工程师,但是几乎没有从头写驱动的机会。基本只有半导体IC厂商的工程师写驱动,做终端产品的工程师只有改驱动的份。
特此积累一些常见的驱动编程模型,方便今后套用。
本文讲述如何使用一个简单的中断处理线程,做一些简单的应用场合。中断处理函数要干脆利索的返回,不能睡眠,最好也不要忙等(msleep之类)
假设为路由器设计一个复位按键,按下3s后(去抖,确认操作),内核调用用户进程做一个更新文件系统的动作。去抖可以在中断处理函数里做,50ms的忙等。但总不能在中断处理函数里等3s来确认操作吧。内核调用用户进程的常见接口,怎么也会引起睡眠吧。
这些不干脆的操作我想应该在中断处理线程里去做。
主要代码如下:
- static irqreturn_t irq_thread_fn(int data,void *dev_id)
-
{
-
-
printk("<0>in irq_thread_fn %d %s \n",current->pid,current->comm);
-
//判断当前上下文
-
if(in_irq())
-
printk(" in_irq\n");
-
if(in_softirq())
-
printk(" in_softirq\n");
-
if(in_interrupt())
-
printk(" in_interrupt\n");
-
-
//实践证明确实是在进程上下文,所以尽管折腾尽管睡眠吧
-
-
return IRQ_HANDLED; //真正完成了中断处理
-
}
-
-
-
static irqreturn_t irq_handler(int irq, void *data)
-
-
{
-
//实践证明中断上下文中可以使用current,但是取得的结果自然没有意义,毕竟不是在进程上下文
-
//大部分情况打印in irq_thread_fn 0 swapper
-
printk("<0>in irq_handler %d %s \n",current->pid,current->comm);
-
if(in_irq())
-
printk(" in_irq\n");
-
if(in_softirq())
-
printk(" in_softirq\n");
-
if(in_interrupt())
-
printk(" in_interrupt\n");
-
//clear pend
-
//硬件相关操作部分,如清空中断标记
-
-
return IRQ_WAKE_THREAD; //表示需要调用中断处理线程才能完成中断处理
-
}
-
-
ret=request_threaded_irq(IRQ_NUM,irq_handler,irq_thread_fn,IRQF_SAMPLE_RANDOM,"LightSensorPS",NULL);
阅读(2525) | 评论(0) | 转发(0) |