实验四 linu驱动程序的编写

上传人:鲁** 文档编号:470569330 上传时间:2023-07-05 格式:DOCX 页数:7 大小:158.89KB
返回 下载 相关 举报
实验四 linu驱动程序的编写_第1页
第1页 / 共7页
实验四 linu驱动程序的编写_第2页
第2页 / 共7页
实验四 linu驱动程序的编写_第3页
第3页 / 共7页
实验四 linu驱动程序的编写_第4页
第4页 / 共7页
实验四 linu驱动程序的编写_第5页
第5页 / 共7页
点击查看更多>>
资源描述

《实验四 linu驱动程序的编写》由会员分享,可在线阅读,更多相关《实验四 linu驱动程序的编写(7页珍藏版)》请在金锄头文库上搜索。

1、中国石油大学(北京)计算机科学与技术系实验报告实验课程:软件系统设计与开发实践评定成绩指导教师实验名称:linux驱动程序的编写学号: 2017215538 姓名: 于宁 班级: 信息研17-4班 完成日期:2018年4月16日一、实验目的1. 掌握linux驱动程序的编写方法;2. 掌握驱动程序动态模块的调试方法;3. 掌握驱动程序填加到内核的方法。二、实验内容1. 学习 linux 驱动程序的编写流程;2. 学习驱动程序动态模块的调试方法;3. 学习驱动程序填加到内核的流程。三、实验设备1. Pentiumll以上的PC机,LINUX操作系统,EL-ARM830实验箱。四、linux的驱动

2、程序的编写嵌入式应用对成本和实时性比较敏感,而对linux的应用主要体现在对硬件的驱动程序 的编写和上层应用程序的开发上。嵌入式linux驱动程序的基本结构和标准Linux的结构基本一致,也支持模块化模式,所以,大部分驱动程序编成模块化形式,而且,要求可以在不同的体系结构上安装。linux是 1 /7可以支持模块化模式的,但由于嵌入式应用是针对具体的应用,所以,一般不采用该模式而是把驱动程序直接编译进内核之中。但是这种模式是调试驱动模块的极佳方法。设备驱动程序是操作系统内核和机器硬件之间的接口。设备驱动程序为应用程序屏蔽了 硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,应用程序可以

3、像操作普通文 件一样对硬件设备进行操作。同时,设备驱动程序是内核的一部分,它完成以下的功能:对设 备初始化和释放;把数据从内核传送到硬件和从硬件读取数据;读取应用程序传送给设备文 件的数据和回送应用程序请求的数据;检测和处理设备出现的错误。在linux操作系统下有字 符设备和块设备两类主要的设备文件类型。字符设备和块设备的主要区别是:在对字符设备发出读写请求时,实际的硬件I/O般就紧接着发生了;块设备利用一块系 统内存作为缓冲区,当用户进程对设备请求满足用户要求时,就返回请求的数据。块设备是主 要针对磁盘等慢速设备设计的,以免耗费过多的CP U时间来等待。4.1 设备驱动程序的 file_op

4、erations 结构通常, 一个设备驱动程序包括两个基本的任务:驱动设备的某些函数作为系统调用执行;而某些函数则负责处理中断(即中断处理函数)。而file_operations结构的每一个成员的名 称都对应着一个系统调用。用户程序利用系统调用,比如在对一个设备文件进行诸如read操 作时,这时对应于该设备文件的驱动程序就会执行相关的ssize _t (*read) (st ruct file *, char *, size_t, loff_t *);函数。在操作系统内部,外部设备的存取是通过一组固定入口 点进行的,这些入口点由每个外设的驱动程序提供,由file_operations结构向系统

5、进行说明, 因此,编写设备驱动程序的主要工作就是编写子函数,并填充file_opera tions的各个域。 file_opera tions 结构在 kernel/include/linux/fs.h 中可以找到。struct file_operations struct module *owner;loff_t (*llseek) (struct file *, loff_t, int);ssize_t (*read) (struct file *, char *, size_t, loff_t *);ssize_t (*write) (struct file *, const char

6、*, size_t, loff_t *);int (*readdir) (struct file *, void *, filldir_t);unsigned int (*poll) (struct file *, struct poll_table_struct *);int (*ioctl) (struct inode*, struct file*, unsigned int, unsigned long);int (*mmap) (struct file *, struct vm_area_struct *);int (*open) (struct inode *, struct fil

7、e *);int (*flush) (struct file *);int (*release) (struct inode *, struct file *);int (*fsync) (struct file *, struct dentry *, int datasync);int (*fasync) (int, struct file *, int);int (*lock) (struct file *, int, struct file_lock *);ssize_t (*readv) (struct file *, const struct iovec *, unsigned lo

8、ng, loff_t*);ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *);ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);#ifdef MAGIC_ROM_

