版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
(第2版)(第2版)主讲内容第8章
嵌入式系统BootLoader技术第9章
嵌入式Linux操作系统移植第10章
嵌入式Linux设备驱动程序开发第11章
嵌入式Linux应用程序设计主讲内容第8章嵌入式系统BootLoader技术10.1嵌入式Linux驱动程序开发基础
10.1.1嵌入式Linux设备驱动程序分类静态加载的驱动程序动态加载的驱动程序Linux将设备按照功能特性划分为三种类型:字符设备,块设备和网络设备。10.1.2最简单的内核模块1.helloworld模块源代码2.模块的编译3.模块的加载和卸载10.1嵌入式Linux驱动程序开发基础
10.1.110.1嵌入式Linux驱动程序开发基础
10.2嵌入式Linux设备驱动重要技术10.2.1内存与I/O端口(1)内核空间和用户空间(2)内核中内存分配内核中获取内存的几种方式如下。①通过伙伴算法分配大片物理内存②通过slab缓冲区分配小片物理内存③非连续内存区分配④高端内存映射⑤固定线性地址映射10.1嵌入式Linux驱动程序开发基础
10.2嵌(3)I/O端口根据CPU体系结构的不同,CPU对IO端口的编址方式有两种:I/O映射方式(I/O-mapped)和内存映射方式(Memory-mapped)。
下面主要讨论一下内存映射方式访问I/O端口的方法,我们称之为I/O内存操作。I/O内存区必须在使用前分配I/O内存映射访问I/O内存映射到用户空间10.1嵌入式Linux驱动程序开发基础
(3)I/O端口10.1嵌入式Linux驱动程序开发基10.2.2同步机制Linux内核中包含的同步机制包括:原子操作、信号量(semaphore)、读写信号量(rw_semaphore)、自旋锁(spinlock)、大内核锁(BigKernelLock,BKL)、读写锁(rwlock)、读拷贝更新(Read-CopyUpdate,RCU)和seqlock(顺序锁)等。10.2.2同步机制1.原子操作原子操作主要用于实现资源计数,很多引用计数(refcnt)就是通过原子操作实现的。原子类型定义如下:typedefstruct{volatileintcounter;}atomic_t;原子操作通常用于实现资源的引用计数2.信号量信号量在创建时需要设置一个初始值.
3.读写信号量读写信号量有两种实现:一种是通用的,不依赖于硬件架构一种是架构相关的1.原子操作读写信号量的相关API有:DECLARE_RWSEM(name)该宏声明一个读写信号量name并对其进行初始化。voidinit_rwsem(structrw_semaphore*sem);该函数对读写信号量sem进行初始化。voiddown_read(structrw_semaphore*sem);在Linux中,每一个进程都用一个类型为task_t或structtask_struct的结构来描述读写信号量的相关API有:4.自旋锁一个执行单元要想访问被自旋锁保护的共享资源,必须先得到锁,在访问完共享资源后,必须释放锁。自旋锁的API有:spin_lock_init(x);4.自旋锁10.2.3阻塞与非阻塞1.阻塞操作2.非阻塞操作10.2.4时间问题1.延时操作:(1)长延时。(2)短延时2.内核定时器内核提供给驱动许多函数来声明、注册、以及去除内核定时器。
3.工作队列采用缺省工作者线程来实现工作队列的API:①INIT_WORK(_work,_func,_data)10.2.3阻塞与非阻塞②intschedule_work(structwork_struct*work)③intschedule_delayed_work(structwork_struct*work,unsignedlongdelay)④voidflush_scheduled_work(void)⑤intcancel_delayed_work(structwork_struct*work)
创建自己的工作者线程和工作队列,API:①structworkqueue_struct*create_workqueue(constchar*name)②intqueue_work(structworkqueue_struct*wq,structwork_struct*work)③intqueue_delayed_work(structworkqueue_struct*wq,structwork_struct*work,unsignedlongdelay)④voidflush_workqueue(structworkqueue_struct*wq)⑤voiddestroy_workqueue(structworkqueue_struct*wq)②intschedule_work(structwor10.2.5中断处理在Linux系统里,对中断的处理是属于系统核心部分,因而如果设别与系统之间以中断方式进行数据交换,就必须把该设备的驱动程序作为系统核心的一部分。设备驱动程序通过调用request_irq函数来申请中断,通过free_irq来释放中断。它们被定义为:#include<linux/sched.h>intrequest_irq(unsignedintirq,void(*handler)(intirq,voiddev_id,structpt_regs*regs),unsignedlongflags,constchar*device,void*dev_id);voidfree_irq(unsignedintirq,void*dev_id);10.2.5中断处理函数的参数如下。unsignedintirq:请求的中断号。irqreturn_t(*handler):安装的中断处理函数指针。unsignedlongflags:中断处理的属性。
constchar*dev_name:这个传递给request_irq的字串用在/proc/interrupts来显示中断的拥有者。
void*dev_id:用作共享中断的指针。函数的参数如下。10.3字符设备驱动程序字符设备驱动程序可以分为三个主要组成部分:1,自动配置和初始化子程序,负责检测所要驱动的硬件设备是否存在和是否能正常工作。2,服务于I/O请求的子程序,又称为驱动程序的上半部分。3,中断服务子程序,又称为驱动程序的下半部分。10.3.1字符设备驱动结构1.主次设备号:字符设备和块设备通过文件系统中的名子来存取。主编号标识设备相连的驱动。次编号被内核用来决定引用哪个设备。设备编号在驱动程序的内部具有固定的表示方式。在建立驱动时,需要做的第一件事是获取一个或多个设备编号来使用。在驱动程序执行的过程中,如果不希望在使用该设备,要及时的将设备编号释放:10.3字符设备驱动程序2.驱动相关数据结构大部分的基础性的驱动操作包括3个重要的内核数据结构,它们是file_operations,file,和inode。(1)文件操作(file_operations) file_operation结构表示了用户程序怎样对设备进行操作。这个结构,定义在<linux/fs.h>中,是一个函数指针的集合structmodule*owner。(2)文件结构 structfile定义于</linux/fs.h>,是设备驱动中第二个最重要的数据结构。(3)inode结构 inode结构由内核在内部用来表示文件。2.驱动相关数据结构3.自动配置和初始化(1)初始化。当驱动程序将被加载的时候,首先会调用初始函数进行自动配置。(2)清除处理。4.中断处理如果需要驱动程序具有中断处理的能力,必须进行中断申请。从request_irq返回给请求函数的返回值是0指示成功,为负表示错误码。中断处理可以在驱动初始化时安装或者在设备第一次打开时。在中断的使用过程中还可以对其进行使能和禁止操作3.自动配置和初始化10.3.2字符设备驱动实例——LED驱动1.LED驱动程序分析本驱动程序文件名为led2440.c2.驱动模块加入内核使用命令:cp-fled2440.c/linux-2.6.32.4/drivers/char/编辑Kconfig文件:修改Makefile文件:配置、编译内核执行makezImage内核映像和驱动程序模块会先后被编译完毕。将内核下载至开发板;将驱动程序模块加入到根文件系统后,下载至开发板。这样就可以调用驱动程序进行演示了。10.3.2字符设备驱动实例——LED驱动3.LED驱动演示(1)驱动程序模块加载到内核。进入驱动程序模块所在目录,执行:insmod-fled2440.ko(2)建立设备节点。也就是建立用户程序关联到驱动程序的途径(3)演示程序。建立一个LED控制的简单演示程序led2440test3.LED驱动演示10.4网络设备驱动程序10.4.1Linux网络设备简介1.Linux网络驱动基础2.DM9000控制器10.4.2网络驱动核心数据结构分成几个方面对其进行介绍通用信息硬件描述信息协议相关信息设备操作函数接口10.4网络设备驱动程序10.4.3网络驱动程序分析1.初始化、清理网络设备
网络设备初始化的工作主要是确定硬件设备的存在,以及将硬件设备加载到设备链表中,为网络设备的激活做准备。需要注意这两个变量:name和owner。2.打开和关闭网络设备open函数主要用来完成对网络设备中断进行注册、通过配置物理接口初始化设备,以及为发送数据准备队列。10.4.3网络驱动程序分析3.中断处理
网络驱动程序的中断处理函数在网络设备激活时进行注册,主要用于完成:现场保护及中断屏蔽、读取网络设备寄存器信息及判断中断原因并处理、恢复中断现场。函数首先需要获得自旋锁,然后将当前的寄存器地址保存下来,以便返回的时候继续进行被打断的作业;接着就是屏蔽所有的中断,读取中断状态寄存器并清除中断状态寄存器,然后就开始真正的中断处理了。当发生接收中断时,中断函数调用dm9000_rx()函数。
4.sk_buff结构sk_buff的数据成员分为两部分:一部分是实际在网络中要传输的部分,数据区(Packetdatestorage);一部分由内核管理服务于结构链表。
3.中断处理还有一些常用的成员如:sk_buff->tstamp:sk_buff->dev:sk_buff->protocol:
内核提供了一系列用于操作sk_buff数据结构的函数,用于分配、释放、复制、克隆、扩展等功能,下面介绍些常用的。structsk_buff*alloc_skb(unsignedintlen,intpriority)structsk_buff*dev_alloc_skb(unsignedintlen)还有一些常用的成员如:
5.数据发送处理
6.数据接收处理
数据接收的主要工作有:检查接收的到的数据包是否正确;根据数据被长度在内核空间为数据包申请sk_buff;把数据包复制到sk_buff,填写相关成员后插入队列;释放网络芯片中分配的缓冲区。7.其它处理接口在网络设备结构中还有一些函数接口需要实现,如:(1)get_stats(2)set_multicast_list(3)tx_tiemout5.数据发送处理10.5设备驱动实例10.5.1ADC设备驱动实例
ADC是比较简单的字符设备,在此直接给出ADC的驱动程序源代码和注释说明。10.5.2PWM设备驱动实例10.5.3触摸屏设备驱动实例1.输入子系统
在Linux中,输入子系统(InputSubsystem)是由输入子系统设备驱动层、输入子系统核心层(InputCore)和输入子系统事件处理层(EventHandler)组成。10.5设备驱动实例设备的驱动的实现步骤如下:①在驱动模块加载函数中设置Input设备支持input子系统的哪些事件;②将Input设备注册到input子系统中;③在Input设备发生输入操作时(如:键盘被按下/抬起、触摸屏被触摸/抬起/移动、鼠标被移动/单击/抬起时等),提交所发生的事件及对应的键值/坐标等状态。在提交输入设备的事件后必须用下列方法使事件同步,让它告知input系统,设备驱动已经发出了一个完整的报告:voidinput_sync(structinput_dev*dev)设备的驱动的实现步骤如下:2.触摸屏驱动实现 S3C2440A芯片内部集成了触摸屏接口并与ADC接口相连。S3C2440A提供的触摸屏接口有4种处理模式,分别是:正常转换模式、单独的X/Y位置转换模式、自动X/Y位置转换模式和等待中断模式,在此实现自动X/Y位置转换模式和等待中断模式。a、驱动的加载和卸载:b、中断服务以及触摸屏状态、坐标的转换。2.触摸屏驱动实现 触摸屏转换过程为:第一步,如果触摸屏接收到触摸,则进入updown_ISR,如果能获取ADC_LOCK则调用touch_timer_fire,启动ADC;第二步ADC转换,如果小于四次继续转换,如果四次完毕后,启动1个时间滴答的定时器,停止ADC,也就是说在这个时间滴答内,ADC是停止的,这样可以防止屏幕抖动;第三步,如果1个时间滴答到时候,触摸屏仍然处于触摸状态则上报转换数据,并重启ADC,重复第二步;如果触摸笔释放了,则上报释放事件,并将触摸屏重新设置为等待中断状态。触摸屏转换过程为:10.6本章小结本章介绍了Linux2.6内核驱动程序的相关技术和一般开发方法。讲述了Linux驱动程序的功能、分类,通过一个简单的Helloworld模块来引入Linux2.6内核的模块运行机制,说明了驱动程序的同模块的关系,以及内核模块和驱动程序的加载使用方法。详细阐述了开发驱动程序所需技术,通过实例详细讲述了字符设备驱动程序的开发过程;对网络驱动程序进行了分析。10.6本章小结(第2版)(第2版)主讲内容第8章
嵌入式系统BootLoader技术第9章
嵌入式Linux操作系统移植第10章
嵌入式Linux设备驱动程序开发第11章
嵌入式Linux应用程序设计主讲内容第8章嵌入式系统BootLoader技术10.1嵌入式Linux驱动程序开发基础
10.1.1嵌入式Linux设备驱动程序分类静态加载的驱动程序动态加载的驱动程序Linux将设备按照功能特性划分为三种类型:字符设备,块设备和网络设备。10.1.2最简单的内核模块1.helloworld模块源代码2.模块的编译3.模块的加载和卸载10.1嵌入式Linux驱动程序开发基础
10.1.110.1嵌入式Linux驱动程序开发基础
10.2嵌入式Linux设备驱动重要技术10.2.1内存与I/O端口(1)内核空间和用户空间(2)内核中内存分配内核中获取内存的几种方式如下。①通过伙伴算法分配大片物理内存②通过slab缓冲区分配小片物理内存③非连续内存区分配④高端内存映射⑤固定线性地址映射10.1嵌入式Linux驱动程序开发基础
10.2嵌(3)I/O端口根据CPU体系结构的不同,CPU对IO端口的编址方式有两种:I/O映射方式(I/O-mapped)和内存映射方式(Memory-mapped)。
下面主要讨论一下内存映射方式访问I/O端口的方法,我们称之为I/O内存操作。I/O内存区必须在使用前分配I/O内存映射访问I/O内存映射到用户空间10.1嵌入式Linux驱动程序开发基础
(3)I/O端口10.1嵌入式Linux驱动程序开发基10.2.2同步机制Linux内核中包含的同步机制包括:原子操作、信号量(semaphore)、读写信号量(rw_semaphore)、自旋锁(spinlock)、大内核锁(BigKernelLock,BKL)、读写锁(rwlock)、读拷贝更新(Read-CopyUpdate,RCU)和seqlock(顺序锁)等。10.2.2同步机制1.原子操作原子操作主要用于实现资源计数,很多引用计数(refcnt)就是通过原子操作实现的。原子类型定义如下:typedefstruct{volatileintcounter;}atomic_t;原子操作通常用于实现资源的引用计数2.信号量信号量在创建时需要设置一个初始值.
3.读写信号量读写信号量有两种实现:一种是通用的,不依赖于硬件架构一种是架构相关的1.原子操作读写信号量的相关API有:DECLARE_RWSEM(name)该宏声明一个读写信号量name并对其进行初始化。voidinit_rwsem(structrw_semaphore*sem);该函数对读写信号量sem进行初始化。voiddown_read(structrw_semaphore*sem);在Linux中,每一个进程都用一个类型为task_t或structtask_struct的结构来描述读写信号量的相关API有:4.自旋锁一个执行单元要想访问被自旋锁保护的共享资源,必须先得到锁,在访问完共享资源后,必须释放锁。自旋锁的API有:spin_lock_init(x);4.自旋锁10.2.3阻塞与非阻塞1.阻塞操作2.非阻塞操作10.2.4时间问题1.延时操作:(1)长延时。(2)短延时2.内核定时器内核提供给驱动许多函数来声明、注册、以及去除内核定时器。
3.工作队列采用缺省工作者线程来实现工作队列的API:①INIT_WORK(_work,_func,_data)10.2.3阻塞与非阻塞②intschedule_work(structwork_struct*work)③intschedule_delayed_work(structwork_struct*work,unsignedlongdelay)④voidflush_scheduled_work(void)⑤intcancel_delayed_work(structwork_struct*work)
创建自己的工作者线程和工作队列,API:①structworkqueue_struct*create_workqueue(constchar*name)②intqueue_work(structworkqueue_struct*wq,structwork_struct*work)③intqueue_delayed_work(structworkqueue_struct*wq,structwork_struct*work,unsignedlongdelay)④voidflush_workqueue(structworkqueue_struct*wq)⑤voiddestroy_workqueue(structworkqueue_struct*wq)②intschedule_work(structwor10.2.5中断处理在Linux系统里,对中断的处理是属于系统核心部分,因而如果设别与系统之间以中断方式进行数据交换,就必须把该设备的驱动程序作为系统核心的一部分。设备驱动程序通过调用request_irq函数来申请中断,通过free_irq来释放中断。它们被定义为:#include<linux/sched.h>intrequest_irq(unsignedintirq,void(*handler)(intirq,voiddev_id,structpt_regs*regs),unsignedlongflags,constchar*device,void*dev_id);voidfree_irq(unsignedintirq,void*dev_id);10.2.5中断处理函数的参数如下。unsignedintirq:请求的中断号。irqreturn_t(*handler):安装的中断处理函数指针。unsignedlongflags:中断处理的属性。
constchar*dev_name:这个传递给request_irq的字串用在/proc/interrupts来显示中断的拥有者。
void*dev_id:用作共享中断的指针。函数的参数如下。10.3字符设备驱动程序字符设备驱动程序可以分为三个主要组成部分:1,自动配置和初始化子程序,负责检测所要驱动的硬件设备是否存在和是否能正常工作。2,服务于I/O请求的子程序,又称为驱动程序的上半部分。3,中断服务子程序,又称为驱动程序的下半部分。10.3.1字符设备驱动结构1.主次设备号:字符设备和块设备通过文件系统中的名子来存取。主编号标识设备相连的驱动。次编号被内核用来决定引用哪个设备。设备编号在驱动程序的内部具有固定的表示方式。在建立驱动时,需要做的第一件事是获取一个或多个设备编号来使用。在驱动程序执行的过程中,如果不希望在使用该设备,要及时的将设备编号释放:10.3字符设备驱动程序2.驱动相关数据结构大部分的基础性的驱动操作包括3个重要的内核数据结构,它们是file_operations,file,和inode。(1)文件操作(file_operations) file_operation结构表示了用户程序怎样对设备进行操作。这个结构,定义在<linux/fs.h>中,是一个函数指针的集合structmodule*owner。(2)文件结构 structfile定义于</linux/fs.h>,是设备驱动中第二个最重要的数据结构。(3)inode结构 inode结构由内核在内部用来表示文件。2.驱动相关数据结构3.自动配置和初始化(1)初始化。当驱动程序将被加载的时候,首先会调用初始函数进行自动配置。(2)清除处理。4.中断处理如果需要驱动程序具有中断处理的能力,必须进行中断申请。从request_irq返回给请求函数的返回值是0指示成功,为负表示错误码。中断处理可以在驱动初始化时安装或者在设备第一次打开时。在中断的使用过程中还可以对其进行使能和禁止操作3.自动配置和初始化10.3.2字符设备驱动实例——LED驱动1.LED驱动程序分析本驱动程序文件名为led2440.c2.驱动模块加入内核使用命令:cp-fled2440.c/linux-2.6.32.4/drivers/char/编辑Kconfig文件:修改Makefile文件:配置、编译内核执行makezImage内核映像和驱动程序模块会先后被编译完毕。将内核下载至开发板;将驱动程序模块加入到根文件系统后,下载至开发板。这样就可以调用驱动程序进行演示了。10.3.2字符设备驱动实例——LED驱动3.LED驱动演示(1)驱动程序模块加载到内核。进入驱动程序模块所在目录,执行:insmod-fled2440.ko(2)建立设备节点。也就是建立用户程序关联到驱动程序的途径(3)演示程序。建立一个LED控制的简单演示程序led2440test3.LED驱动演示10.4网络设备驱动程序10.4.1Linux网络设备简介1.Linux网络驱动基础2.DM9000控制器10.4.2网络驱动核心数据结构分成几个方面对其进行介绍通用信息硬件描述信息协议相关信息设备操作函数接口10.4网络设备驱动程序10.4.3网络驱动程序分析1.初始化、清理网络设备
网络设备初始化的工作主要是确定硬件设备的存在,以及将硬件设备加载到设备链表中,为网络设备的激活做准备。需要注意这两个变量:name和owner。2.打开和关闭网络设备open函数主要用来完成对网络设备中断进行注册、通过配置物理接口初始化设备,以及为发送数据准备队列。10.4.3网络驱动程序分析3.中断处理
网络驱动程序的中断处理函数在网络设备激活时进行注册,主要用于完成:现场保护及中断屏蔽、读取网络设备寄存器信息及判断中断原因并处理、恢复中断现场。函数首先需要获得自旋锁,然后将当前的寄存器地址保存下来,以便返回的时候继续进行被打断的作业;接着就是屏蔽所有的中断,读取中断状态寄存器并清除中断状态寄存器,然后就开始真正的中断处理了。当发生接收中断时,中断函数调用dm9000_rx()函数。
4.sk_buff结构sk_buff的数据成员分为两部分:一部分是实际在网络中要传输的部分,数据区(Packetdatestorage);一部分由内核管理服务于结构链表。
3.中断处理还有一些常用的成员如:sk_buff->tstamp:sk_buff->dev:sk_buff->protocol:
内核提供了一系列用于操作sk_buff数据结构的函数,用于分配、释放、复制、克隆、扩展等功能,下面介绍些常用的。structsk_buff*alloc_skb(unsignedintlen,intpriority)structsk_buff*dev_alloc_skb(unsignedintlen)还有一些常用的成员如:
5.数据发送处理
6.数据接收处理
数据接收的主要工作有:检查接收的到的数据包是否正确;根据数据被长度在内核空间为数据包申请sk_buff;把数据包复制到sk_buf
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年广西货运从业资格证试题库和答案
- 2025年呼和浩特货运从业资格证的试题
- 2025年漯河货车资格证考试题
- 办公室健康活动的策划与实施方法论
- 2025年济宁货运资格证模拟考试卷
- 《积的近似值》第1课时(教学实录)-2024-2025学年五年级上册数学西师大版
- 互动课堂在提高教育质量中的作用
- 北师大版三年级下册数学一课一练5.3长方形的面积带答案
- 2023年高考历史试卷(广东)含答案解析
- 教科版科学一年级上册第一单元《植物》测试卷加答案解析
- GB/T 43232-2023紧固件轴向应力超声测量方法
- 低压配电室的安全操作规程
- 新目标汉语口语课本2课件-第2单元
- 二手车买卖合同(标准版范本)
- 国有企业合规制度培训
- 血液透析的医疗质量管理与持续改进
- 铬安全周知卡、职业危害告知卡、理化特性表
- 部编小语必读整本书《西游记》主要情节赏析
- 工程保修方案和措施三篇
- 抖音快手短视频创业项目融资商业计划书模板(完整版)
- 新探索研究生英语(基础级)读写教程参考答案Language-focus
评论
0/150
提交评论