驱动与设备的关系
(思路还不是很清晰,表达更是杂乱,就是抛砖引玉,欢迎拍砖)
一个外设就是具备一定功能的数字电路单元(也可能包涵模拟电路如ADC,DAC,但一定具备数字电路否则无法被CPU驱动),它的工作状态受一组寄存器来直接控制和反馈,CPU对外设的驱动就是通过读写这组寄存器来实现的。
不同的是片内外设的寄存器直接映射为内存空间内的一段内存,CPU可以直接读写这块内存,而片外设备则是通过某种通信接口(如I2c,SPI,USB等)间接来访问这组寄存器。
驱动是对硬件单元操作的集合。
真正实现一个或一组设备驱动时,除了要有对寄存器结构的表述(通过结构体或地址偏移宏来描述),还有可能会有一些常量定义,变量定义,另外还必须有一组对寄存器操作的函数。
当一个系统内有多个相同外设时,他们的寄存器结构是完全一样的,可以共用常量,函数,以及使用方法,但寄存器基址或总线上的地址不一样,一些工作参数也不一样。
驱动中使用的参数一部分是必须由调用者指定的,一部分则是在驱动运行时动态获取的,只需留好位置即可。
这样把其中共用的寄存器结构描述,常量,函数,以及使用方法等都集合在一起作为设备驱动,而将差异化的配置参数集合为设备配置参数。
驱动指共用的方法。在程序上表现为一个包含固定数据结构和函数的代码库。
设备指相同类型硬件的不同实体,在程序上表现为一组相同结构不同内容的结构体。
驱动框架是设备及驱动的高度抽象,好的驱动框架能更好的兼容多种同类设备,可以使得驱动的编写及设备的使用更简洁明了。
驱动程序要封装对底层的操作,对上层提供一组统一的API接口,这组API接口对于调用者是很重要的,但对于实现驱动本身是次要的,实现驱动更关心需要用到那些软硬件资源以及硬件的正确配置流程。
对于同一系统上的多个相同片内设备,只有寄存器基址,中断号,引脚等不同,且其配置都是固定的,可以通过指定通道号后明确取值,且设备的数目也是固定的(对于同系列SOC,不同型号某一外设数目不一定相同,但有已知的最大数目)。
所以对于片内外设驱动可以预先设定好资源数组,设备通过指定通道号来间接获取其他通道相关参数。
对于片外设备,驱动应和soc无直接关联,可同时挂接的设备数也无法预知,所以资源结构可以动态分配。设备参数也要显式给出。 |