嵌入式linux系统开发概述之四----设备驱动(Drivers)

2019-07-13 02:00发布

4   设备驱动程序     嵌入式系统通常有许多设备用于与用户交互,象触摸屏、小键盘、滚动轮、传感器、RS232接口、LCD等等。除了这些设备外,还有许多其它专用设备,包括闪存、USBGSM等。内核通过所有这些设备各自的设备驱动程序来控制它们,包括GUI用户应用程序也通过访问这些驱动程序来访问设备。     开发者编写驱动程序是应该特别注意下面所提到的概念:编写访问硬件的内核代码是不要给用户强加任何策略。因为不同的用户有不同的需求,驱动程序应该处理如何使硬件可用的问题,而将怎样使用硬件的问题留给上层应用。因此,当驱动程序只提供了访问硬件的功能而没有附加任何限制时,这个驱动程序就比较灵活。然而,有时候我们也需要在驱动程序中实现一些策略。例如,某个数字I/O驱动程序只提供了以字节为单位访问硬件的方法,这样就省去了编写额外代码以处理单个数据位的麻烦。     如果从另一个角度来看驱动程序,那么它可以被看作是应用和实际设备之间的一个软件层。这种定位使开发者可以选择如何展现设备特性:即使对于相同的设备,不同的驱动程序也可以提供不同的功能。实际的驱动程序设计应该在许多考虑因素之间取得平衡。例如,某个驱动程序可能同时被多个进程使用,我们就应该考虑如何处理并发的问题:可以在设备上实现独立于硬件功能的内存映射;也可以提供一个函数库,以帮助应用程序开发者在已有原语的基础上实现新的策略。总之,驱动程序的设计主要还是综合考虑下面三方面的因素:提供给用户尽量多的选项、编写驱动程序占用较少的时间以及尽量保持程序简单而不至于错误丛生。     本节着重讨论通常几乎在每个嵌入式环境中都会使用的一些重要设备的设备驱动程序。   4.1 帧缓冲区驱动程序(FrameBuffer)
    这是最重要的驱动程序之一,因为通过这个驱动程序才能使系统屏幕显示内容。帧缓冲区驱动程序通常有三层。最底层是基本控制台驱动程序 drivers/char/console.c,它提供了文本控制台常规接口的一部分。通过使用控制台驱动程序函数,我们能将文本打印到屏幕上 — 但图形或动画还不能(这样做需要使用视频模式功能,通常出现在中间层,也就是drivers/video/fbcon.c 中)。这个第二层驱动程序提供了视频模式中绘图的常规接口。     帧缓冲区是显卡上的内存,需要将它内存映射到用户空间以便可以将图形和文本能写到这个内存段上:然后这个信息将反映到屏幕上。帧缓冲区支持提高了绘图的速度和整体性能。这也是顶层驱动程序引人注意之处:顶层是非常特定于硬件的驱动程序,它需要支持显卡不同的硬件方面 — 象启用/禁用显卡控制器、深度和模式的支持以及调 {MOD}板等。所有这三层都相互依赖以实现正确的视频功能。与帧缓冲区相对应的设备是/dev/fb0(主设备号29,次设备号0)。可以用下面的命令来创建该设备: #mknod /dev/fb0 c 29 0     有一个简单的比喻来理解帧缓冲驱动。假设当前需要的显示分辨率是640x480x16bpp(16bpp代表16位 {MOD},一般的RGB排列为565,),那么要存储整个屏幕的像素信息所需要的内存大小为640x480x16/8 = 600K bytes(一个像素的16位 {MOD}需要两个字节来表示)。帧缓冲驱动即在内存中分配了上述大小的一块区域,同时与实际屏幕上的像素一一对应。     如果我们要改变屏幕上某个像素的颜 {MOD}显示,首先计算该颜 {MOD}的16位的RGB排列,然后计算出该像素在内存中的偏移量,最后操作fb0设备,重画该像素。下面的代码将屏幕上的第二排的第二个像素设置成白 {MOD}: { int fd, pixel_addr, pixel_color, ;   pixel_addr = (640+1)x16/8;      /* 得到像素偏移地址 */ pixel_color = 0xffff;           /* 设置像素点颜 {MOD} */   fd = open(/dev/fb0”, O_RDWR); /* 打开framebuffer设备 */ if (fd >= 0) {     lseek(fd, pixel_addr, SEEK_SET);    /* 找到该像素 */     write(fd, pixel_color, 2);          /* 重画该像素 */ }     现在一般的linux内核已经包含了对帧缓冲驱动的支持,我们要作的只是在内核配置选项中加入它: #make menuconfig(命令行下),或xconfig(XWindow下)。     与 frame buffer device有关的选项有(用空格键来进行选中或去除,其余编译选项请参考其它资料): Code maturity level opetions
   [*] Prompt for development and/or incomplete codes/drivers
   Console drivers
   [*] Video mode selection support
   ...
   [*] Support for frame buffer devices
   ...
   [*] VESA VGA graphics console
   ...
   [*] Advance low level driver options
   ...
[Exit]
[Exit]
Do you wish to save your new kernel configuration?
[Yes]
编译安装内核: #make dep 
#make bzImage

4.2 输入设备驱动程序
    可触摸板是用于嵌入式设备的最基本的用户交互设备之一 — 小键盘、传感器和滚动轮也包含在许多不同设备中以用于不同的用途。
    触摸板设备的主要功能是随时报告用户的触摸,并标识触摸的坐标。这通常在每次发生触摸时,通过生成一个中断来实现。然后,这个设备驱动程序的角 {MOD}是每当出现中断时就查询触摸屏控制器,并请求控制器发送触摸的坐标。一旦驱动程序接收到坐标,它就将有关触摸和任何可用数据的信号发送给用户应用程序,并将数据发送给应用程序(如果可能的话)。然后用户应用程序根据它的需要处理数据。
    几乎所有输入设备 — 包括小键盘 — 都以类似原理工作。     输入设备驱动程序通常需要与上层的GUI应用接口。比如触摸板需要和GUI的鼠标显示结合起来,随着用户触摸位置的不同,屏幕上鼠标的图标移动到相应的位置。一般在GUI中有专门处理外部输入的文件,修改这些文件,可以支持自己的输入设备。

4.3 闪存MTD驱动程序
    MTD
设备是象闪存芯片、小型闪存卡、记忆棒等之类的设备,它们在嵌入式设备中的使用正在不断增长。     MTD驱动程序是在linux下专门为嵌入式环境开发的新的一类驱动程序。     相对于常规块设备驱动程序,使用MTD驱动程序的主要优点在于MTD驱动程序是专门为基于闪存的设备所设计的,所以它们通常有更好的支持、更好的管理和基于扇区的擦除和读写操作的更好的接口。