Linux驱动开发笔记

本文详细记录了Linux驱动开发的学习历程,从基础的设备模型到字符设备驱动、块设备驱动的实现,深入探讨了I/O控制、中断处理和DMA等关键概念。通过实例解析,帮助读者理解驱动程序与内核的交互,为Linux驱动程序的开发打下坚实基础。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 中断
先申请中断号
irqno = get_irqno_from_node();
在申请中断
request_irq(irqno, key_irq_handler, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,"key3_eint10", NULL);
2. 中断驱动,加入字符框架后,出现空指针NULL pointer问题

Unable to handle kernel NULL pointer dereference at virtual address 00000000
先看request_irq函数原型:
static inline int __must_check
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
   const char *name, void *dev)
{
return request_threaded_irq(irq, handler, NULL, flags, name, dev);
}
可以看到,request_irq()也是调用了另外一个函数,request_threaded_irq(),在这个函数的描述中有下面的文字
 * This call allocates interrupt resources and enables the
 * interrupt line and IRQ handling. From the point this
 * call is made your handler function may be invoked. Since
 * your handler function must clear any interrupt the board
 * raises, you must take care both to initialise your hardware
 * and to set up the interrupt handler in the right order.
在调用request_irq()之前,要把中断标志都清理,否则可能会调用中断处理函数;(目前调试看,没有做中断标志清除动作,百分百调用了中断处理函数)
这就是为什么,在L11D8的学习中,加入字符设备框架后,在request_irq()后面才初始化--key_dev->data_reg_base = ioremap(0x11000C24, 8);将会导致空指针的出现;
那为什么出现的机会是呈概率性的?因为他是通过创建线程来完成中断request的,中断的响应是在新线程中进行。
因为在中断处理函数中,已经有用到这个data_reg_base了。所以ioremap()操作要放在request_irq()之前。

3. 中断驱动加入阻塞IO代码,出现BUG: spinlock bad magic on CPU#0问题
阻塞IO的实现:
首先,初始化等待队列头;
在驱动初始化函数xxx_init()中加入
init_waitqueue_head(&key_dev->wq_head);
然后在需要等待的时候,进行休眠;
中断处理函数中xxx_handler()加入
wait_event_interruptible(key_dev->wq_head,key_dev->key_state);//休眠
最后在合适的时候,唤醒
wake_up_interruptible(&key_dev->wq_head);//唤醒

出现BUG的原因,同2;因为init_waitqueue_head()放在了request_irq()后面,导致中断处理函数被调用时,等待队列头还没有初始化。而且,从图片可以看到,驱动挂载和卸载,已经完成了13次,第14次才出现问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值