PCA课件 第七章 嵌入式设备驱动_第1页
PCA课件 第七章 嵌入式设备驱动_第2页
PCA课件 第七章 嵌入式设备驱动_第3页
PCA课件 第七章 嵌入式设备驱动_第4页
PCA课件 第七章 嵌入式设备驱动_第5页
已阅读5页,还剩57页未读 继续免费阅读

下载本文档

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

文档简介

第7章嵌入式Linux的设备驱动Linux系统驱动程序开发简介常用的系统支持

Linux系统网络设备驱动程序

编写Linux网络驱动程序中需要注意的问题

第7章嵌入式Linux的设备驱动Linux系统驱动程序7.1Linux系统驱动程序开发简介Linux中设备被抽象出来,所有设备都看成文件如:系统中第一个IDE硬盘被表示成/dev/hda

设备的读写和普通文件一样设备驱动程序主要完成这些功能:探测设备和初始化设备从设备接收数据并提交给内核从内核接收数据送到设备检测和处理设备错误7.1Linux系统驱动程序开发简介Linux中设备被抽象Linux设备驱动程序分类Linux系统的设备分为字符设备(chardevice),块设备(blockdevice)和网络设备(networkdevice)三种字符设备是指存取时没有缓存的设备。如:系统的串口设备/dev/cua0和/dev/cua1块设备的读写都有缓存来支持,并且块设备必须能够随机存取(randomaccess),且不管块位于设备中何处都可以对其进行读写。块设备可以通过其设备相关文件进行访问,但更为平常的访问方法是通过文件系统。只有块设备才能支持可安装文件系统。如硬盘用mknod命令创建的块设备特殊文件与字符设备特殊文件

网络设备在Linux里做专门的处理,可以通过BSD套接口访问。Linux设备驱动程序分类Linux系统的设备分为字符设备1、核心代码

设备驱动是核心的一部分,象核心中其它代码一样,出错将导致系统的严重损伤。一个编写奇差的设备驱动甚至能使系统崩溃并导致文件系统的破坏和数据丢失。

2、核心接口

设备驱动必须为Linux核心或者其从属子系统提供一个标准接口。例如终端驱动为Linux核心提供了一个文件I/O接口而SCSI设备驱动为SCSI子系统提供了一个SCSI设备接口,同时此子系统为核心提供了文件I/O和buffercache接口。

Linux核心中的设备驱动具有的共性:1、核心代码Linux核心中的设备驱动具有的共性:3、核心机制与服务

设备驱动可以使用标准的核心服务如内存分配、中断发送和等待队列等等。

4、动态可加载

多数Linux设备驱动可以在核心模块发出加载请求时加载,同时在不再使用时卸载。这样核心能有效地利用系统资源。

5、可配置

Linux设备驱动可以连接到核心中。6、动态性

