1、 字符设备驱动程序字符设备驱动程序 课程设计报告课程设计报告 一、一、课程设计目的课程设计目的 1. 了解 Linux 字符设备驱动程序的结构; 2. 掌握 Linux 字符设备驱动程序常用结构体和操作函数的使用方法; 3. 初步掌握 Linux 字符设备驱动程序的编写方法及过程; 4. 掌握 Linux 字符设备驱动程序的加载方法及测试方法。 二、二、课程设计课程设计内容内容 5. 设计 Windows XP 或者 Linux 操作系统下的设备驱动程序; 6. 掌握虚拟字符设备的设计方法和测试方法; 7. 编写测试应用程序,测试对该设备的读写等操作。 三、三、需求分析需求分析 3 3.1.1
2、 驱动程序介绍驱动程序介绍 驱动程序负责将应用程序如读、 写等操作正确无误的传递给相关的硬件, 并使硬件能够 做出正确反应的代码。驱动程序像一个黑盒子,它隐藏了硬件的工作细节,应用程序只需要 通过一组标准化的接口实现对硬件的操作。 3 3.2 Linux.2 Linux 设备驱动程序分类设备驱动程序分类 Linux 设备驱动程序在 Linux 的内核源代码中占有很大的比例, 源代码的长度日益增加, 主要是驱动程序的增加。虽然 Linux 内核的不断升级,但驱动程序的结构还是相对稳定。 Linux 系统的设备分为字符设备(char device),块设备(block device)和网络设备 (
3、network device)三种。字符设备是指在存取时没有缓存的设备,而块设备的读写都有缓存 来支持,并且块设备必须能够随机存取(random access)。典型的字符设备包括鼠标,键盘, 串行口等。块设备主要包括硬盘软盘设备,CD-ROM 等。 网络设备在 Linux 里做专门的处理。Linux 的网络系统主要是基于 BSD unix 的 socket 机制。在系统和驱动程序之间定义有专门的数据结构(sk_buff)进行数据传递。系统有支持 对发送数据和接收数据的缓存,提供流量控制机制,提供对多协议的支持。 3 3.3.3 驱动程序的结构驱动程序的结构 驱动程序的结构如图 3.1 所示,
4、应用程序经过系统调用,进入核心层,内核要控制硬件 需要通过驱动程序实现,驱动程序相当于内核与硬件之间的“系统调用” 。 图 3.1 驱动程序的结构 3 3.3.1 .3.1 内核模块内核模块 内核模块是 Linux 内核的重要组成要素,内核模块能在 Linux 系统启动之后能够动态进 行装载和卸载, 因此不需对内核进行重新编译或重启系统就可将内核的一部分替换掉, Linux 内核的所有设备驱动,文件系统,网络协议等可做成模块的形式来提供。在所有的模块中需 记录编译的内核版本信息,并与当前执行的内核版本一致。即,模块具有版本依赖性,如果 不一样就会出错,当然可以在模块程序中的 include之前
5、通过宏定义 #define_NO_VERSION_表明不定义模块的版本信息。 内核模块程序与一般应用程序之间主要不同之处是, 模块程序没有 main()函数, 模块程 序 在 装 载 时 调 用 init_module(void) 函 数 添 加 到 内 核 中 , 在 卸 载 时 调 用 void cleanup_module( )函数从内核中卸载。另外一个应用程序从头到尾只执行一个任务,但一 个模块可以把响应未来请求的事务登记到内核中, 然后等待系统调用, 内核模块程序结构如 图 3.2 所示。 init_module( )register_capability( ) printk( )
6、. . . . . cleanup_module( )unregister_capability( ) insmod rmmod ModuleKernel capabilities 图 3.2 内核模块程序结构 3 3.4.4 主、从设备号主、从设备号 应用程序通过设备文件系统(devfs)的名字(或节点)访问硬件设备,所有的设备节点 在/dev 目录下。利用 mknod 命令生成设备文件系统的节点,但只有超级用户才能生成设备 文。Mknod 命令必须要有设备名和设备类型,主设备号(Major Number) ,次设备号(Minor Number)等 3 个参数。主设备号用于内核区分设备驱动,次设备号用于设备驱动区分设备。 一个设备驱动可能控制多个设备。新的设备驱动要有新的主设备号。在内核源代码的 Documentation/devices.txt 中定义了所有设备的主设备号。 在创建设备的时候不要与常用 的设备好冲突。 3 3.5.5 驱动程序基本框架驱动程序基本框架 如果采用模块方式编写设备驱动程序时, 通常至少要实现设备初始化模块、 设备打开模 块、