00 驱动开发总览
github主页:https://github.com/snqx-lqh
本项目github地址:https://github.com/snqx-lqh/RaspberryPiDriver
本项目硬件地址:https://oshwhub.com/from_zero/shu-mei-pai-kuo-zhan-ban
欢迎交流
系列开发参考¶
参考正点原子《I.MX6U 嵌入式 Linux 驱动开发指南 V1.81》
韦东山《01_嵌入式Linux应用开发完全手册V5.1_IMX6ULL_Pro开发板》
树莓派驱动开发实战项目:Philon/rpi-drivers
部分是总结,部分是个人理解,不一定正确,仅供参考。系列笔记主要偏向实战,会简要介绍部分理论,因为部分理论我也不清楚,写个笔记帮助自己整理思路。
开发环境¶
硬件使用树莓派3B+,安装的系统是**Raspberry Pi OS 32 位 桌面版**,Debian12应该是。
软件在VMware虚拟机上安装Docker,配置ubuntu20.04的系统进行编译运行。
硬件扩展版是自己设计的一块板子,开源链接在:https://oshwhub.com/from_zero/shu-mei-pai-kuo-zhan-ban
设备驱动的形式¶
3种常见的设备驱动模式。传统设备驱动模式、PlatformDevice/PlatformDriver模式、设备树/PlatformDriver模式。
传统设备驱动模式:将所有的资源分配放进一个文件中,使用哪个引脚,怎么操作引脚,都写死在代码中,修改引脚时,需要重新编译。
PlatformDevice/PlatformDriver模式:资源放进PlatformDevice文件,实现驱动放进PlatformDriver文件,代码稍微复杂,但是易于扩展,但是冗余代码太多,更换引脚时,只需要修改PlatformDevice文件。
设备树/PlatformDriver模式:资源放进设备树,实现驱动放进PlatformDriver文件。设备树一种是提前编译内核的时候就编译好,还有一种方式是添加设备树插件。
后面两种方式都是为了实现**总线-设备-驱动**框架,实现设备驱动的分离。感觉第二种模式用的比较少,一般都是在写第一种或者第三种,可能是我见的少,学的少,第三种应该是最多的。
GPIO子系统和Pinctrl¶
传统寄存器控制:使用ioremap的方式,将寄存器的地址信息映射到虚拟地址,然后控制对应的寄存器输入输出。
gpio子系统和pinctrl方式:这一部分的使用,应该在使用了设备树的情况下。pinctrl子系统在修改了设备树信息之后,会自己做相关的处理,使得gpio子系统能够获取并处理在设备树上设置的信息。
常用驱动总线¶
MISC驱动:通常嵌套在platform总线驱动中,实现比较杂项的驱动,在我感觉,他就是一个封装过的传统设备驱动,没有传统设备驱动的注册class和device的这些步骤,因为类它已经建好了,分配到了主设备号为10,只是各个驱动次设备号不同。
Platform驱动:一种虚拟平台驱动,比如有些外设可以挂载到I2C、SPI等实际的总线上,但是有些设备,不是使用这些总线,我们就需要一个虚拟的设备总线来解决这个问题。比如普通的LED,只是使用了GPIO,就可以挂载到这个总线上。
I2C驱动:和Platform驱动不同,这个就是一个实际的总线,不是虚拟的总线。但是实现它的思想还是为了实现**总线-设备-驱动**框架。
SPI驱动:和I2C驱动一样。
还会有许多如USB、PCI等等,暂时不详细说明,我也不会。
重要的知识点¶
休眠与唤醒、POLL机制、异步通知、阻塞与非阻塞、定时器、中断下半部、工作队列、中断的线程化处理