当系统启动及设备驱动初始化时将查找它所控制的硬件设备。如果某个设备的驱动为一个空过程并不会有什么问题。此时此设备驱动仅仅是一个冗余的程序,它除了会占用少量系统内存外不会对系统造成什么危害。3、核心机制与服务驱动程序的几个概念1、轮询与中断轮询方式意味着需要经常读取设备的状态,一直到设备状态表明请求已经完成为止。如果设备驱动被连接进入核心,这时使用轮询方式将会带来灾难性后果:核心将在此过程中无所事事,直到设备完成此请求。但是轮询设备驱动可以通过使用系统定时器,使核心周期性调用设备驱动中的某个例程来检查设备状态。定时器过程可以检查命令状态及Linux软盘驱动的工作情况。使用定时器是轮询方式中最好的一种,但更有效的方法是使用中断。驱动程序的几个概念1、轮询与中断轮询方式意味着需要经常读取设基于中断的设备驱动会在它所控制的硬件设备需要服务时引发一个硬件中断。如以太网设备驱动从网络上接收到一个以太数据报时都将引起中断。Linux核心需要将来自硬件设备的中断传递到相应的设备驱动。这个过程由设备驱动向核心注册其使用的中断来协助完成。此中断处理例程的地址和中断号都将被记录下来。在/proc/interrupts文件中你可以看到设备驱动所对应的中断号及类型:0:727432timer1:20534keyboard2:0cascade3:79691+serial4:28258+serial5:1soundblaster11:20868+aic7xxx13:1matherror14:247+ide015:170+ide1基于中断的设备驱动会在它所控制的硬件设备需要服务时引发一个硬2、直接内存访问(DMA)DMA控制器可以在不受处理器干预的情况下在设备和系统内存之间高速传输数据。设备驱动使用DMA时必须十分小心。首先DMA控制器没有任何虚拟内存的概念,它只存取系统中的物理内存。同时用作DMA传输缓冲的内存空间必须是连续物理内存块。这意味着不能在进程虚拟地址空间内直接使用DMA。但是你可以将进程的物理页面加锁以防止在DMA操作过程中被交换到交换设备上去。另外DMA控制器所存取物理内存有限。DMA通道地址寄存器代表DMA地址的高16位而页面寄存器记录的是其余8位。所以DMA请求被限制到内存最低16M字节中。2、直接内存访问(DMA)DMA控制器可以在不受处理器干Linux通过dma_chan(每个DMA通道一个)数组来跟踪DMA通道的使用情况。dma_chan结构中包含有两个域,一个是指向此DMA通道拥有者的指针,另一个指示DMA通道是否已经被分配出去。当敲入cat/proc/dma打印出来的结果就是dma_chan结构数组。Linux通过dma_chan(每个DMA通道一个)数组来3、

内存设备驱动必须谨慎使用内存。由于它属于核心,所以不能使用虚拟内存。Linux为设备驱动提供了一组核心内存分配与回收过程。核心内存以2的次幂大小的块来分配。如512或128字节,此时即使设备驱动的需求小于这个数量也会分配这么多。所以设备驱动的内存分配请求可得到以块大小为边界的内存。这样核心进行空闲块组合更加容易。请求分配核心内存时Linux需要完成许多额外的工作。如果系统中空闲内存数量较少,则可能需要丢弃些物理页面或将其写入交换设备。一般情况下Linux将挂起请求者并将此进程放置到等待队列中直到系统中有足够的物理内存为止。3、

内存设备驱动必须谨慎使用内存。由于它属于核心,所以4、设备驱动与核心的接口

Linux核心与设备驱动之间必须有一个以标准方式进行互操作的接口。每一类设备驱动:字符设备、块设备及网络设备都提供了通用接口以便在需要时为核心提供服务。这种通用接口使得核心可以以相同的方式来对待不同的设备及设备驱动。如SCSI和IDE硬盘的区别很大但Linux对它们使用相同的接口。Linux动态性很强。每次Linux核心启动时如遇到不同的物理设备将需要不同的物理设备驱动。4、设备驱动与核心的接口Linux核心与设备驱动之间必须4.1

字符设备字符设备是Linux设备中最简单的一种字符设备初始化时,它的设备驱动通过在device_struct结构的chrdevs数组中添加一个入口来将其注册到Linux核心上。设备的主设备标志符用来对此数组进行索引(如对tty设备的索引4)

4.1

