从需求的角度去理解嵌入式Linux:总线、设备和驱动

1、软件、面向对象、软件框架编程

软件是为了解决现实问题而产生的,面向对象的软件思惟是解决广泛现实问题的一种有效的抽象方法,而软件框架指的是用面向对象的思惟去解决某种特定领域的问题而专门设计的一套行之有效的解决方案。网络

通常地,JAVA/C++编程反映面向对象的软件思惟,而像Android Framework、Windows MFC和Linux的QT则表明应用层的软件框架。前述应用框架要解决的问题包括应用消息处理、UI控件显示和处理、资源管理等等。软件框架带来的好处就是对于解决某个领域问题,框架会帮你完成80%的开发工做量,而你只须要完成20%的开发工做量。数据结构

Linux平台上的各个子系统,如设备驱动模型、input子系统、I2C总线、frame buffer驱动等等都属于软件框架,它是针对特定的硬件体系需求以面向对象的思惟去设计的一种软件解决方案,并且已经通过长时间的多平台验证。严格意义上,将子系统纳入软件抽象组件会更加贴切,而软件框架表现为一组抽象组件及其组件实例之间的交互。软件框架和软件组件的特色都是解决特色领域问题,能够高度重用设计。框架

Linux系统以C语言开发为主,C语言在教科书上会被认为是过程语言。事实上,面向对象只是一种软件思惟,并不局限于某种语言,只不过C++/JAVA在娘胎(编译器)里就已经获得支持,而C语言经过struct数据结构和函数指针同样能够出色地完成面向对象抽象的工做。Linux系统绝对是利用C语言进行面向对象编程的开山鼻祖,到处洋溢着软件艺术的光辉!函数

2、理解好软件需求是学习好软件框架的前提学习

对于学习着来讲,软件需求(即软件要解决的问题)和软件框架都已经存在。但学习者每每只关注软件框架,由于学习的终极目标也是为了掌握软件框架并使用它来解决本身的问题。对于通常的知识传播者来讲(例如学校老师、机构培训师;教科书或者网络文献),每每也是着重于解读软件框架的组成和原理。操作系统

事实上,对于一个代码量有几万甚至几十万行代码量的软件框架,一开始接触就学习原理和代码并非好事。这种作法很像是试图从软件框架的学习理解中得出软件需求,有太多的未知就接触源码,那理解过程会很是痛苦,每每会感到很是迷惑。设计

我认为,深刻地理解好需求,再去理解软件框架会事半功倍。指针

甚至,当达到必定的水平后,知道了需求,彻底能够去猜想软件框架的实现。对象

3、Linux系统的软件需求


   对于软件需求,最容易让人联想到的是一种具体的业务需求,如12306购票业务等等。Linux是一种操做系统,操做系统的软件需求是什么?操做系统是为了给应用层提供良好的接口而进行总线设备驱动管理、内存管理、文件管理、进程管理等等。更多系统学习资料和内容以及方法加意义气呜呜吧久零就易,总线设备驱动管理就是咱们今天要谈的主题。Linux平台有各类子系统、各类总线、各类驱动,Linux系统对它们的管理就是软件框架的组成。咱们要理解好Linux已有的框架,就要清晰地知晓其解决的问题,也就是其管理了哪些硬件设备,这些硬件设备的特色是什么,这些设备的访问方式是什么。

        能够说,深刻地理解硬件体系是理解好Linux总线设备驱动框架的前提!从面向对象的角度,咱们要弄清楚,物理意义上的硬件是什么,而对应的软件对象是如何表述的。

        如下阐述会重点讲述软件需求,做为之后分析框架的基础。

4、总线、驱动、设备

1. 总线

总线表明着同类设备须要共同遵照的工做时序,不一样的总线对于物理电平的要求是不同的,对于每一个比特的电平维持宽度也是不同,而总线上传递的命令也会有本身的格式约束。如I2C总线、USB总线、PCI总线等等。以I2C总线为例,在同一组I2C总线上链接着不一样的I2C设备。

 

2.设备