9、PTRint (*romptr) (struct file *, struct vm_area_struct *);#endif /* MAGIC_ROM_PTR */;其中主要的函数说明如下:1. open是驱动程序用来完成设备初始化操作的,open还会增加设备计数,以防止文件 在关闭前模块被卸载出内核。open主要完成以下操作:检查设备错误(诸如设备未就 绪或相似的硬件问题);如果是首次打开,初始化设备;标别次设备号;分配和填写要 放在filepriva te_da ta内的数据结构;增加使用计数。2. read用来从外部设备中读取数据。当其为NULL指针时,将引起read系统调用返 回-

10、EINVAL( “非法参数”)。函数返回一个非负值表示成功地读取了多少字节。3. write向外部设备发送数据。如果没有这个函数, write系统调用向调用程序返回 一个-EINVAL。如果返回值非负,就表示成功地写入的字节数。4. release是当设备被关闭时调用这个操作。release的作用正好与open相反。这个设 备方法有时也称为close。它应该完成以下操作:使用计数减1;释放open分配在file f private_data中的内存,在最后一次关闭操作时关闭设备。5. llseek 是改变当前的读写指针。6. readdir 一般用于文件系统的操作。7. poll 一般用于查询

11、设备是否可读可写或处于特殊的状态。8. ioctl 执行设备专有的命令。9. mmap 将设备内存映射到应用程序的进程地址空间。4.2 设备驱动程序编写的具体内容通过了解驱动程序的file_operations结构,用户就可以编写出相关外部设备的驱动程 序。首先,用户在自己的驱动程序源文件中定义file_operations结构,并编写出设备需 要的各操作函数,对于设备不需要的操作函数用NULL初始化,这些操作函数将被注册到 内核,当应用程序对设备相应的设备文件进行文件操作时,内核会找到相应的操作函数, 并进行调用。如果操作函数使用NULL,操作系统就进行默认的处理。定义并编写完file_op

12、era ti ons结构的操作函数后,要定义一个初始化函数,比如函数 名可device_init(),在linux初始化的时候要调用该函数,因此,该函数应包含以下几 项工作:a. 对该驱动所使用到的硬件寄存器进行初始化。包括中断寄存器。b. 初始化设备相关的参数。一般来说每个设备要定义一个设备变量,用来保存设备相关的参数。c. 注册设备。Linux内核通过主设备号将设备驱动程序同设备文件相连。每个设备有且仅有一个主设备号。通过查看linux系统中/proc下的devices文件,该文件记录已 经使用的主设备号和设备名,选择一个没有使用的主设备号,调用下面的函数来注 册设备。int regist

13、er_chrdev(unsigned int ,const char*,struct file_operations*),其 中的三个参数代表主设备号,设备名,file_operations的结构地址。d. 注册设备使用的中断。注册中断使用的函数。int request_irq(unsigned irq,void(*handler)(int,void*,structpt_ regs*),unsigned long flags, cons t char* device, void* dev_id); 其中, irq是中断向量。硬件系统将IRQ n映射成中断向量。handler中断处理函数。fla

14、gs中断处理中的一些选项的掩码。device设备的名称dev_id在中断共享时使用的id。e. 其他的一些初始化工作,比如给设备分配I/O,申请DMA通道等。当设备的驱动程序使用了如下的函数方式,则设备驱动可以动态的加载和卸载int _init device_init (void)void _exit device_exit(void)module_init(device _init);module_exit(device _exit); 当然,也可以编译进内核中。4.3将设备驱动加到linux内核中设备驱动程序写完后,就可以加到linux的内核中了,这需要修改linux的源码,然后重 新编译

15、linux内核。1. 将设备驱动文件(比如device_driver.c)复制到kernel/drivers/char目录下,该 目录保存了 linux的字符型设备的设备驱动程序。该驱动程序中,使用int _in t device_i nit(v oid)方式编写。2. 在kernel/drivers/char目录下的Makefile文件中填加如下代码: ifeq($(CONFIG_DEVICE_DRIVER),y)L_OBJS+= DEVICE_DRIVER.oendif或obj-$(CONFIG_DEVICE_DRIVER) += DEVICE_DRIVER.o如果在配置linux内核的时候,选择了支持我们定义的设备,则在编译内核的时候, 会编译 DEVICE_DRIVER.c,生成 DEVICE_DRIVER.o 文件。3. 在kernel/drivers/char 目录下修改 config.in文 件。在 commen t Charac ter devices 下面填加:bool support for DEVICE_DRIVER CONFIG_DEVICE_DRIVER这样在编译内核时,运行make menuconfig时,在配置字符设备时就会出现support for DEVICE_DRIVER的字样。当选中它时,编译通过,则驱动程序就加到内核

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 学术论文 > 其它学术论文

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号