字符设备字符设备是Linux设备中最简单的一种4.2块设备块设备也支持以文件方式访问。Linux在blkdevs数组中维护所有已注册的块设备。象chrdevs数组一样,blkdevs也使用设备的主设备号进行索引。其入口也是device_struct结构。和字符设备不同的是系统有几类块设备。SCSI设备是一类而IDE设备则是另外一类。和普通文件操作接口一样,每个块设备驱动必须为buffercache提供接口。每个块设备驱动将填充其在blk_dev数组中的blk_dev_struct结构入口。数组的索引值还是此设备的主设备号。4.2块设备块设备也支持以文件方式访问。Linux在bbuffercache块设备请求上图表示每个请求有指向一个或多个buffer_hear结构的指针,每个请求读写一块数据。一旦设备驱动完成了请求则它必须将每个buffer_heard结构从request结构中清除。buffercache块设备请求上图表示每个请求有指向一4.3网络设备网络设备,即Linux的网络子系统,是一个发送与接收数据包的实体。它一般是一个象以太网卡的物理设备。每个网络设备都用一个device结构来表示,所有传输与接收到的网络数据用一个sk_buff结构来表示。这些数据结构使得网络协议头可以更容易的添加与删除。4.3网络设备网络设备,即Linux的网络子系统,是一网络设备特殊文件仅在于系统网络设备发现与初始化时建立。它们使用标准的命名方法,每个名字代表一种类型的设备。多个相同类型设备将从0开始记数。这样以太网设备被命名为/dev/eth0,/dev/eth1,/dev/eth2等等。一些常见的网络设备如下:/dev/ethN以太网设备/dev/slNSLIP设备/dev/pppNPPP设备/dev/loLoopback设备网络设备特殊文件仅在于系统网络设备发现与初始化时建立。它编写驱动程序的一些基本概念读写几乎所有设备都有输入和输出。每个驱动程序要负责本设备的读写操作。操作系统的其他不需要知道对设备的具体读写操作怎样进行,这些都由驱动程序屏蔽掉了。操作系统定义好一些读写接口,由驱动程序完成具体的功能。在驱动程序初始化时,需要把具有这种接口的读写函数注册进操作系统。编写驱动程序的一些基本概念读写中断中断在现代计算机结构中有重要的地位。操作系统必须提供驱动程序响应中断的能力。一般是把一个中断处理程序注册到系统中去。操作系统在硬件中断发生后调用驱动程序的处理程序。Linux支持中断的共享,即多个设备共享一个中断。PCA课件第七章嵌入式设备驱动时钟在实现驱动程序时,很多地方会用到时钟。如某些协议里的超时处理,没有中断机制的硬件的轮询等。操作系统应为驱动程序提供定时机制。一般是在预定的时间过了以后回调注册的时钟函数。时钟常用的系统支持

内存申请和释放中断时钟I/O中断打开关闭打印信息注册驱动程序常用的系统支持内存申请和释放内存申请和释放include/linux/kernel.h里声明了kmalloc()和kfree()。用于在内核模式下申请和释放内存。与用户模式下的malloc()不同,kmalloc()申请空间有大小限制。长度是2的整次方。可以申请的最大长度也有限制。另外kmalloc()有priority参数Kfree()释放的内存必须是kmalloc()申请的内存申请和释放include/linux/kernel.h申请中断和释放中断request_irq()、free_irq()是驱动程序申请中断和释放中断的调用。在include/linux/sched.h里声明申请中断和释放中断request_irq()、free_i时钟时钟的处理类似中断,也是登记一个时间处理函数,在预定的时间过后,系统会调用这个函数。在include/linux/timer.h里声明使用时钟,先声明一个timer_list结构,调用init_timer对它进行初始化。Time_list结构里expires是标明这个时钟的周期,单位采用jiffies的单位。jiffy指连续微处理器时钟周期间的时间长度时钟时钟的处理类似中断,也是登记一个时间处理函数,在预定的I/OI/O端口的存取使用:inlineunsignedintinb(unsignedshortport);inlineunsignedintinb_p(unsignedshortport);inlinevoidoutb(charvalue,unsignedshortport);inlinevoidoutb_p(charvalue,unsignedshortport);在include/adm/io.h里定义I/OI/O端口的存取使用:中断打开关闭系统提供给驱动程序开放和关闭响应中断的能力是在include/asm/system.h#definecli()__asm____volatile__("cli"::)#definesti()__asm____volatile__("sti"::)中断打开关闭系统提供给驱动程序开放和关闭响应中断的能力打印信息驱动程序要输出信息使用printk()include/linux/kernel.h里声明打印信息驱动程序要输出信息使用printk()注册驱动程序如果使用模块(module)方式加载驱动程序,需要在模块初始化时把设备注册到系统设备表里去,不再使用时,把设备从系统中卸除定义在drivers/net/net_init.h里的两个函数完成这个工作Intregister_netdev(structdevice*dev);voidunregister_netdev(structdevice*dev);注册驱动程序如果使用模块(module)方式加载驱动程序,网络驱动程序的结构所有的Linux网络驱动程序遵循通用的接口设计时采用的是面向对象的方法一个设备就是一个对象(device结构),它内部有自己的数据和方法一个网络设备最基本的方法有初始化、发送和接收网络驱动程序的结构所有的Linux网络驱动程序遵循通用的接网络驱动程序的基本方法初始化(initialize)打开(open)关闭(stop)发送(hard_start_xmit)接收(reception)硬件帧头(hard_header)地址解析(xarp)参数设置和统计数据网络驱动程序的基本方法初始化(initialize)网络驱动程序中用到的数据结构最重要的是网络设备的数据结构。定义在include/linux/netdevice.hsk_buffLinux网络各层之间的数据传送都是通过sk_buff网络驱动程序中用到的数据结构最重要的是网络设备的数据结构。编写Linux网络驱动程序中需要注意的问题

