学术咨询

让论文发表更省时、省事、省心

基于Linux操作系统字符设备驱动程序开发

时间:2021年07月13日 分类:电子论文 次数:

摘要:本文详细介绍了基于Linux操作系统中字符设备驱动开发。首先介绍了字符设备驱动开发的相关概念,简述了驱动程序开发的基本知识和字符设备驱动程序开发的基本流程,重点阐述了Linux内核相关程序结构。为字符设备驱动开发的完整性,举例说明了字符设备驱

  摘要:本文详细介绍了基于Linux操作系统中字符设备驱动开发。首先介绍了字符设备驱动开发的相关概念,简述了驱动程序开发的基本知识和字符设备驱动程序开发的基本流程,重点阐述了Linux内核相关程序结构。为字符设备驱动开发的完整性,举例说明了字符设备驱动开发的编译下载和测试等实践知识。通过本论文能达到掌握字符设备驱动开发的基本能力,进而为复杂设备驱动开发打下基础。

  关键词:Linux;字符设备;驱动程序

计算机程序

  任何一个计算机系统的运转都是系统中软硬件共同努力的结果,没有硬件的软件是空中楼阁,而没有软件的硬件则只是一堆废铁。计算机系统发现外部设备并与外部设备通信,依靠驱动程序。设备驱动程序运行在内核空间,作为外部设备与应用软件桥梁。在所有嵌入式操作系统里,嵌入式Linux系统相比于其他的系统,在嵌入式领域有着独特的优势。首先是Linux开源免费;然后是Linux的内核体积小且易于模块化,适应性和可配置性好适合各种平台,它同时还支持多任务、多用户;最后是Linux有很多开发论坛,提供丰富开发资料,对开发者而言是强大的技术外援。所以本论文是基于Linux操作系统上开发字符设备驱动程序。

  程序设计论文:以OJ系统和学科竞赛为核心的程序设计实践教学

  1字符设备驱动程序设计基础

  1.1基本原理

  1.1.1创建设备节点。

  在Linux操作系统中所有设备都当作文件来处理,每个设备在/dev目录下都有一个设备文件与之相对应,对设备的打开、读写、控制和关闭等所有操作都是通过/dev/目录下对应的文件进行操作。设备节点有时会自动创建,可是字符设备驱动并不直接负责这一项操作。因此我们在设计字符设备驱动时会需要手动创建节点,使用mknod命令在文件系统上人工创建。除此之外Linux中有一组函数可以用来在/dev目录下创建设备节点,即class_create()和device_create()。

  1.1.2主次设备号。Linux管理的所有设备都有与之对应的目录,内核通过驱动程序来识别设备。一般来说驱动程序通过主设备号快速匹配外部设备,但同一类设备数量不只一个(或者说一个驱动程序可以同时匹配多个设备),所以必须增加次设备号,它给驱动程序提供了一种能从同一驱动管理下的同类型设备分辨出目标设备的方法。

  1.1.3用户空间和内核空间。嵌入式系统属于多用户、多任务操作系统,不能因为某个用户或某个任务的非法操作造成死机现象,所以用程序运行在用户空间,而驱动程序则运行在内核空间,内核空间维护计算机系统全局稳定性,驱动程序运行时受到内核程序较多约束,因为在内核中运行任一程序出现问题都会造成计算机系统死机。而应用程序运行较“宽松”。

  1.1.4应用程序与硬件设备的访问。

  计算机系统中的应用程序通过运行在内核空间的驱动程序来访问计算机外部设备。应用程序按照其中的流程对硬件设备进行访问。首先是应用程序调用操作系统提供的系统函数,从而访问内核空间,然后内核空间的结构file_operations来实现驱动程序中的相关 函数,从而实现对设备的访问。

  1.2重要结构

  file_operations要实现用户空间对内核空间的调用,必须依赖Linux操作系统内核中一个非常重要的数据结构:file_operations。此结构存放在内核include/linux/fs.h文件中,所以用到此结构的代码都应包含此头文件#include 。file_operations结构如下:Linux使用file_operations访问驱动中的函数时,file_operations中存储着对设备进行各种操作的函数指针f_ops,file_operations中每一个成员名都对应一个调用函数,如:file_open()、file_allocate()、file_read()、file_write()、file_ioctl()、file_close()等。比如在对系统进行数据存取的时候,系统通过设备的设备号来找到驱动,然后读取驱动,开始执行函数。例如:应用程序要对某个外部设备进行如open操作时,这时匹配该外部设备的驱动程序就会执行对应的fopen函数。

  2字符设备驱动程序开发

  字符设备驱动程序开发涉及到知识点较多,开发起来显得有点复杂。但规律可循,总结如下流程:第一步:编写驱动程序文件准备工作(定义设备名称、定义主次设备号)、设备注册、定义结构体file_operations、实现结构体内的功能函数、设备注销等。具体下来有以下工作:a.初始化外部设备的相关寄存器。包括定时寄存器、中断寄存器、串口寄存器;b.初始化硬件设备参数;c.注册设备。通过主次设备号与次设备号将驱动程序与设备关联起来,内核会调用函数register_chrdev来注册匹配的外部设备;d.注册外部设备中断函数。内核会调用函数request_irq()来注册匹配的外部设备的中断函数。

  第二步:驱动程序放进Linux内核将编辑好驱动程序源文件和头文件放置内核相对应的文件下./kernel/drivers/char,同时修改Linux内核配置文件***.config,在使用makemenuconfig命令时在配置页面里出现相应的配置选项,使用空格键选中,保存后退出,再使用预安装好的交叉编译工具链进行交叉编译。需要说明的,设备驱动程序编译有两种方法,一种是编译进内核,另一种是编译成模块。一般来说,调试阶段编译成模块形式,驱动程序稳定后,编译进内核。

  3字符设备驱动程序举例

  在Linux环境下,以键盘驱动程序为例进行说明。硬件基本情况是:S3C2410+HD7279(键盘数码管模块)。

  3.1编写键盘驱动程序

  a.编写file_operations结构。structfile_operationsKey_Board_7279={open:Key_Board_7279_Open,//打开设备文件ioctl:Key_Board_7279_Ioctl,//设备文件其他操作release:Key_Board_7279_Close,//关闭设备文件};b.编写Key_Board_7279_Open/。Key_Board_7279_Close/Key_Board_7279_Ioctl函数。打开/关闭函数为NULL,Key_Board_7279_Ioctl函数实现获取键值c.键盘服务子程序。staticvoidKey_Board_7279_ISR(intirq,void*dev_id,structpt_regs*regs){disable_irq(33);//使用33号中断key_number=Read_Key_Board_7279(cmd_read);//中断方式读取键值...}d.初始化键盘硬件函数。

  voidSetup_Key_Board_7279(void)e.注册键盘设备,调用初始化函数。int__initKey_Board_7279_Init(void){register_chrdev(...)//注册设备Setup_Key_Board_7279(...)//调用硬件初始化函数request_irq(...)//注册中断}f.卸载键盘设备。void__exitKey_Board_7279_Exit(void)3.2测试键盘驱动程序设备驱动编译后,接着编写测试程序kbd.c用来检测驱动程序的效果。fd=open("/dev/Kbd7279",0)

  结束语

  本论文讲述了字符设备驱动的基本原理及编写字符设备驱动程序的方法。基于S3C2410+HD7279平台上,演示了键盘字符设备驱动程序开发并进行了验证。本文可认为是字符设备驱动开发范例,为初学字符设备驱动开发提供参考。

  参考文献

  [1]周立功.单片机实验与实践[M].北京:北京航空航天大学出版社.

  [2]陆亚民.单片机原理及应用[M].北京:轻工业出版社.

  [3]Corbet,Rubini&Kroah-Hartman著,魏永明等译.《LinuxDevice设备驱动程序第三版》[M].北京:中国电力出版社,2006.

  [4]RobertLove著,陈莉君译.Linux内核设计与实现第二版[M].北京:机械工业出版社,2006.

  [5]JeanJ.Labrosse著,邵贝贝译《嵌入.式实时操作系统μC/OS-Ⅱ(第2版)》[M].北京:北京航空航天大学出版社,2005.

  [6]倪继利.Linux内核分析及编程[M].北京:电子工业出版社,2005.

  [7]EL-arm-830+型教学实验系统[M].北京:北京精仪达盛科技有限公司.

  作者:占华林徐涛涛陈亮亮于子正李明鑫

NOW!

Take the first step of our cooperation迈出我们合作第一步

符合规范的学术服务 助力您的学术成果走向世界


点击咨询学术顾问