目录
一、驱动的作用
二、裸机驱动 VS linux驱动
1、裸机驱动
2、linux驱动
三、linux驱动位于哪里?
四、应用编程 VS 内核编程
1、共同点
2、不同点
五、linux驱动分类
1、字符设备
2、块设备
3、网络设备
六、Linux驱动学习难点与误区
1、学习难点
2、学习误区
一、驱动的作用
相信学过os的同学,对上面的图应该不陌生,操作系统位于应用层和硬件之间,向下管理着各种硬件资源,向上屏蔽硬件细节,提供统一操作接口。当应用层需要操作硬件时,通过各种系统调用向操作系统发出请求,操作系统根据传入的参数,找到对应硬件的驱动,驱动再根据需求,操作硬件,完成请求。
二、裸机驱动 VS linux驱动
下面以最简单的“点灯”实验,来看裸机驱动和linux驱动的差别:
硬件电路图如下:
当GPIO输出高电平时,LED灯亮
当GPIO输出低电平时,LED灯灭
1、裸机驱动
应用层:在while循环里,调用gpio_init()对gpio做初始化,调用Led_on()/Led_off()来控制LED亮灭
驱动层:需要用到两个moudle:gpio和Led,其中gpio提供gpio操作函数集,如gpio_init(),gpio_output()等等,Led则提供led_init(),led_on()和led_off() ,led_on()调用gpio_ouput(1),让GPIO输出高电平,从而点亮led,同理,led_off()调用gpio_ouput(0),让GPIO输出低电平,从而熄灭led
2、linux驱动
首先linux驱动都是以module的形式来写的,其次Led属于字符设备,所以需要注册一个字符设备,要向linux内核注册一个字符设备,需要满足三要素:分配设备号,实现file_operation操作集,动态分配并add一个cdev。操作gpio的操作可以包含在file_operation操作集里write函数中
你可能会疑惑:为什么linux驱动要这么复杂呢?其实一切都是为了实现“一切皆文件”的思想,这样操作硬件就可以像操作文本文件一样简单啦
三、linux驱动位于哪里?
来一张linux系统全景图:
为了提升系统的安全性,操作系统利用处理器的特权模式,将进程的地址空间分成了两部分:用户空间和内核空间,从上图可以看出,驱动位于内核空间,所以驱动开发属于内核编程范畴。
四、应用编程 VS 内核编程
1、共同点
1)无论应用编程,还是内核编程,都是编程,编程就是写程序,而程序 = 数据结构 + 算法,所以常用数据结构和算法是编程的基石!
2)熟悉相应的API及其用法,应用编程需要和内核交互,比如在linux系统中操作文件,首先要open文件,open函数需要两个参数,一个是路径,一个是flag。linux驱动同样需要与linux内核交互,比如创建一个字符设备需要先分配cdev结构体,再cdev_init,最后cdev_add
2、不同点
1)应用程序执行任务,从开始到结束,内核模块将自己注册到内核中,在module_init中做些初始化操作后,等待被调用
2)并非所有应用程序都是事件驱动类型,但所有内核模块都是事件驱动类型
3)应用程序可以选择偷懒不去释放资源,由OS来统一回收,内核模块卸载函数需要做init里相反的操作,否则资源一直被占用,直到系统重启
4)应用程序可以使用C库,但内核模块只能使用内核export出来的符号表
5)处理错误的方式不同:应用程序一般会出现段错误,可以使用gdb直接调试,内核模块可能会使系统panic,或者重启
五、linux驱动分类
根据设备操作的特点,分为字符设备驱动,块设备驱动和网络设备驱动
1、字符设备
-
字节流
-
一般顺序访问
-
存在特殊的字符设备,允许lseek,mmap等操作
2、块设备
-
以块大小(512 byte)进行传输
-
任意顺序访问
-
可以安装文件系统
3、网络设备
-
使用套接字,处理网络事务
工作中遇到绝大多数的设备为字符设备,比如串口,LCD,触摸屏,platform设备等等都是字符设备。
六、Linux驱动学习难点与误区
1、学习难点
1)linux驱动开发属于内核编程,需要经常与内核其他子系统交互,因此需要熟悉linux内核
2)linux驱动需要处理并发,尤其如今已属于SMP的天下
3)linux驱动的鲁棒性要求高,否则会导致kernel panic
2、学习误区
1)没有硬件知识,看不懂原理图,就不能做驱动开发
解释:并非所有驱动都依赖对原理图的理解,在实际工作中,驱动分为外设驱动和bsp驱动,其中bsp驱动,如pinctrl驱动,gpio驱动,clk驱动,regulator驱动,这些只依赖Soc的设计,和原理图无关。
2)没有开发板,就没法学习linux驱动
解释:如果要开发的驱动不涉及具体硬件,优先选择qemu环境进行驱动开发
3)看书和看培训视频就行,不需要自己动手
解释:20%理论 + 80%实践,多动手,多实践,方能事半功倍!!
4)抱着经典书狂啃就够了
解释:其实最好的学习资料是源代码,经典书虽然经典,但其中内容早已过时,阅读经典书重要的是把握其中的设计思想,阅读最新的linux内核源代码才知晓具体实现细节
参考资料:《LDD3》
《linux设备驱动开发详解,基于4.0内核》