中断共享硬件发送忙时的处理流量控制(flowcontrol)调试编写Linux网络驱动程序中需要注意的问题中断共享第7章嵌入式Linux的设备驱动Linux系统驱动程序开发简介常用的系统支持

Linux系统网络设备驱动程序

编写Linux网络驱动程序中需要注意的问题

第7章嵌入式Linux的设备驱动Linux系统驱动程序7.1Linux系统驱动程序开发简介Linux中设备被抽象出来,所有设备都看成文件如:系统中第一个IDE硬盘被表示成/dev/hda

设备的读写和普通文件一样设备驱动程序主要完成这些功能:探测设备和初始化设备从设备接收数据并提交给内核从内核接收数据送到设备检测和处理设备错误7.1Linux系统驱动程序开发简介Linux中设备被抽象Linux设备驱动程序分类Linux系统的设备分为字符设备(chardevice),块设备(blockdevice)和网络设备(networkdevice)三种字符设备是指存取时没有缓存的设备。如:系统的串口设备/dev/cua0和/dev/cua1块设备的读写都有缓存来支持,并且块设备必须能够随机存取(randomaccess),且不管块位于设备中何处都可以对其进行读写。块设备可以通过其设备相关文件进行访问,但更为平常的访问方法是通过文件系统。只有块设备才能支持可安装文件系统。如硬盘用mknod命令创建的块设备特殊文件与字符设备特殊文件

网络设备在Linux里做专门的处理,可以通过BSD套接口访问。Linux设备驱动程序分类Linux系统的设备分为字符设备1、核心代码

设备驱动是核心的一部分,象核心中其它代码一样,出错将导致系统的严重损伤。一个编写奇差的设备驱动甚至能使系统崩溃并导致文件系统的破坏和数据丢失。

2、核心接口

设备驱动必须为Linux核心或者其从属子系统提供一个标准接口。例如终端驱动为Linux核心提供了一个文件I/O接口而SCSI设备驱动为SCSI子系统提供了一个SCSI设备接口,同时此子系统为核心提供了文件I/O和buffercache接口。

Linux核心中的设备驱动具有的共性:1、核心代码Linux核心中的设备驱动具有的共性:3、核心机制与服务

设备驱动可以使用标准的核心服务如内存分配、中断发送和等待队列等等。

4、动态可加载

多数Linux设备驱动可以在核心模块发出加载请求时加载,同时在不再使用时卸载。这样核心能有效地利用系统资源。

5、可配置

Linux设备驱动可以连接到核心中。6、动态性

