Linux驱动开发,说白了就是让操作系统能“认得”并且“用好”你手里的硬件。不管你是刚接触嵌入式的新人,还是从单片机转过来的老手,这事儿听起来吓人,其实拆开了看,就那么几块内容。我做了几年驱动,踩过不少坑,今天就把最核心的东西跟你捋一捋。

驱动到底是个啥东西

很多人一听到驱动开发就头大,觉得得把内核源码啃完才行。其实驱动说白了,就是内核和硬件之间的一个翻译官。内核不会直接跟每个芯片打交道,它只认一套标准接口RED HAT LINUX 9.0,比如你往某个文件里写数据,内核就调你的write函数。而你的任务,就是把芯片手册里的那些寄存器的操作,塞进这些标准接口里去。

驱动开发工程师_spec驱动开发_linux 驱动 开发

举个例子,一个简单的LED驱动,内核里注册个platform_driver,probe函数里把GPIO的寄存器地址映射进来,然后写一个ioctl或者sysfs接口,用户空间echo个1或者0,你就往寄存器里写个值,灯就亮了。这中间没有魔法,全是手册和代码的对应。

很多初学者一上来就搞复杂的设备树、中断、DMA,其实没必要。先从最简单的字符设备驱动开始,把open、read、write、ioctl这些回调写完,跑通一遍,你对驱动的理解就到位了。

设备树到底该怎么写才不报错

linux 驱动 开发_驱动开发工程师_spec驱动开发

设备树是Linux驱动开发里最让人头疼的一块,尤其是刚上手的时候,稍微写错一个属性,内核直接就起不来。其实设备树没那么玄乎,它就是个描述硬件资源的配置文件linux 驱动 开发,告诉内核:我这个设备用哪个中断号、哪个寄存器地址、哪个GPIO管脚。

写设备树的第一个原则是:严格按照芯片厂商的参考手册和内核文档来。不要自己发明属性名,那样内核不认识。比如你想描述一个I2C设备,就写compatible = “xxx,yyy”,这个字符串必须跟驱动里of_match_table里写的一模一样,少个字母都不行。

另一个常见问题是reg属性的长度和地址位数搞混。32位芯片用#address-cells = ,64位用,别弄反了。我见过有人把rk3399这种64位芯片的地址写成32位,结果设备死活没反应。还有就是中断号不要自己瞎编,得查芯片的datasheet,看看这个外设到底挂在哪个中断控制器上。

spec驱动开发_驱动开发工程师_linux 驱动 开发

调试驱动时那些让人崩溃的坑

驱动开发里,写代码只占一小半时间,大部分时间都在调试。而调试的难度在于,内核一旦崩溃,你可能连个错误信息都看不到,只能靠串口打印一点点定位。我常用的方法就是printk,别看它土,真管用。

printk的级别要选对,KERN_DEBUG的默认不打印,要改内核log等级才出来。建议调试时用KERN_ERR或者KERN_INFO,确保能直接看到。另一个技巧是在关键函数入口和出口都加打印,比如probe函数里,每一步都打印“step1 done”、“step2 done”,这样挂了你就知道卡在哪。

linux 驱动 开发_spec驱动开发_驱动开发工程师

还有种情况是驱动加载了但设备没反应,多半是资源申请失败。比如ioremap没成功,或者request_irq返回非零。这种错误不能忽略,一定要打印错误码,然后根据错误码查原因。像-ENOMEM是内存不够,-EBUSY是资源被占,-EINVAL是参数错误,每个都有意义。

锁的问题也容易让人抓狂。自旋锁和互斥锁用错了场景,轻则死锁,重则整个系统卡死。记住一点:中断上下文里只能用自旋锁,不能睡眠的任务里才用互斥锁。如果不确定,就看你的代码里有没有调msleep或者copy_from_user,有的话必须用互斥锁。

从零开始做一个实用的驱动

如果你想真正学会驱动开发,不要光看书,得动手写个能用的东西。我的建议是从一个简单的温度传感器驱动开始,比如ds18b20接在GPIO上linux 驱动 开发,或者用I2C的SHT20。这类驱动麻雀虽小五脏俱全,有设备树、有读写操作、有中断或者轮询,还能跟用户空间交互。

linux 驱动 开发_驱动开发工程师_spec驱动开发

先搭好字符设备框架,写好open、release、read。在read里获取温度数据,你可以用GPIO模拟单总线协议,或者直接调用i2c_transfer。然后通过ioctl或者sysfs把温度值暴露给用户。跑通了之后,再给它加上poll支持,让应用程序能select等待数据。一步步加功能,每加一个就测试一遍,不要一次加太多,不然出了问题你根本不知道是哪步错了。

等你把这个驱动跑顺了,再去看网卡驱动、块设备驱动这些复杂的,就不觉得慌了。因为核心思路都一样:找对接口,填对回调,处理对中断,管理好资源。

写驱动不像写应用,没有那么多花哨的库和框架,更多是跟硬件手册和内核机制死磕。但正是因为这样,每搞定一个驱动,你对整个系统的理解都会上一个台阶。别怕慢,别怕错linux学习视频,慢慢来,比较快。

Tagged:
Author

这篇优质的内容由TA贡献而来

刘遄

《Linux就该这么学》书籍作者,RHCA认证架构师,教育学(计算机专业硕士)。

发表回复