一、驱动的效果
任何一个计算机体系的运转都是体系中软硬件协作的成果,没有硬件的软件是海市蜃楼,而没有软件的硬件则仅仅一堆废铁。硬件是底层根底,是一切软件得以运转的渠道,代码最终会落实为硬件上的组合逻辑与时序逻辑;软件则完结了详细运用,它依照各种不同的事务需求而规划,满意了用户的需求。硬件较固定,软件则很灵敏,能够习惯各种杂乱多变的运用。能够说,计算机体系的软硬件相互成果了对方。
可是,软硬件之间相同存在着悖论,那便是软件和硬件不应该相互渗透到对方的领地。为了尽可能快速地完结规划,运用软件工程师不想也不必关怀硬件,而硬件工程师也难有满足的空闲和才干来顾及软件。例如,运用软件工程师在调用套接字发送和接纳数据包的时分,他不必关怀网卡上的中止、寄存器、存储空间、I/O端口、片选以及其他任何硬件词汇;在运用printf()函数输出信息的时分,他不必知道底层终究是怎样把相应的信息输出到屏幕或串口。
也便是说,运用软件工程师需求看到一个没有硬件的朴实的软件世界,硬件有必要被透明地出现给他们。谁来完结硬件对运用软件工程师的隐形?这个艰巨的使命就落在了驱动工程师的头上。
对设备驱动最浅显的解说便是“唆使硬件设备举动” 。设备驱动与底层硬件直接打交道,依照硬件设备的详细作业方式读写设备寄存器,完结设备的轮询、中止处理、DMA通讯,进行物理内存向虚拟内存的映射,最终使通讯设备能够收发数据,使显现设备能够显现文字和画面,使存储设备能够记载文件和数据。
由此可见,设备驱动充当了硬件和运用软件之间的枢纽,它使得运用软件只需求调用体系软件的运用编程接口(API)就可让硬件去完结要求的作业。在体系中没有操作体系的情况下,工程师能够依据硬件设备的特色自行界说接口,如对串口界说SerialSend()、SerialRecv();对 LED 界说LightOn()、LightOff();以及对 Flash 界说FlashWrite()、FlashRead()等。而在有操作体系的情况下,设备驱动的架构则由相应的操作体系界说,驱动工程师有必要依照相应的架构规划设备驱动,这样,设备驱动才干杰出地整合到操作体系的内核中。
驱动程序交流着硬件和运用软件,而驱动工程师则交流着硬件工程师和运用软件工程师。跟着通讯、电子职业的迅速发展,全世界每天都会有许多的新芯片被出产,许多的新电路板被规划,因而,也会有许多设备驱动需求开发。这些设备驱动,或运转在简略的单使命环境中,或运转在 VxWorks、Linux、Windows等多使命操作体系环境中,发挥着不行代替的效果。
二、有无操作体系的差异
1)无操作体系(即裸机)时的设备驱动
并不是任何一个计算机体系都一定要运转操作体系,在许多情况下操作体系是不要的。关于功用比较单一、操控并不杂乱的体系,如公交车刷卡机、电冰箱、微波、简略的手机和小灵通等,并不需求多使命调度、文件体系、内存办理等杂乱功用,单使命架构完全能够很好地支撑它们的作业。一个无限循环中搀杂对设备中止的检测或许对设备的轮询是这种体系中软件的典型架构。裸机的完结果有点相似单片机(MCU)了,尽管单片机的寄存器没有那么的多,假如会裸机驱动,我想,应该能担任单片机的作业了,呵呵。
在这样的体系中,尽管不存在操作体系,可是设备驱动是有必要存在的。一般情况下,对每一种设备驱动都会界说为一个软件模块,包括.h文件和.c文件,前者界说该设备驱动的数据结构并声明外部函数,后者进行设备驱动的详细完结。书中例举了一个串口驱动serial.c serial.h,主要是装备GPIO,串口操控寄存器,以及串口的收发(读写)寄存器,而这几个装备都是自界说函数完结的,比方串口的写(发)SerialSend 函数等。
其他模块需求运用这个设备的时分,只需求包括设备驱动的头文件 serial.h,然后调用其间的外部接口函数即可。如咱们要从串口上发送字符串“Hello World”,运用函数SerialSend( " Hello World ",11)即可。
由此可见,在没有操作体系的情况下,设备驱动的接口被直接提交给了运用软件工程师, 运用软件没有跨过任何层次就直接拜访了设备驱动的接口。 设备驱动包括的接口函数也与硬件的功用直接符合, 没有任何附加功用。
有的工程师把单使命体系规划成设备驱动和详细的运用软件模块处于同一层次(即运用程序也在比方serial.c中完结),这显然是不合理的,不符合软件规划中高内聚低耦合的要求。
另一种不合理的规划是直接在运用中操作硬件的寄存器(独自一个main.c,一切功用都在一个函数中完结,不选用其他任何接口/函数),而不独自规划驱动模块,这种规划意味着体系中不存在或未能充分利用可被重用的驱动代码。
2)有操作体系时的设备驱动
无操作体系时的设备驱动中的设备驱动直接运转在硬件之上,不与任何操作体系相关。当体系中包括操作体系后,设备驱动会变得怎样?
首要,无操作体系时设备驱动的硬件操作作业仍然是必不行少的, 没有这一部分,设备驱动不行能与硬件打交道。
其次,咱们还需求将设备驱动融入内核。为了完结这种交融,有必要在一切的设备驱动中规划面向操作体系内核的接口,这样的接口由操作体系规则,对一类设备而言结构共同,独立于详细的设备。
由此可见,当体系中存在操作体系的时分,设备驱动变成了衔接硬件和内核的桥梁。操作体系的存在必然要求设备驱动附加更多的代码和功用(以我看,主要是供给了许多结构),把单一的“唆使硬件设备举动”变成了操作体系内与硬件交互的模块,它对外出现为操作体系的API,不再给运用软件工程师直接供给接口。有了操作体系之后,设备驱动反而变得杂乱,那要操作体系干什么?
首要,一个杂乱的软件体系需求处理多个并发的使命,没有操作体系,想完结多使命并发是很困难的。
其次,操作体系给咱们供给内存办理机制。一个典型的比方是,关于大都含 MMU的处理器而言,Windows、Linux 等操作体系能够让每个进程都独登时拜访 4GB的内存空间。
上述长处好像并没有体现在设备驱动身上,操作体系的存在给设备驱动终究带来了什么优点呢?
简而言之,操作体系经过给设备驱动制作费事来到达给上层运用供给便当的意图。假如设备驱动都依照操作体系给出的独立于设备的接口而规划,运用程序将可运用一致的体系调用接口来拜访各种设备。关于类UNIX的VxWorks、Linux等操作体系而言,运用程序经过write()、read()等函数读写文件就能够拜访各种字符设备和块设备,而不必管设备的详细类型和作业方式,是十分便利的。
不论有无操作体系,不论是SerialSend,或许write,拜访设备都需求对寄存器进行读写操作,比方串口,在dev目录下有个ttys0结点,咱们能够经过ioctl函数对其进行读写操作,当然,write、read更为直接咯。而上层的运用能够对这些函数进行封装,界说不同的接口,然后完结更多的功用