总线、设备、驱动模型和三者的关系
Q1:编写linux驱动指写什么?
A1:一是指芯片控制器设备的驱动如LCD控制器,IIC控制器等;二是指芯片外接的设备的驱动如24C02、LED灯、按键等。前者一般由芯片厂商的BSP工程师编写,后者一般是应用的嵌入式工程师编写。
Q2:嵌入式工程师写的驱动怎么保证最大的可重用性?
A2:
A2.1怎么做到更换了控制引脚的板子,主控芯片不变的情况下,外设驱动不用改?
引脚等资源通过外部引用,不在驱动直接写死。如同样芯片做成的两款板子,主控一样,控制LED灯的一个是IO1,一个是IO2。要写出来的驱动通用,就得把差异化的放到外面不要在驱动里面写死。
A2.2怎么做到换了同类型,参数,特性不一样的外设,外设驱动不用改?
同样的特定外设类型的具体参数,不能在驱动里面写死。如同一块板子驱动不同的LCD面板,采用的接口都一样,一款是1024*600,一款是320*240,通信速度等略有差异。这时候也要从外面获取这些差异化的参数和特性。
A2.3那假如换了产家的主控芯片呢?还能做到驱动的重用吗?
答案也是肯定的,主控芯片上集成了很多接口和controller,而这些设备的驱动一般都由BSP厂商给嵌入式工程师写好了驱动。在这个基础上结合linux的上层抽象系统如input子系统,总线等,直接调用抽象后的接口,而不是直接操作芯片的寄存器,这样就能做到和主控芯片无关。如写24C02的驱动用IIC总线抽像出来的API函数去操作特定芯片的controller。
Q3:嵌入式工程师写的驱动到底做了些什么?
A3:引用大神的一句话,在考虑了最大可重用性后,驱动写的其实是操作具体一类外设的控制流程和方法。如字符设备驱动里面open、read、write对应到具体的设备具体的操作流程是怎么样的。
探讨
思考了上面几个问题后,我们再来探讨一下linux下的总线、设备、驱动模型。
按我的理解,该模型是应用了分层,隔离和最大可重用性减少冗余代码的思想的产物。
为了保证驱动代码的可重用性,隔离了驱动使用的资源,参数和操作流程和方法。
前者由“设备”维护,也就是xxx_device维护外设驱动的资源和特定参数;在新版本的linux上,这部分工作已经交由设备树去管理。
后者由“驱动”完成,也就是设备的注册初始化,fileoperation结构的实现在xxx_driver完成。
那么谁来完成这两者的协调呢?
在这里是总线充当了这个角色,xxx_device和xxx_driver注册的时候都会触发总线一个匹配的过程。并且特定的总线还会提供统一的接口函数给到驱动使用。总线接口由特定芯片的controller驱动提供。
下面是他们的关系图: