华清远见Linux设备驱动(每章小结)
1、 linux设备驱动是以内核模块的方式而存在的,在具体的驱动开发中将驱动编译为模块具有很到的工程意义。因为如果将正在开发中的驱动编译如内核,而开发过程中会不断修改驱动代码,则需要不断的编译和重启Linux,但是如果直接编译为模块则只需要rmmod与insmod即可,开发效率大大提高。
2、 linux系统的用户空间编程有两种方法,即通过linux API和通过C库函数访问文件。用户空间看不到设备驱动,能看到的只有设备对应的文件,因此文件编程即是用户空间的设备编程。
Linux按照功能对文件系统的目录进行了良好的规划。/dev是设备文件存放的目录,devfs和udev分别是linux2.4和linux2.6设备生成的设备文件节点方法,前者运行于内核空间后者运行于用户空间。
linux2.6设备通过一些列的数据结构定义了设备模型,设备模型与sysfs文件系统中的目录和文件存在一种对应关系,udev可以利用sysfs中记录的信息定义规则并提取主次设备号动态创建/dev文件设备。
3、 字符设备是三大设备(字符设备、块设备、网络设备)中较简单的一类设备,器驱动程序中完成的主要功能是初始化、添加和删除dev结构体,申请和释放设备号,以及填充file_operations结构体中的操作函数,实现file_operations结构体中的read()、write()和ioctl()等函数是驱动设计的主体工作。
4、 并发态和竞态广泛存在,中断屏蔽、原子操作、自旋锁和信号量都是解决并发问题的机制。中断屏蔽很少被单独使用,院子操作只针对整型进行,因此自旋锁和信号量应用最为广泛。
自旋锁会导致死循环,锁定期间不允许阻塞,因此要求锁定的临界区小。信号量允许临界区阻塞,可以适用于临界区大的情况。
读写自旋锁和读写信号量分别是放宽了条件的自旋锁和信号量,它允许多个执行单元对共享资源并读开发。
5、 阻塞与非阻塞访问时I/O操作的两种不同的模式,前者在I/O操作不可进行时会让进程睡眠。
在设备驱动中阻塞I/O一般基于等待队列来实现,等待队列可用于同步驱动中事件发生的先后顺序。使用非阻塞I/O也可以借助轮询函数来查询设备是否立即被访问,用户空间调用select()函数和poll()接口,设备驱动提供poll()函数。设备驱动的poll()函数本身不会阻塞,但是poll()和select()系统调用则会阻塞的等待文件描述符至少一个可访问或超时。
6、 使用信号量可以实现设备驱动与用户程序之间的异步通知,总体而言,设备驱动和用户空间要分别完成以下工作:用户空间设置文件的拥有者、FASYNC标志及捕获信号,内核空间响应对文件对文件的拥有者、FASYNC标志的设置,并在资源可获得是释放信号。
linux2.6内核包含对AIO的支持为用户空间提供统一的异步I/O接口。在AIO中,信号和回调函数是实现内核空间对用户空间应用程序通知的两种机制。
7、 硬中断是是外部设备对CPU的中断、软中断通常是硬中断服务程序对内核的中断,而信号则是有内核(或其他进程)对某个进程的中断。
linux内核中断处理分为两个半部,顶半部处理紧急硬件操作,底半部处理不紧急的耗时操作。Tasklet和工作队列都是调度底半部的良好机制,tasklet基于软中断实现。内核定时器也依靠软中断实现。
内核中的延时是忙等待或者睡眠等待,为了充分利用CPU资源,使系统有更好的吞吐性能,在对延时时间的要求并不是很精确的情况下,睡眠等待通常是值得推荐的。
8、 Malloc()的内存一定要被free(),否则会造成内存泄露。理想情况下,malloc()与free()应该成对出现,即谁申请就由谁释放。
外设可处于CPU的内存空间或者I/O空间,除X86外嵌入式处理器一般只存在内存空间。在Linux系统中,为I/O内存和I/O端口的访问提供了一套统一的方法,访问流程一般为“申请资源—>映射—>访问—>去映射—>释放资源”。
对于有MMU的处理器而言,linux系统的内部布局比较复杂,可直接映射的物理内存称为常规内存,超出部分为高端内存。Kmalloc()和__get_free_pages()申请的内存在物理上连续,而vmalloc()申请的内存在物理上不连续。
DMA操作可能导致Cache的不一致问题,因此,对于DMA缓冲,应该用dma_alloc_coherent()等方法申请。在DMA操作中涉及总线地址、物理地址和虚拟地址等概念,区分这3类地址非常重要。Linux内核中对DMA通道的申请和释放采用了和中断类似的方法。
9、 TTY设备驱动的主体工作围绕tty_driver这个结构体的成员函数展开,主要实现其中的数据发送和接收流程以及tty设备线路设置函数。
针对串口,内核实现了内核核心层,这个层实现了串口设备通用的tty_driver。因此,串口设备驱动的主体工作从tty_driver移动到uart_driver。
10、块设备的I/O操作方式与字符设备存在较大不同,因而引入了request_queue、request、bio等一系列数据结构。在整个块设备的I/O操作中,贯穿于始终的是“请求”,字符设备的I/O操作则是直接进行不绕弯,块设备的I/O操作会排队和整合。
驱动的任务是处理请求,对请求的排队和整合由I/O调度算法解决,因此,块设备驱动的核心是请求处理函数或“制造请求”函数。
尽管块设备驱动中仍然存在block_device_operations结构体及其成员函数,但其不在包含读写一类的成员函数,而只是包含打开、释放及I/O控制等与具体读写无关的函数。
块设备驱动的结构相当复杂,但幸运的是,块设备不像字符设备那样包罗万象,它通常就是存储设备,而且驱动的主体已经由Linux内核提供,针对一个特定的硬件系统,驱动工程师所涉及的工作往往只是编写少量的与硬件直接交互的代码。
11、linux I2C驱动体系结构相当复杂,它主要分为3个部分组成,即I2C核心、I2C总线驱动和I2C设备驱动。I2C核心是2C总线驱动和I2C设备驱动的中间枢纽,它以通用的、与平台无关的接口实现了I2C设备与适配器的沟通。I2C总线驱动填充i2c_adapter和i2c_algorithm结构体,I2C设备驱动填充i2c_driver和i2c_client结构体。
另外,系统中的i2c-dev.c文件定义的主设备号为89的设备可以方便的给用程序提供读写I2C设备寄存器的能力,使得工程师大多时候不需要为具体的I2C设备驱动定义文件操作接口。
工程师在计I2C设备驱动程序的时候,并不一定要遵守linux I2C驱动体系结构,完全可以把它当做一个普通的字符设备来处理。
12、在音频设备驱动中,几乎必须使用DMA,而DMA缓冲区会被分成一个一个的段,每次DMA操作进行期中的一段。
13、帧缓冲设备是一种典型的字符设备,它统一了显存,将显示缓冲区直接映射到用户空间。帧缓冲设备驱动file_operations中VFS接口函数由fbmem.c文件统一实现。这样,驱动工程师的工作重点将是实现针对特定设备fb_info中的fb_ops的成员函数,另外,理解并灵活的修改fb_info中的var和fix参数非常关键。fb_info中的var参数直接和LCD控制器的硬件设置以及LCD屏幕对应。
华清远见Linux设备驱动(每章小结)的更多相关文章
- 热烈庆祝华清远见2014嵌入式系统(Linux&Android)开发就业培训课程全面升级
近日,华清远见公开宣布:2014嵌入式系统 (Linux&Android)开发就业培训课程再次升级!据悉,华清远见如今已经持续10年,一直保持课程每年2次的更新的频率.华清远见的每 次课程更新 ...
- 宋宝华:Linux设备驱动框架里的设计模式之——模板方法(Template Method)
本文系转载,著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 作者: 宋宝华 来源: 微信公众号linux阅码场(id: linuxdev) 前言 <设计模式>这本经典 ...
- linux 设备驱动概述
linux 设备驱动概述 目前,Linux软件工程师大致可分为两个层次: (1)Linux应用软件工程师(Application Software Engineer): 主要利用C库函数和 ...
- Linux设备驱动中的软件架构思想
目录 更新记录 一.Linux驱动的软件架构 1.1 出发点 1.2 分离思想 1.3 分层思想 二.platform设备驱动 2.1 platform设备 2.2 platform驱动 2.3 pl ...
- linux设备驱动归纳总结(七):1.时间管理与内核延时【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-100005.html linux设备驱动归纳总结(七):1.时间管理与内核延时 xxxxxxxxxxx ...
- linux设备驱动归纳总结(五):4.写个简单的LED驱动【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-84693.html linux设备驱动归纳总结(五):4.写个简单的LED驱动 xxxxxxxxxxx ...
- linux设备驱动归纳总结(五):1.在内核空间分配内存【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-79134.html linux设备驱动归纳总结(五):1.在内核空间分配内存 xxxxxxxxxxxx ...
- linux设备驱动归纳总结(三):7.异步通知fasync【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-62725.html linux设备驱动归纳总结(三):7.异步通知fasync xxxxxxxxxxx ...
- Linux 设备驱动 Edition 3
原文网址:http://oss.org.cn/kernel-book/ldd3/index.html Linux 设备驱动 Edition 3 By Jonathan Corbet, Alessand ...
随机推荐
- 通过css属性hack完成select样式美化,并兼容IE
最近在重构时遇到了select样式问题,并且需要在不影响语义化的情况下,兼容IE8. 经过一番的百度后始终没有找到合适的纯CSS解决方案,最后换了一下思路,大胆使用了属性hack: 在chrome和F ...
- Spring-Session实现Session共享入门教程
任何一种技术的出现,都是来解决特定的问题的! 本篇开始学习Spring-Session相关的一些知识学习整理,让我们开始吧! Spring-Session介绍 Spring-Session使用的场景? ...
- Swift map filter reduce 使用指南
转载:https://useyourloaf.com/blog/swift-guide-to-map-filter-reduce/ Using map, filter or reduce to ope ...
- Android-序列化-Serializable/Parcelable
Android-序列化-Serializable/Parcelable 学习自 <Android开发艺术探索> 序列化漫谈 IPC的首要目的是传输数据,当然不能仅仅是传输一些基础数据了,毕 ...
- 洛谷P1220关路灯[区间DP 提前计算代价]
题目描述 某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少).老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯. 为了给村 ...
- BZOJ3772精神污染
参见http://blog.csdn.net/popoqqq/article/details/43122821 #include<bits/stdc++.h> using namespac ...
- poj 2253 最短路floyd **
题意:有两只青蛙和若干块石头,现在已知这些东西的坐标,两只青蛙A坐标和青蛙B坐标是第一个和第二个坐标,现在A青蛙想要到B青蛙那里去,并且A青蛙可以借助任意石头的跳跃,而从A到B有若干通路,问从A到B的 ...
- CentOS 7下的KVM网卡配置为千兆网卡
在KVM下可以生成两种型号的网卡,RTL8139和E1000,其实应该是底层生成不同芯片的网卡,而不是附带宿主机网卡是什么型号就是什么型号的,其中默认为100兆网卡,即RTL8319的螃蟹卡,另一种是 ...
- centos上安装elasticsearch 5.5.1 遇到的各种坑
mac玩得好好滴,一次性启动成功,结果在centos上安装时,遇坑无数,记录一下: 一.只能localhost访问的问题修改 conf\elasticsearch.yml network.host: ...
- ARM DEBUGGER FOR NEARLY ONE DOLLAR
http://hackaday.com/2014/01/23/arm-debugger-for-nearly-one-dollar/ Oh that title is so misleading. B ...