设备驱动程序设计_第1页
设备驱动程序设计_第2页
设备驱动程序设计_第3页
设备驱动程序设计_第4页
设备驱动程序设计_第5页
已阅读5页,还剩30页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Linux设备驱动程序设计Linux设备驱动程序设计郗闽军牛建伟实验目的学习Linux下进行驱动程序设计的原理掌握Linux设备驱动程序开发的基本过程和设计方法实验内容内核驱动设计入门-模块方式驱动程序(5.1)内核驱动设计实验-触摸屏驱动(5.2)写一个简单的应用程序,显示触摸位置的坐标(x,y)开发一个LED(数码管)驱动程序,并编写一个应用程序对所开发的驱动程序进行测试(大作业)实验实现的功能是上电复位后,数码管显示数字0-7,然后每一个数字依次闪烁一次,小数点也要点亮,即:0.1.2.3.4.5.6.7.Linux的设备驱动程序硬件设备与应用程序之间的一个中间软件层它使得某个特定硬件能够响应一个定义良好的内部编程接口,同时完全隐蔽了设备的工作细节用户通过一组与具体设备无关的标准化的调用来完成相应的操作驱动程序的任务就是把这些标准化的系统调用映射到具体设备对于实际硬件的特定操作上驱动程序是内核的一部分,可以使用中断、DMA等操作驱动程序在用户态和内核态之间传递数据设备驱动程序的分类字符设备所有能够象字节流一样访问的设备都通过字符设备来实现它们被映射为文件系统中的节点,通常在/dev/目录下面一般要包含openreadwriteclose等系统调用的实现块设备通常是指诸如磁盘、内存、Flash等可以容纳文件系统的存储设备。块设备也是通过文件系统来访问,与字符设备的区别是:内核管理数据的方式不同它允许象字符设备一样以字节流的方式来访问,也可一次传递任意多的字节。网络接口设备通常它指的是硬件设备,但有时也可能是一个软件设备(如回环接口loopback),它们由内核中网络子系统驱动,负责发送和接收数据包。它们的数据传送往往不是面向流的,因此很难将它们映射到一个文件系统的节点上。基本概念主设备号和次设备号主设备号和次设备号能够唯一地标识一个设备128(V2.0以前),256(V2.0以后)主设备号相同的设备使用相同的驱动程序,次设备号用于区分具体设备的实例动态获取主设备号Linux下对设备号的分配请参考Documentation/devices.txt设备文件Linux使用设备文件来统一对设备的访问接口,将设备文件放在/dev/目录下设备的命名一般为设备文件名+数字或者字母表示的子类,例如/dev/hda1,/dev/hda2等Linux2.4以后引入了设备文件系统(devfs)的概念,所有的设备文件作为一个可以挂装的文件系统,这样就可以被文件系统统一管理,从而设备文件就可以挂装到任何需要的地方。一般将主设备建立一个目录,再将具体的子设备文件建立在此目录下。例如,/dev/mtdblock0基本概念驱动程序使用的2个重要结构structfilestructfile_operations基本概念structfile基本概念structfile数据结构定义位于include/fs.hstructfile结构与驱动相关的成员mode_tf_mode 标识文件的读写权限loff_tf_pos 当前读写位置unsignedint_f_flag 文件标志,主要进行阻塞/非阻塞型操作时检查structfile_operation*f_op文件操作的结构指针void*private_data 驱动程序一般将它指向已经分配的数据structdentry*f_dentry 文件对应的目录项结构基本概念设备驱动程序接口(structfile_operations),标记化方法:staticstructfile_operationsdemo_fops={owner:THIS_MODULE,write:demo_write,read:demo_read,ioctl:demo_ioctl,open:demo_open,release:demo_release,};基本概概念设备驱驱动程程序接接口((structfile_operations))通常所所说的的设备备驱动动程序序接口口是指指structfile_operations{},,它的的定义义位于于include/linux/fs.h中。。在嵌入入式系系统的的开发发中,,通常常只要要实现现如下下几个个接口口函数数就能能完成成系统统所需需要的的功能能init加加载驱驱动程程序时时,内内核自自动调调用read从从设备备中读读取数数据write向向字字符设设备中中写数数据ioctl控控制制设备备,实实现除除读写写操作作以外外的其其他控控制命命令open打打开设设备并并进行行初始始化release关关闭设设备并并释放放资源源exit卸卸载驱驱动程程序时时,内内核自自动调调用基本概概念驱动程程序注注册过过程((动态态分配配主设设备号号)insmodmodule_name;加加载驱驱动程程序,,运行行init函数数(register_chrdev(dev_Major,““module_name”,*fs))查看/proc/devicesmknod/dev/module_namec/b主主设备备号次次设备备号rmmodmodule_name;卸卸载驱驱动,,运行行exit函函数((unregister_chrdev(dev_Major,““module_name””,*fs))用户程程序调调用Open(“/dev/module_name””,mode);O_RDWRIoctl()Write()Read()Close()开发驱驱动程程序时时须注注意的的事项项中断处处理中断是是现代代微处处理器器的一一个重重要功功能Linux驱动动程序序中的的中断断处理理函数数externintrequest_irq(unsignedintirq,void(*handler)(int,void*,structpt_regs*),unsignedlongflag,constchar*dev_name,void*dev_id);//请请求为为中断断号irq分配配中断断处理理函数数externvoidfree_irq(unsignedint,void*);//释放放中断断注意事事项不能向向用户户空间间发送送或者者接收收数据据不能执执行有有睡眠眠操作作的函函数不能调调用调调度函函数谨慎使使用全全局变变量((可重重入))自旋锁锁的使使用基本概概念字符设设备的的管理理驱动程程序模模块通通过函函数intregister_chrdev(unsignedintmajor,constchar*name,structfile_operations*fops)完成向向内核核的注注册,,其中中major是是主设设备号号,name是是设备备名,,fops是针针对该该设备备的驱驱动程程序的的接口口。在系统统中为为驱动动程序序模块块建立立一个个设备备节点点[minjun@RedHatAS~]$mknod/dev/democ2540其中/dev/demo标识识设备备名为为demo,““c””说明明是字字符设设备,,254是是指定定的主主设备备号,,0是次次设备备号基本概概念驱动程程序的的编译译以demo.c为例例Makefile的的形式-参参考实验指指导书命令行的形形式[minjun@RedHatAS~]$armv4l-unknown-linux-gcc-Wall-c-O-D__KERNEL__-I/home/minjun/embedded/kernel-2410s/includedemo.c-odemo.o加载驱动[minjun@RedHatAS~]$insmoddemo.o卸载驱动[minjun@RedHatAS~]$rmmoddemo.o基本概念测试程序实实例//test.c#include<stdio.h>#include<fcntl.h>#include<stdlib.h>intmain() {intfd;fd=open("/dev/demo",O_RDWR);if(fd<0){exit(fd);}//yourcodehereread(fd,buffer,size);write(fd,buffer,size);......close(fd);return0;}驱动程序的的实现-驱驱动程序框框架#include<linux/config.h>#include<linux/module.h>#include<linux/init.h>#include<linux/kernel.h>/*printk()*/#include<linux/fs.h>/*everything...*/#include<linux/errno.h>/*errorcodes*/#include<linux/types.h>/*size_t*/#include<linux/proc_fs.h>#include<linux/fcntl.h>/*O_ACCMODE*/#include<linux/poll.h>/*COPY_TO_USER*/#include<asm/system.h>/*cli(),*_flags*/#defineDEVICE_NAME"demo"#definedemo_MAJOR250#definedemo_MINOR0staticssize_tdemo_write(structfile*filp,constchar*buffer,size_tcount) {copy_from_user(drv_buf,buffer,count);WRI_LENGTH=count;printk("userwritedatatodriver\n");//yourcodeherereturncount;}驱动程序的的实现-驱驱动程序框框架staticssize_tdemo_read(structfile*filp,char*buffer,size_tcount,loff_t*ppos){if(count>MAX_BUF_LEN)count=MAX_BUF_LEN;copy_to_user(buffer,drv_buf,count);printk("userreaddatafromdriver\n");returncount;}staticintdemo_ioctl(structinode*inode,structfile*file,unsignedintcmd,unsignedlongarg){printk("ioctlruning\n");switch(cmd){case1:printk("runingcommand1\n");break;case2:printk("runingcommand2\n");break;default:printk("errorcmdnumber\n");break;}return0;}staticintdemo_open(structinode*inode,structfile*file){MOD_INC_USE_COUNT;sprintf(drv_buf,"deviceopensucess!\n");printk("deviceopensucess!\n");return0;}驱动程序的的实现-驱驱动程序框框架staticintdemo_release(structinode*inode,structfile*filp){MOD_DEC_USE_COUNT;printk("devicerelease\n");return0;}staticstructfile_operationsdemo_fops={owner: THIS_MODULE,write: demo_write,read: demo_read,ioctl: demo_ioctl,open: demo_open,release:demo_release,};staticint__initdemo_init(void) {SET_MODULE_OWNER(&demo_fops);result=register_chrdev(demo_MAJOR,"demo",&demo_fops);if(result<0)returnresult;printk(DEVICE_NAME"initialized\n");return0;}staticvoid__exitdemo_exit(void) {unregister_chrdev(demo_MAJOR,"demo");printk(DEVICE_NAME"unloaded\n");}module_init(demo_init);module_exit(demo_exit);驱动程序的的实现-驱驱动程序框框架open提供给驱动动程序初始始化设备的的能力,为为后续的操操作做准备备此外一般会会递增使用用计数,防防止文件关关闭前模块块被卸载通常情况下下,open完成如如下工作::递增使用计计数检查特定设设备错误如果设备是是首次打开开,则对其其进行初始始化识别次设备备号,如有有必要,则则修改f_op指针针分配并填写写filp->private_data中的的数据release与open正好相反反释放由open分配配的filp->private_data中中的数据在最后一次次关闭操作作时关闭设设备使用计数减减一驱动程序的的实现-驱驱动程序框框架read和和writeread将将数据从内内核拷贝到到应用程序序空间,write则将数据据从应用程程序空间拷拷贝到内核核。由于用户空空间和内核核空间的内内存映射方方式不同,,所以在内内核和用户户空间传输输数据的时时候需要使使用如下的的函数unsignedlongcopy_to_user(void*to,constvoid*from,unsignedlongcount);unsignedlongcopy_from_user(void*to,constvoid*from,unsignedlongcount);在阻塞型IO中,read和和write调用可可能会出现现阻塞read调调用当前无无数据可读读,而又没没有数据马马上可读,,这时会睡睡眠并且等等待,write调调用也会出出现这样的的情况等待队列机机制-wait_queue_head_t;(定义在在<linux/wait.h>中)如果声明了了等待队列列并完成初初始化,进进程就可以以睡眠,可可以调用sleep_on的的不同变体体来完成睡睡眠(函数数声明位于于<linux/sched.h>中)大多数情况况下应使用用“可中断断”的函数数,如interruptible_sleep_on。睡眠进程被被唤醒并不不一定代表表有数据,,也有可能能是被其他他的信号唤唤醒,所以以醒来后需需要测试condition.8段LED显示器外外形原理图图一个数码管管(LED)由一个个8位的字字节控制当该位为““1”时点点亮,为““0”时灭灭acbdefhgLED连接接原理图LED显示示驱动器ZLG7290I2CLED/键键盘驱动动器I2C串串行接口提提供键盘中中断信号方方便与处理理器接口可驱动8位位共阴数数码管或64只独独立LED和64个按键键可控扫描位位数可控任任一数码管管闪烁提供数据译译码和循环环移位段寻寻址等控制制8个功能能键可检测测任一键的的连击次数数无需外接元元件即直接接驱LED可扩展展驱动电流流和驱动电电压详细资料参参加课程网网站上的::zlg7290.pdfzlg7290_led.pdf图1ZLG7290引脚图图LED显示示驱动器功功能框图IIC基地地址是0x70有24个8位寄存器器(0x0-0x17),通通过IIC总线访问问,必须是是字节操作作主要寄存器器SystemReg0x0FlashOnOff0x0cScanNum0x0dDpRam0~70x10-0x17CmdBuf0~10x7-0x8两种控制方方式:-寄存器映映象控制-命令解释释控制参考zlg7290.pdfLED驱动动程序的主主要函数staticintled_write(structfile*filp,constchar*buffer,size_tcount,loff_t*ppos){…}staticintled_ioctl(structinode*inode,structfile*file,unsignedintcmd,unsignedlongarg){…}staticintled_open(structinode*inode,structfile*filp){…}staticintled_release(structinode*inode,structfile*filp){……}staticint__initled_init(void){…}staticvoid__exitled_exit(void){…}staticstructfile_operationsled_fops={owner: THIS_MODULE,open: led_open,release:led_release,write: led_write,ioctl: led_ioctl,};可以使用IIC_Write(charbaseAddr,charoffSet,chardata)来设置寄寄存器的值((字节操作)),该函数在在iic.h文件中定义义。LED测试应应用程序框架架#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<fcntl.h>#include<sys/types.h>intmain(){intfd;intret;if((fd=open("/dev/led",O_RDWR))<0){printf("openleddevicefailed!\n");exit(fd);}ioctl(intfd,intcmd,……);write(intfd,char*buf,intlength);close(fd);return0;}实验内内容内核驱驱动设设计入入门--模块块方式式驱动动程序序(5.1)在PClinux和开开发平平台上上运行行通过过内核驱驱动设设计实实验--触摸摸屏驱驱动((5.2))写一个个简单单的应应用程程序,,显示示触摸摸位置置的坐坐标((x,y))在开发发平台台上装装载驱驱动程程序,,运行行编写写的测测试应应用程程序开发一一个LED(数数码管管)驱驱动程程序,,并编编写一一个应应用程程序对对所开开发的的驱动动程序序进行行测试试(如如果做做不完完,可可以在在下下下次实实验接接着做做)开发led_driver.c开发led_test.c实验步步骤-demo驱动动程序序阅读和和理解解源代代码进入/arm2410s/exp/drivers/demo,阅阅读理理解源源代码码编译驱驱动模模块修改Makefile文文件,编编译实实验平平台运运行的的驱动动程序序测试驱驱动程程序装载驱驱动程程序和和建立立设备备文件件节点点insmoddemo.o[]mknod/dev/democ2540编译测测试程程序并并运行行[]armv4l-unknown-linux-gcctest_demo.c––otest_demo./test_demo实验步步骤-触摸摸屏驱驱动测试驱驱动程程序驱动程程序位位于内内核源源代码码目录录下面面的drivers/char/下面面,名称:s3c2410-ts-ads7843.o装载驱驱动程程序和和建立立设备备文件件节点点在将触触摸屏屏驱动动加载载到内内核中中时,可以以看到到系统统为触触摸屏屏设备备分配配的设设备号号[]insmods3c2410-ts-ads7843.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论