设备表明真实的、具体的物理器件,在软件上用器件的独特的参数属性来表明该器件。如I2C总线上链接的I2C从设备都有一个标识本身的设备地址,由这个设备地址来肯定主设备发过来的命令是否该由它来响应。

 

3.驱动

        驱动表明着操做设备的方式和流程。对于应用来讲,应用程序open打开设备后,接着就read访问这个设备,驱动就是如何实现这个访问的具体的过程。驱动主要包括两部分,第一是经过对SOC的控制寄存器进行编程,按总线要求输出时序和命令,成功地与外围设备进行交互;第二是对第一步中获得的数据进行处理,并向应用层提供特定格式的数据。

a.不一样总线的设备的驱动过程是不同的,这个很容易理解,USB鼠标的驱动和I2C EEPROM的读时序确定是不同的,访问时序的产生和控制也是驱动的一部分。

b.同种总线不一样设备类型的设备驱动也是不同的。如I2C电容屏设备,对于读read来讲就是在datasheet规定的地址上去读触摸点的X和Y坐标,而I2C EEPROM的读操做是读取存储的内容,两种设备的datasheet是不同的,驱动天然是不同的。

c.同种总线的同类设备的设备驱动也多是不同的。例如对于触摸屏,TSC2003只支持单点触控,而FT5X06支持多点触摸。在获取触控坐标时,前者只须要得到一个点的数据就返回,然后者则须要先得到当前有几个点的数据,而后再把全部点的坐标都读出来。

        在驱动的操做中,通常都会用到GPIO和中断等硬件资源,如上图的SDA和SCL会链接到SOC芯片的具体的两个GPIO引脚,而I2C读写时通常都采用中断控制的方式(查询读写是否完成比较低效,浪费CPU)。若是咱们在驱动中直接针对具体的引脚来编程,那这个驱动的平台可移植性就比较差,由于不一样的产品设计可能引脚不同。因此,为了提升驱动的可移植性,Linux把驱动要用到的GPIO和中断等资源剥离给设备去管理。即在设备里面包含其本身的设备属性,还包括了其链接到SOC所用到的资源。而驱动重点关注操做的流程和方法。

 

4.再谈总线

        第1点中谈到的总线只是物理意义上的表述,总线就是在行业中制定出标准,明确规定时序的格式。咱们在第3点中谈到,在软件层面上,时序的产生和控制由驱动负责。那咱们要思考在软件层面上,总线的职责是什么?

        总线在软件层面主要是负责管理设备和驱动。

a.设备要让系统感知本身的存在,设备须要向总线注册本身;一样地,驱动要让系统感知本身的存在,也须要向总线注册本身。设备和总线在初始化时必需要明确本身是哪一种总线的,I2C设备和驱动不能向USB总线注册吧。

b.多个设备和多个驱动都注册到同一个总线上,那设备怎么找到最适合本身的驱动呢,或者说驱动怎么找到其所支持的设备呢?这个也是由总线负责,总线就像是一个红娘,负责在设备和驱动中牵线。设备会向总线提出本身对驱动的条件(最简单的也是最精确的就是指定对方的名字了),而驱动也会向总线告知本身可以支持的设备的条件(通常是型号ID等,最简单的也能够是设备的名字)。那设备在注册的时候,总线就会遍历注册在它上面的驱动,找到最适合这个设备的驱动,而后填入设备的结构成员中;驱动注册的时候,总线也会遍历注册在其之上的设备,找到其支持的设备(能够是多个,驱动和设备的关系是1:N),并将设备填入驱动的支持列表中。咱们称总线这个牵线的行为是match。牵好线以后,设备和驱动之间的交互红娘可无论了。

c.总线在匹配设备和驱动以后驱动要考虑一个这样的问题,设备对应的软件数据结构表明着静态的信息,真实的物理设备此时是否正常还不必定,所以驱动须要探测这个设备是否正常。咱们称这个行为为probe,至于如何探测,那是驱动才知道干的事情,总线只管吩咐得了。因此咱们能够猜想在总线的管理代码中会有这样的逻辑:

if(match(device, driver) == OK)

        driver->probe();

相关文章
相关标签/搜索