当系统启动及设备驱动初始化时将查找它所控制的硬件设备。如果某个设备的驱动为一个空过程并不会有什么问题。此时此设备驱动仅仅是一个冗余的程序,它除了会占用少量系统内存外不会对系统造成什么危害。3、核心机制与服务驱动程序的几个概念1、轮询与中断轮询方式意味着需要经常读取设备的状态,一直到设备状态表明请求已经完成为止。如果设备驱动被连接进入核心,这时使用轮询方式将会带来灾难性后果:核心将在此过程中无所事事,直到设备完成此请求。但是轮询设备驱动可以通过使用系统定时器,使核心周期性调用设备驱动中的某个例程来检查设备状态。定时器过程可以检查命令状态及Linux软盘驱动的工作情况。使用定时器是轮询方式中最好的一种,但更有效的方法是使用中断。驱动程序的几个概念1、轮询与中断轮询方式意味着需要经常读取设基于中断的设备驱动会在它所控制的硬件设备需要服务时引发一个硬件中断。如以太网设备驱动从网络上接收到一个以太数据报时都将引起中断。Linux核心需要将来自硬件设备的中断传递到相应的设备驱动。这个过程由设备驱动向核心注册其使用的中断来协助完成。此中断处理例程的地址和中断号都将被记录下来。在/proc/interrupts文件中你可以看到设备驱动所对应的中断号及类型:0:727432timer1:20534keyboard2:0cascade3:79691+serial4:28258+serial5:1soundblaster11:20868+aic7xxx13:1matherror14:247+ide015:170+ide1基于中断的设备驱动会在它所控制的硬件设备需要服务时引发一个硬2、直接内存访问(DMA)DMA控制器可以在不受处理器干预的情况下在设备和系统内存之间高速传输数据。设备驱动使用DMA时必须十分小心。首先DMA控制器没有任何虚拟内存的概念,它只存取系统中的物理内存。同时用作DMA传输缓冲的内存空间必须是连续物理内存块。这意味着不能在进程虚拟地址空间内直接使用DMA。但是你可以将进程的物理页面加锁以防止在DMA操作过程中被交换到交换设备上去。另外DMA控制器所存取物理内存有限。DMA通道地址寄存器代表DMA地址的高16位而页面寄存器记录的是其余8位。所以DMA请求被限制到内存最低16M字节中。2、直接内存访问(DMA)DMA控制器可以在不受处理器干Linux通过dma_chan(每个DMA通道一个)数组来跟踪DMA通道的使用情况。dma_chan结构中包含有两个域,一个是指向此DMA通道拥有者的指针,另一个指示DMA通道是否已经被分配出去。当敲入cat/proc/dma打印出来的结果就是dma_chan结构数组。Linux通过dma_chan(每个DMA通道一个)数组来3、

内存设备驱动必须谨慎使用内存。由于它属于核心,所以不能使用虚拟内存。Linux为设备驱动提供了一组核心内存分配与回收过程。核心内存以2的次幂大小的块来分配。如512或128字节,此时即使设备驱动的需求小于这个数量也会分配这么多。所以设备驱动的内存分配请求可得到以块大小为边界的内存。这样核心进行空闲块组合更加容易。请求分配核心内存时Linux需要完成许多额外的工作。如果系统中空闲内存数量较少,则可能需要丢弃些物理页面或将其写入交换设备。一般情况下Linux将挂起请求者并将此进程放置到等待队列中直到系统中有足够的物理内存为止。3、

内存设备驱动必须谨慎使用内存。由于它属于核心,所以4、设备驱动与核心的接口

Linux核心与设备驱动之间必须有一个以标准方式进行互操作的接口。每一类设备驱动:字符设备、块设备及网络设备都提供了通用接口以便在需要时为核心提供服务。这种通用接口使得核心可以以相同的方式来对待不同的设备及设备驱动。如SCSI和IDE硬盘的区别很大但Linux对它们使用相同的接口。Linux动态性很强。每次Linux核心启动时如遇到不同的物理设备将需要不同的物理设备驱动。4、设备驱动与核心的接口Linux核心与设备驱动之间必须4.1

字符设备字符设备是Linux设备中最简单的一种字符设备初始化时,它的设备驱动通过在device_struct结构的chrdevs数组中添加一个入口来将其注册到Linux核心上。设备的主设备标志符用来对此数组进行索引(如对tty设备的索引4)

4.1

