火龙果软件LINUX设备驱动开发1汇编_第1页
火龙果软件LINUX设备驱动开发1汇编_第2页
火龙果软件LINUX设备驱动开发1汇编_第3页
火龙果软件LINUX设备驱动开发1汇编_第4页
火龙果软件LINUX设备驱动开发1汇编_第5页
已阅读5页,还剩30页未读 继续免费阅读

下载本文档

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

文档简介

1、嵌入式嵌入式Linux系统高级开发讲义系统高级开发讲义 第一天课程l 模块模块 Linux设备驱动程序简介设备驱动程序简介 l Linux字符设备驱动开发字符设备驱动开发 l 并发与竞争并发与竞争 l Linux内核调试技术内核调试技术 日程安排l设备驱动简介设备驱动简介l驱动是什么Driver is a software layer that lies between the applications and the actual devicel驱动程序的角色提供机制, 而不是策略l隐藏在UNIX中的哲学mechanism: What capabilities are provided.po

2、licy: How these capabilities can be used. Kernel的作用lKernel可划分为下列功能单元进程管理: 进程调度, 资源分配, 进程间通信.内存管理: 其实也算是资源分配的一部分文件系统: 管理, 组织物理媒介上数据的方法设备控制: 设备驱动(ldd3所关注的)网络: 实质上是进程间通信. 但它不局限于一个特定的进程. 它关注收/发packets, 路由, 地址解析.Kernel的结构模块l可加载模块(lodable modules)module: 可实时加载到内核中的代码, 它可动态连接到内核(insmod, rmmod)设备驱动就是module的

3、代表, 但module还包括文件系统等等.设备和模块的分类 l模块分为这些类型,每种类型的模块驱动对应类型的设备character module, block module, network interfaceother module 字符设备和块设备l 字符设备: 以字节流的形式被访问的设备。e.g: /dev/console : 文本控制台. /dev/ttyS0 : 串口l 它通过文件系统节点被访问. e.g: /dev/tty1, /dev/lp0l 字符设备与一般文件(regular file)的区别 可以在一般文件中前后移动(lseek), 但只能顺序访问字符设备. 当然, 也有特

4、例: frame grabbers.l 块设备: 能支持文件系统的设备 传统的UNIX: 只能以block(512B)为单位访问块设备 Linux: 能以访问字符设备的方式访问块设备, 即以字节文单位访问块设备.l Linux中字符设备与块设备的区别 内核内部对数据的组织和管理不同, 对驱动开发者来说透明 接口不同: 使用两套不同的interface网络设备l 网络接口: 能与其他主机通信的设备它可以是硬件设备, 也可以是软件设备, 比如lo. (参考TCP/IP详解p26)网络接口只管收发数据包, 而不管这些数据包被什么协议所使用不同于字符设备和块设备, 网络接口没有对应的文件系统节点. 虽

5、然可以通过类似eth0这样的文件名来访问网络接口, 但文件系统节点中却没有针对网络接口的节点内核与网络接口之间的通信也不同于内核与字符/块设备之间的通信(read, write), 它们之间使用特定的传输数据包的函数调用其他设备l也有一些module不能严格地划分类型. USB module: 它工作在内核的USB子系统之上实际的USB设备可以是字符设备, 块设备, 也可以是网络接口l在设备驱动之外, 别的功能, 不论硬件和软件, 在内核中都是模块化的 例如文件系统内核模块VS应用程序 l执行机制不同模块初始化模块退出类似事件编程l使用库不一样无法使用标准库只能调用内核提供的函数用户空间VS内

6、核空间 l 用户空间VS内核空间应用程序运行在用户空间设备模块运行在内核空间运行模式不一样内存地址映射也不一样l 用户空间和内核空间的转换可能发生在进程中的系统调用时或者硬件中断系统调用虽然在内核中执行,但是依然是在进程的上下文中进行的,所以可以访问到进程中的数据。中断处理和进程是异步的了,而且不和任何进程有关系l 模块跨越两个空间,有两个触发入口 一些函数作为系统调用的一部分执行 一些函数负责中断处理 内核模块的编译Linux 2.4内核与2.6内核版本的模块编译方式不一致。Linux2.4的模块为.o文件 Linux2.6的模块为.ko文件 模块的加载卸载和查看l加载使用insmodl卸载

7、使用rmmodl查看使用lsmod模块代码lstatic int _init initialization_function(void)ll /*initialization code here*/llmodule_init(initialization_function);模块代码lstatic void _exit cleanup_function(void)ll /* Cleanup code here*/llmodule_exit(cleanup_function);日程安排llinux字符设备驱动开发主次设备号l字符设备可以通过文件系统来存取字符设备一般位于/dev下有c标志的是字符

