LINUX_内核驱动设计入门ppt课件.ppt_第1页
LINUX_内核驱动设计入门ppt课件.ppt_第2页
LINUX_内核驱动设计入门ppt课件.ppt_第3页
LINUX_内核驱动设计入门ppt课件.ppt_第4页
LINUX_内核驱动设计入门ppt课件.ppt_第5页
已阅读5页,还剩32页未读 继续免费阅读

下载本文档

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

文档简介

第十章内核驱动设计入门,嵌入式系统及其软件工具,1,本章提要,2,10.1驱动程序概述,设备驱动程序是操作系统内核和机器硬件之间的接口。所有对设备的操作都必须由被控设备相关的代码驱动程序来完成。设备驱动隐藏了设备的具体细节,为不同设备提供了统一的访问接口。用户或者应用程序可以像操作普通文件一样对硬件设备进行操作,设备驱动是内核的一部分。,3,10.1.1设备驱动功能,设备的初始化和释放负责内核与外设之间的数据交换提供各类设备服务检测和处理设备工作过程中出现的错误,4,驱动程序在嵌入式Linux中的作用:,在嵌入式系统中,要访问某个特定的硬件,实际上就是访问物理的地址空间(处理器内的寄存器、外设的地址映像)。然而,由于MMU的内存映射以及对操作系统的保护,运行在用户态的应用程序一般不能够直接访问硬件地址,因此需要驱动程序作为应用程序和访问硬件之间的媒介。某些驱动程序并不能直接给应用程序调用,而是给Linux内核调用。例如:串口作为console的物理载体;或者驱动程序由操作系统调用,应用程序可以间接的使用驱动程序,如framebuffer,网络设备驱动等。(要去哦球驱动程序必须按照某个框架编写,供上层模块使用),5,10.1.2驱动程序开发注意,开发驱动程序和开发应用程序不同;驱动程序应提供尽量多的选项给用户,不应该强加约束;尽量提高驱动程序的速度、效率,尽量简化,便于维护。,6,10.2Linux设备与设备驱动,Linux把设备分成3类,每类设备有自己的接口和常用框架,他们也有很多共性。,7,字符设备:采用字符流方式访问的设备,每次只传输一个字符。特点:顺序访问。鼠标、键盘、串口等。块设备:采用随机访问的方式访问,数据具有固定大小的块的设备;(Linux中块设备与字符设备使用基本一致)特点:缓冲存储,随机访问。硬盘、光盘等。网络设备:采用数据包传输方式访问的设备。特点:与字符设备和块设备不同,没有设备文件。通过socket进行使用。,设备,设备的分类,10.2.1Linux设备和设备驱动,8,设备驱动的共性:设备驱动工作在内核态,误操作后果很严重;设备驱动必须提供一个标准的内核接口,字符和块设备采用文件接口,网络设备采用套接字;驱动可以采用标准的内核服务,如:“内存分配”、等待队列、中断机制等;驱动可以动态的连接到内核中,不用时可以卸载。也可将驱动编译到内核中。,10.2.1Linux设备和设备驱动,9,10.2.2Linux设备文件,bash#ls-l/dev查看相关设备信息crw-1rootroot14,3Jan302003dspcrw-rw-1rootfloppy2,0Jan302003fd0,系统启动时会把设备文件系统挂载在/dev目录下,linux的设备文件的创建、删除和目录层次等都由各设备驱动程序管理。/dev中每个文件都动态的对应了一个系统上存在的设备驱动程序。,10,10.2.3Linux对设备文件的操作,open()intopen(const*pathname,intflag);open函数用于通过文件路径打开一个文件,返回一个整数类型的文件描述符。,close()intclose(intfd);close函数用于关闭文件,close会让数据写回磁盘,并释放文件所占用的资源。,11,10.2.3Linux对设备文件的操作,read()ssize_tread(intfd,void*buf,size_tcount);read函数从fd指向的文件传送count个字节到buf指针指向的内存中文件读写指针的位置会随着读取到的字节移动。当读取成功时,最好将返回值和count值进行比较若返回的值比count少,则可能读到了文件尾,或者read操作被中断了等。,12,10.2.4设备驱动程序接口,write()ssize_twrite(intfd,void*buf,size_tcount);write函数把参数buf指向的内存写入count个字节到fd指向的文件内。文件的读写位置也会随之变化;,13,10.2.3Linux对设备文件的操作,lseek()loff_tlseek(intfd,loff_toffset,intwhence);lseek函数用来控制文件的读写位置。,ioctl()intioctl(intfd,unsignedintcmd,);ioctl是Linux中对设备文件操作的特殊函数。可以对应到驱动程序的相应函数中。,14,文件操作示例:,#include#include#include#includeintmain()intfd,size;chars=”FileOperationn”;charbuffer80;fd=open(“/tmp/tempfile”,O_WRONLY|O_CREAT);write(fd,s,sizeof(s);close(fd);fd=open(“/tmp/tempfile”,O_RDONLY);size=read(fd,buffer,sizeof(buffer);close(fd);printf(“Display:%s”,buffer);return0;,以上的程序首先打开文件,接下来向文件中写入内容,然后从文件中读取内容,最后关闭文件。其运行结果为:Display:Fileoperation,15,10.2.4Linux对设备文件的操作,设备驱动程序是操作系统内核和机器硬件之间的接口。所有对设备的操作都必须由被控设备相关的代码驱动程序来完成。设备驱动隐藏了设备的具体细节,为不同设备提供了统一的访问接口。,16,应用程序与驱动程序之间的调用关系,10.2.4Linux对设备文件的操作,Linux应用程序中,通过对文件操作的函数对驱动程序的设备文件进行调用。,17,10.2.4Linux对设备文件的操作,structfile_operations/文件操作structmodule*owner;loff_t(*llseek)(structfile*,loff_t,int);ssize_t(*read)(structfile*,char*,size_t,loff_t*);ssize_t(*write)(structfile*,constchar*,size_t,loff_t*);int(*readdir)(structfile*,void*,filldir_t);unsignedint(*poll)(structfile*,structpoll_table_struct*);int(*ioctl)(structinode*,structfile*,unsignedint,long);int(*mmap)(structfile*,structvm_area_struct*);int(*open)(structinode*,structfile*);int(*release)(structinode*,structfile*);,字符设备操作,18,10.2.4Linux对设备文件的操作,structblock_device_operations/块设备操作int(*open)(structinode*,structfile*);int(*release)(structinode*,structfile*);int(*ioctl)(structinode*,structfile*,unsignedint,long);int(*check_media_change)(kdev_t);int(*revalidate_disk)(kdev_t);structmodule*owner;,Linux2.4定义的块设备操作,19,10.2.4Linux对设备文件的操作,structblock_device_operationsint(*open)(structinode*,structfile*);int(*release)(structinode*,structfile*);int(*ioctl)(structinode*,structfile*,unsignedint,long);int(*compat_ioctl)(structfile*,unsignedint,long);int(*media_changed)(structgendisk*);int(*revalidate_disk)(structgendisk*);structmodule*owner;,Linux2.6定义的块设备操作,20,10.2.5内核空间和用户空间交互,intaccess_ok(inttype,unsignedlongaddr,unsignedlongsize);unsignedlongcopy_to_user(void*to,constvoid*from,unsignedlongfen);unsignedlongcopy_from_user(void*to,constvoid*from,unsignedlongfen);void*mmap(void*start,size_tlength,intprot,intflags,intfd,loff_toffsize);,21,直接编译到内核,再运行新的内核来调试调试效率低,10.2.6Linux驱动开发和调试方法,module模式,将单独的驱动编译为module模式,单独加载调试调试效率高,调试时不用重启内核,22,10.2.7内核模块module,1.什么是module?module就是一个程序,但他可以被动态加载到kernel里,成为kernel的一部分。加载到kernel里的module具有和kernel一样的权力,它可以访问kernel里发布的任何数据结构,使用发布的function()。,23,10.2.7内核模块module,2.kernel如何管理module?,24,10.2.7内核模块module,3.module的初始化与回收,intinit_module(void)/模块初始化函数intresult;result=register_chrdev(“参数1”,“参数2”,“参数3”);if(result0)printk(DEVICE_NAME“cantgetmajormumber”);returnresult;if(device_major=0)device_major=result;returnresult;,25,10.2.7内核模块module,3.module的初始化与回收,voidcleanup_module(void)/模块卸载函数unregister_chrdev(参数1,参数2);,Module_init(module_init),module_exit(module_cleanup)这两个宏是在Linux内核头文件中定义的,Linux2.4中才具有。,26,10.3设备驱动程序框架,includeincludeincludeincludeincludedefineDEMO_DEVICE_MAJOR125defineDEMO_DEVICE_NAME“demo”defineDEMO_DEVICE_COMMAND11defineDEMO_DEVICE_COMMAND22defineDEMO_DEVICE_COMMAND33,1头文件包含:编写设备驱动的时候要包含内核的头文件,2定义常量:定义模块的主设备号和模块的名称,27,10.3设备驱动程序框架,module_init(demo_init);module_exit(demo_cleanup);staticstructfile_operationdemo_device_fops=owner:THIS_MOUDLE,read:demo_read,write:demo_write,ioctl:demo_ioctl,open:demo_open,release:demo_close,;,3函数声明;,4文件操作结构的指针,28,10.3设备驱动程序框架,staticintdemo_init(void)intresult;SET_MODULE_OWNER(,29,10.3设备驱动程序框架,staticintdemo_write(structfile*flip,constchar*buffer,size_tcount)chardev_buf;copy_from_user(dev_buff,buffer,count);staticintdemo_read(structfile*flip,char*buffer,size_tcount,loff_t*ppos)chardev_buf;copy_to_user(buffer,dev_buff,count);,5各种操作,30,10.3设备驱动程序框架,staticintdemo_ioctl(structinode*inode,structfile*file,unsignedintcmd,unsignedlongarg)switch(cmd)caseDEMO_DEVICE_COMMAND1:/*DEMO_DEVICE_COMMAND1处理函数*/break;caseDEMO_DEVICE_COMMAND2:/*DEMO_DEVICE_COMMAND2处理函数*/break;caseDEMO_DEVICE_COMMAND3:/*DEMO_DEVICE_COMMAND3处理函数*/break;return0;,31,10.3设备驱动程序框架,staticintdemo_open(structinode*inode,structfile*file)printk(KERN_CRIT“demo_deviceopenn”);MOD_INC_USE_COUNT;return0;staticintdemo_close(structinode*inode,structfile*file)printk(KERN_CRIT“demo_deviceclosen”);MOD_DEC_USE_COUNT;return0;,32,补充:设备驱动程序开发中一些具体问题,IOPortLinux下任何驱动程序都可以对任意IO进行操作,每个驱动程序都应该自己避免误用端口。有两个Kernel函数可以使用。check_region(intio_port,intoff_set)request_region(intio_port,intoff_set,char*devname),33,另:设备驱动程序开发中一些具

温馨提示

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

评论

0/150

提交评论