字符设备字符设备是Linux设备中最简单的一种4.2块设备块设备也支持以文件方式访问。Linux在blkdevs数组中维护所有已注册的块设备。象chrdevs数组一样,blkdevs也使用设备的主设备号进行索引。其入口也是device_struct结构。和字符设备不同的是系统有几类块设备。SCSI设备是一类而IDE设备则是另外一类。和普通文件操作接口一样,每个块设备驱动必须为buffercache提供接口。每个块设备驱动将填充其在blk_dev数组中的blk_dev_struct结构入口。数组的索引值还是此设备的主设备号。4.2块设备块设备也支持以文件方式访问。Linux在bbuffercache块设备请求上图表示每个请求有指向一个或多个buffer_hear结构的指针,每个请求读写一块数据。一旦设备驱动完成了请求则它必须将每个buffer_heard结构从request结构中清除。buffercache块设备请求上图表示每个请求有指向一4.3网络设备网络设备,即Linux的网络子系统,是一个发送与接收数据包的实体。它一般是一个象以太网卡的物理设备。每个网络设备都用一个device结构来表示,所有传输与接收到的网络数据用一个sk_buff结构来表示。这些数据结构使得网络协议头可以更容易的添加与删除。4.3网络设备网络设备,即Linux的网络子系统,是一网络设备特殊文件仅在于系统网络设备发现与初始化时建立。它们使用标准的命名方法,每个名字代表一种类型的设备。多个相同类型设备将从0开始记数。这样以太网设备被命名为/dev/eth0,/dev/eth1,/dev/eth2等等。一些常见的网络设备如下:/dev/ethN以太网设备/dev/slNSLIP设备/dev/pppNPPP设备/dev/loLoopback设备网络设备特殊文件仅在于系统网络设备发现与初始化时建立。它编写驱动程序的一些基本概念读写几乎所有设备都有输入和输出。每个驱动程序要负责本设备的读写操作。操作系统的其他不需要知道对设备的具体读写操作怎样进行,这些都由驱动程序屏蔽掉了。操作系统定义好一些读写接口,由驱动程序完成具体的功能。在驱动程序初始化时,需要把具有这种接口的读写函数注册进操作系统。编写驱动程序的一些基本概念读写中断中断在现代计算机结构中有重要的地位。操作系统必须提供驱动程序响应中断的能力。一般是把一个中断处理程序注册到系统中去。操作系统在硬件中断发生后调用驱动程序的处理程序。Linux支持中断的共享,即多个设备共享一个中断。PCA课件第七章嵌入式设备驱动时钟在实现驱动程序时,很多地方会用到时钟。如某些协议里的超时处理,没有中断机制的硬件的轮询等。操作系统应为驱动程序提供定时机制。一般是在预定的时间过了以后回调注册的时钟函数。时钟常用的系统支持

内存申请和释放中断时钟I/O中断打开关闭打印信息注册驱动程序常用的系统支持内存申请和释放内存申请和释放include/linux/kernel.h里声明了kmalloc()和kfree()。用于在内核模式下申请和释放内存。与用户模式下的malloc()不同,kmalloc()申请空间有大小限制。长度是2的整次方。可以申请的最大长度也有限制。另外kmalloc()有priority参数Kfree()释放的内存必须是kmalloc()申请的内存申请和释放include/linux/kernel.h申请中断和释放中断request_irq()、free_irq()是驱动程序申请中断和释放中断的调用。在include/linux/sched.h里声明申请中断和释放中断request_irq()、free_i时钟时钟的处理类似中断,也是登记一个时间处理函数,在预定的时间过后,系统会调用这个函数。在include/linux/timer.h里声明使用时钟,先声明一个timer_list结构,调用init_timer对它进行初始化。Time_list结构里expires是标明这个时钟的周期,单位采用jiffies的单位。jiffy指连续微处理器时钟周期间的时间长度时钟时钟的处理类似中断,也是登记一个时间处理函数,在预定的I/OI/O端口的

温馨提示

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

评论

0/150

提交评论