8、设备有b标志的是块设备l设备号文档Documentation/devices.txt l主设备号决定驱动的种类l次设备号决定使用哪个设备设备编号的内部表达ldev_t 类型(在 中定义)用来持有设备编号 - 主次部分都包括获得一个 dev_t 的主或者次编号, 使用lMAJOR(dev_t dev); lMINOR(dev_t dev); 转换为一个 dev_t, 使用:lMKDEV(int major, int minor); 分配和释放设备编号分配和释放设备编号l分配指定的主设备号int register_chrdev_region(dev_t first, unsigned int co

9、unt, char *name);l动态分配主设备号int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name); l释放 void unregister_chrdev_region(dev_t first, unsigned int count); 字符驱动中重要的数据结构l file_operations结构结构lstruct file_operations l struct module *owner;l loff_t (*llseek) (struct file

10、*, loff_t, int);l ssize_t (*read) (struct file *, char *, size_t, loff_t *);l ssize_t (*write) (struct file *, const char *, size_t, loff_t *);l int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);l int (*mmap) (struct file *, struct vm_area_struct *);l int (*open) (struct inod

11、e *, struct file *);l int (*release) (struct inode *, struct file *);l l;字符设备的注册l 在Linux 2.6下使用“struct cdev”记录字符设备的信息。结构定义如下:struct cdev struct module *owner; struct file_operations *ops; dev_t dev; ;l void cdev_init(struct cdev *, struct file_operations *);l struct cdev *cdev_alloc(void);l int cdev

12、_add(struct cdev *, dev_t, unsigned)l void cdev_del(struct cdev *);Open方法l检查设备的特定错误l如果设备是首次打开,则对其进行初始化l如有必要,更新f_op指针l分配且填写filp-private_data里的数据结构Release方法l释放由open分配的, 保存在filp-private中的所有内容l在最后一次关闭操作时关闭设备日程安排l调试技术通过打印调试l通过宏可以定义日志级别参考P79l如果开启Klogd及Syslogd则输出到日志日志文件参考/var/log/messagel在printk当中打印设备编号Pri

13、nt_dev_tFormat_dev_t日程安排l并发和竞争并发和管理并发和管理l并发源很多多个进程运行SMP多个CPU并行设备中断延迟机制(工作队列,定时器,Tasklet)并发和竞争l两个或多个进程读写某些共享数据,而最后的结果取决于进程运行的精确时序,就称为竞争条件竞争条件(Race Conditions)。 竞争情况来自对资源的共享存取的结果.l存取管理的常用技术是加锁或者互斥l其次常用的技术是引用计数临界区l 把对共享内存进行访问的程序片段称作临界区临界区(critical region),或临界段临界段(critical section)。如果我们能够适当地安排使得两个进程不可能同

14、时处于临界区,则就能够避免竞争条件。l 临界区四要素任何两个进程不能同时处于临界区临界区外的进程不能阻塞其他进程不能使进程在临界区外无限等待不应对CPU的速度和数目做假设 PV操作解决同步互斥l PV原语的含义原语的含义P操作和V操作是不可中断的程序段,称为原语。PV原语及信号量的概念都是由荷兰科学家E.W.Dijkstra提出的。信号量sem是一整数,sem大于等于零时代表可供并发进程使用的资源实体数,但sem小于零时则表示正在等待使用临界区的进程数。P原语操作的动作是:(1)sem减1;(2)若sem减1后仍大于或等于零,则进程继续执行;(3)若sem减1后小于零,则该进程被阻塞后进入与该

15、信号相对应的队列中,然后转进程调度。V原语操作的动作是:(1)sem加1;(2)若相加结果大于零,则进程继续执行;(3)若相加结果小于或等于零,则从该信号的等待队列中唤醒一等待进程,然后再返回原进程继续执行或转进程调度。PV操作对于每一个进程来说,都只能进行一次,而且必须成对使用。在PV原语执行期间不允许有中断的发生。解决互斥l用用PV原语实现进程的互斥原语实现进程的互斥由于用于互斥的信号量sem与所有的并发进程有关,所以称之为公有信号量。公有信号量的值反映了公有资源的数量。只要把临界区置于P(sem)和V(sem)之间,即可实现进程间的互斥。就象火车中的每节车厢只有一个卫生间,该车厢的所有旅

16、客共享这个公有资源:卫生间,所以旅客间必须互斥进入卫生间,只要把卫生间放在P(sem)和V(sem)之间,就可以到达互斥的效果。解决同步l用用PV原语实现进程的同步原语实现进程的同步与进程互斥不同,进程同步时的信号量只与制约进程及被制约进程有关而不是与整组并发进程有关,所以称该信号量为私有信号量。利用PV原语实现进程同步的方法是:首先判断进程间的关系为同步的,且为各并发进程设置私有信号量,然后为私有信号量赋初值,最后利用PV原语和私有信号量规定各进程的执行顺序。Linux 信号量实现 l void sema_init(struct semaphore *sem, int val); l DECLARE_MUTEX(name);l DECLARE_MUTEX_LOCKED(name

温馨提示

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

评论

0/150

提交评论