linux设备驱动开发实例.
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
驱动针对的对象是存储器和外设(包括CPU内部集成的存储器和外设),而不是针对CPU核。Linux将存储器和外设分为3种基本设备类型(字符设备、块设备、网络设备).每个模块常常实现3种设备类型中的1种,因此可分类成字符模块,块模块,网络模块.
3类设备如下:
字符设备:一个字符( char )设备是一种可以当作一个字节流来存取的设备(如同一个文件);它是必须以串行顺序依次进行访问的设备,如触摸屏、磁带驱动器、鼠标等。这样的驱动常常至少实现open, close, read,和write系统调用.它不经过系统的快速缓冲。
·2 linux内核模块编程
linux内核的整体结构非常庞大,其包含的组件也非常多,那么我们怎么把需要的部分都包含在内核中呢?一种方法时把所有需要的功能都编译到内核,利用make zImage可以实现,并会生成镜像文件,烧录到开发板上即可。但是这会导致两个问题,一是生成的内核会很大,二是如果我们要在现有的内核中新增或删除部分功能,将不得不重新编译内核,而这个过程是比较耗费时间的。那么有没有一种机制使得编译出的内核本身并不需要包含所有功能,而是在这些功能需要被使用的时候,其对应的代码可以被动态的加载到内核中呢?linux提供了这种机制,称为模块(MODULE)。模块的特点:模块本身不被编译如内核镜像,从而控制了内核的大小;模块一旦被加载,它就和内核中的其他部分完全一样;模块可以被卸载,使用非常方便。
网络设备:面向数据包的接收和发送而设计,它并不对应文件系统的节点。
除了网络设备以外,字符设备和块设备都被映射到linux文件系统的文件和目录,在linux中,一切皆文件。通过文件系统的系统调用接口open/write/read/close等函数调用即可访问字符设备和块设备。所有的字符设备和块设备都被统一的呈现给用户。块设备比字符设备复杂,在它上面会首先建立一个磁盘/Flash文件系统,如FAT、Ext3、YAFFS、JFFS等。这些文件系统规范了文件和目录在存储介质上的组织方式。应用程序可以使用linux的系统调用接口编程,也可以使用C库函数。linux设备驱动与整个软硬件系统的关系如图:
Linux内核的划分如图所示:
计算机系统的硬件主要由CPU、存储器和外设组成。随着IC制造工艺的发展,目前,芯片的集成度越来越高,往往在CPU内部就集成了存储器和外设适配器。ARM、PowerPC、MIPS等处理器都集成了UART、IIC控制器、USB控制器、SDRAM控制器等,有的处理器还集成了片内RAM和Flash。
驱动程序在Linux内核里扮演着特殊的角色.它们是截然不同的"黑盒子",使硬件的特殊的一部分响应定义好的内部编程接口.它们完全隐藏了设备工作的细节.用户的活动通过一套标准化的调用来进行,这些调用与特别的驱动是独立的;设备驱动的角色就是将这些调用映射到作用于实际硬件的和设备相关的操作上.这个编程接口是这样,驱动可以与内核的其他部分分开建立,并在需要的时候在运行时"插入".这种模块化使得Linux驱动易写,以致于目前有几百个驱动可用.总而言之:驱动就是linux给用户操作硬件提供的一个接口,它是一个存在于应用程序和实际设备间的软件层。
那么如果计算机系统中包含了操作系统,那么设备驱动会变得怎样呢?首先我们要知道操作系统的功能。操作系统的主要功能:进程管理、内存管理、文件管理、设备控制和网络管理等。操作系统的存在它要求设备驱动附加更多的代码和功能,把单一的“驱动硬件设备行动”变成了操作系统内与硬件交互的模块,它对外呈现为操作系统的API。此时我们需要将设备驱动融入到内核中。为了实现这个融合,必须在所有的设备驱动中设计面向操作系统内核的接口,这样的接口由操作系统规定。我们的linux操作系统是一个开源的操作系统,Linux的众多优良特性之一就是可以在运行时扩展由内核提供的特性的能力.这意味着你可以在系统正在运行着的时候增加内核的功能(也可以去除).每块可以在运行时添加到内核的代码,被称为一个模块. Linux内核提供了对许多模块类型的支持,包括但不限于设备驱动.每个模块由目标代码组成(没有连接成一个完整可执行文件),可以动态连接到运行中的内核中,通过insmod安装模块程序,以及通过rmmod移除模块.
块设备:如同字符设备,它可以用任意顺序进行访问,以块为单位进行操作,它会经过系统的快速缓冲。块设备通过位于/dev目录的文件系统结点来存取.一个块设备(例如一个磁盘)应该是可以驻有一个文件系统的. Linux允许应用程序读写一个块设备象一个字符设备一样--它允许一次传送任意数目的字节.结果就是,块和字符设备的区别仅仅在内核在内部管理数据的方式上,因此在内核/驱动的软件接口上有所不同.
并不是所有的计算机系统都一定要运行操作系统,在许多情况下操作系统是不必要的。对于一些功能比较单一、控制并不复杂的系统,如公交车刷卡机、电冰箱、微波炉、简单的手机和小灵通等,并不需要多任务调度、文件系统、内存管理等复杂功能,用单任务架构完全可以很好的支持它们的工作。一个无限循环中夹杂对设备中断的检测或者对设备的轮询是这种系统中软件的典型架构。在这样的系统中,虽然不存在操作系统,但是设备驱动往往是必须存在的。一般情况下,对每一种设备驱动都来自百度文库定义
由此可见,设备驱动充当了硬件和应用软件之间的纽带,它使得应用软件只需要调用系统的一些应用编程接口(API)就可以让硬件去完成相应的操作。在没有操作系统的情况下,我们可以根据硬件设备的特点利用汇编和C语言的混合编程来操作硬件。在有操作系统的情况下,设备驱动的结构则由相应的操作系统定义,然后驱动工程师必须按照相应的架构设计设备驱动,这样,设备驱动才能良好的整合到操作系统的内核中。
·1基础知识
设备驱动的作用:任何一个计算机系统的运行都是系统中软硬件协作的结果,没有硬件的软件是空中楼阁,没有软件的硬件则是一堆废铁。硬件是底层基础,是所有软件得以运行的平台,代码最终会落实为硬件上的组合逻辑与时序逻辑;软件则实现了具体应用,它按照各种不同的业务需求而设计,满足了用户的需求。软件和硬件不应该相互渗透到对方的领域。为了尽快的完成设计,应用软件工程师不想也不必关心硬件,而硬件工程师也难掌握软件编程语言。例如,应用软件工程师在使用printf函数输出信息的时候,他不用知道具体底层是怎么实现将信息输出到显示屏或者串口上的。也就是说,应用软件工程师需要看到的是一个没有硬件的纯粹的软件世界,他不用知道底层的硬件原理,而是通过一些通用的接口函数就可以操作。那么这些接口函数是怎么提供给上层的软件工程师的呢,那这个艰巨的任务就落在了驱动工程师的头上。
3类设备如下:
字符设备:一个字符( char )设备是一种可以当作一个字节流来存取的设备(如同一个文件);它是必须以串行顺序依次进行访问的设备,如触摸屏、磁带驱动器、鼠标等。这样的驱动常常至少实现open, close, read,和write系统调用.它不经过系统的快速缓冲。
·2 linux内核模块编程
linux内核的整体结构非常庞大,其包含的组件也非常多,那么我们怎么把需要的部分都包含在内核中呢?一种方法时把所有需要的功能都编译到内核,利用make zImage可以实现,并会生成镜像文件,烧录到开发板上即可。但是这会导致两个问题,一是生成的内核会很大,二是如果我们要在现有的内核中新增或删除部分功能,将不得不重新编译内核,而这个过程是比较耗费时间的。那么有没有一种机制使得编译出的内核本身并不需要包含所有功能,而是在这些功能需要被使用的时候,其对应的代码可以被动态的加载到内核中呢?linux提供了这种机制,称为模块(MODULE)。模块的特点:模块本身不被编译如内核镜像,从而控制了内核的大小;模块一旦被加载,它就和内核中的其他部分完全一样;模块可以被卸载,使用非常方便。
网络设备:面向数据包的接收和发送而设计,它并不对应文件系统的节点。
除了网络设备以外,字符设备和块设备都被映射到linux文件系统的文件和目录,在linux中,一切皆文件。通过文件系统的系统调用接口open/write/read/close等函数调用即可访问字符设备和块设备。所有的字符设备和块设备都被统一的呈现给用户。块设备比字符设备复杂,在它上面会首先建立一个磁盘/Flash文件系统,如FAT、Ext3、YAFFS、JFFS等。这些文件系统规范了文件和目录在存储介质上的组织方式。应用程序可以使用linux的系统调用接口编程,也可以使用C库函数。linux设备驱动与整个软硬件系统的关系如图:
Linux内核的划分如图所示:
计算机系统的硬件主要由CPU、存储器和外设组成。随着IC制造工艺的发展,目前,芯片的集成度越来越高,往往在CPU内部就集成了存储器和外设适配器。ARM、PowerPC、MIPS等处理器都集成了UART、IIC控制器、USB控制器、SDRAM控制器等,有的处理器还集成了片内RAM和Flash。
驱动程序在Linux内核里扮演着特殊的角色.它们是截然不同的"黑盒子",使硬件的特殊的一部分响应定义好的内部编程接口.它们完全隐藏了设备工作的细节.用户的活动通过一套标准化的调用来进行,这些调用与特别的驱动是独立的;设备驱动的角色就是将这些调用映射到作用于实际硬件的和设备相关的操作上.这个编程接口是这样,驱动可以与内核的其他部分分开建立,并在需要的时候在运行时"插入".这种模块化使得Linux驱动易写,以致于目前有几百个驱动可用.总而言之:驱动就是linux给用户操作硬件提供的一个接口,它是一个存在于应用程序和实际设备间的软件层。
那么如果计算机系统中包含了操作系统,那么设备驱动会变得怎样呢?首先我们要知道操作系统的功能。操作系统的主要功能:进程管理、内存管理、文件管理、设备控制和网络管理等。操作系统的存在它要求设备驱动附加更多的代码和功能,把单一的“驱动硬件设备行动”变成了操作系统内与硬件交互的模块,它对外呈现为操作系统的API。此时我们需要将设备驱动融入到内核中。为了实现这个融合,必须在所有的设备驱动中设计面向操作系统内核的接口,这样的接口由操作系统规定。我们的linux操作系统是一个开源的操作系统,Linux的众多优良特性之一就是可以在运行时扩展由内核提供的特性的能力.这意味着你可以在系统正在运行着的时候增加内核的功能(也可以去除).每块可以在运行时添加到内核的代码,被称为一个模块. Linux内核提供了对许多模块类型的支持,包括但不限于设备驱动.每个模块由目标代码组成(没有连接成一个完整可执行文件),可以动态连接到运行中的内核中,通过insmod安装模块程序,以及通过rmmod移除模块.
块设备:如同字符设备,它可以用任意顺序进行访问,以块为单位进行操作,它会经过系统的快速缓冲。块设备通过位于/dev目录的文件系统结点来存取.一个块设备(例如一个磁盘)应该是可以驻有一个文件系统的. Linux允许应用程序读写一个块设备象一个字符设备一样--它允许一次传送任意数目的字节.结果就是,块和字符设备的区别仅仅在内核在内部管理数据的方式上,因此在内核/驱动的软件接口上有所不同.
并不是所有的计算机系统都一定要运行操作系统,在许多情况下操作系统是不必要的。对于一些功能比较单一、控制并不复杂的系统,如公交车刷卡机、电冰箱、微波炉、简单的手机和小灵通等,并不需要多任务调度、文件系统、内存管理等复杂功能,用单任务架构完全可以很好的支持它们的工作。一个无限循环中夹杂对设备中断的检测或者对设备的轮询是这种系统中软件的典型架构。在这样的系统中,虽然不存在操作系统,但是设备驱动往往是必须存在的。一般情况下,对每一种设备驱动都来自百度文库定义
由此可见,设备驱动充当了硬件和应用软件之间的纽带,它使得应用软件只需要调用系统的一些应用编程接口(API)就可以让硬件去完成相应的操作。在没有操作系统的情况下,我们可以根据硬件设备的特点利用汇编和C语言的混合编程来操作硬件。在有操作系统的情况下,设备驱动的结构则由相应的操作系统定义,然后驱动工程师必须按照相应的架构设计设备驱动,这样,设备驱动才能良好的整合到操作系统的内核中。
·1基础知识
设备驱动的作用:任何一个计算机系统的运行都是系统中软硬件协作的结果,没有硬件的软件是空中楼阁,没有软件的硬件则是一堆废铁。硬件是底层基础,是所有软件得以运行的平台,代码最终会落实为硬件上的组合逻辑与时序逻辑;软件则实现了具体应用,它按照各种不同的业务需求而设计,满足了用户的需求。软件和硬件不应该相互渗透到对方的领域。为了尽快的完成设计,应用软件工程师不想也不必关心硬件,而硬件工程师也难掌握软件编程语言。例如,应用软件工程师在使用printf函数输出信息的时候,他不用知道具体底层是怎么实现将信息输出到显示屏或者串口上的。也就是说,应用软件工程师需要看到的是一个没有硬件的纯粹的软件世界,他不用知道底层的硬件原理,而是通过一些通用的接口函数就可以操作。那么这些接口函数是怎么提供给上层的软件工程师的呢,那这个艰巨的任务就落在了驱动工程师的头上。