我在Linux字符设备驱动框架一文中简单介绍了Linux字符设备编程模型,在那个模型中,只要应用程序open()了相应的设备文件,就可以使用ioctl通过驱动程序来控制我们的硬件,这种模型直观,但是从软件设计的角度看,却是一种十分糟糕的方式,它有一个致命的问题,就是设备信息和驱动代码冗余在一起,一旦硬件信息发生改变甚至设备已经不在了,就必须要修改驱动源码,非常的麻烦,为了解决这种驱动代码和设备信息耦合的问题,Linux提出了platform bus(平台总线)的概念,即使用虚拟总线将设备信息和驱动程序进行分离,设备树的提出就是进一步深化这种思想,将设备信息进行更好的整理。平台总线会维护两条链表,分别管理设备和驱动,当一个设备被注册到总线上的时候,总线会根据其名字搜索对应的驱动,如果找到就将设备信息导入驱动程序并执行驱动;当一个驱动被注册到平台总线的时候,总线也会搜索设备。总之,平台总线负责将设备信息和驱动代码匹配,这样就可以做到驱动和设备信息的分离。
在设备树出现之前,设备信息只能使用C语言的方式进行编写,在3.0之后,设备信息就开始同时支持两种编写方式——设备树、C语言,如果用设备树,手动将设备信息写到设备树中之后,内核就可以自动从设备树中提取相应的设备信息并将其封装成相应的platform_device对象,i2c_device对象并注册到相应的总线中,如果使用设备树,我们就不需要对设备信息再进行编码。如果使用C语言,显然,我们需要将使用内核提供的结构将设备信息进行手动封装,这种封装又分为两种形式,一种是使用平台文件(静态),将整个板子的所有设备都写在一个文件中并编译进内核。另一种是使用模块(动态),将我们需要的设备信息编译成模块在insmod进内核。对于ARM平台,使用设备树封装设备信息是将来的趋势,但是由于历史原因,当下的内核中这三种方式并存。封装好后再创建相应的xxx_device实例最后注册到总线中。针对平台总线的设备信息,我在Linux设备树语法详解一文中已经讨论了设备树的写法,所以,本文主要讨论4个问题:
如何使用C语言封装设备信息?
设备树的设备信息和C语言的设备信息如何转换?
如何将C语言设备信息封装到platform_device结构中?
如何将封装好的platform_device结构注册到平台总线中?
何为资源?
所谓的设备信

