华清远见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 ...
随机推荐
- 在 Intellij IDEA 中部署 Java 应用到 阿里云 ECS
你有没有怀疑过人生 多的去了 在开发过程中,发布部署项目是一件令人头疼的事 拿springboot项目来说吧(springboot算是已经极大简化了部署了) 步骤 运行clean install 将打 ...
- PHP 从基础开始 ——重要知识点笔记
PHP static 关键词 通常,当函数完成/执行后,会删除所有变量.不过,有时我需要不删除某个局部变量.实现这一点需要更进一步的工作. 要完成这一点,请在您首次声明变量时使用 static 关键词 ...
- Linux下实现自动设置SSH代理
SSH的巨大价值体现在能够配置为代理服务器上.不像在Windows下每次还需要手动登录设置,Linux有很好的工具链能够实现自动设置SSH代理,就是expect和ssh的联合使用,再加上proxych ...
- zoj 3644 记忆化搜索
题目:给出一个有向图,从1到n,每个结点有个权值,每走一步,分值为结点权值的LCM,而且每一步的LCM都要有变化,问到达N的时候分值恰好为K的路径有多少条 记忆化搜索,虽然做过很多了,但是一直比较慢, ...
- KVM源代码阅读--内核版本3.17.4
为了更加深入的学习虚拟化,因此我必须把KVM源代码搞清楚,这是一个必须要挖的坑.我会把自己的一些阅读的代码贴上来,可能会有理解不对的地方,希望和大家一起交流,请多提意见,以便于纠正错误.所用的内核版本 ...
- Spring boot整合jsp
这几天在集中学习Spring boot+Shiro框架,因为之前view层用jsp比较多,所以想在spring boot中配置jsp,但是spring boot官方不推荐使用jsp,因为jsp相对于一 ...
- Linux下查看哪些IP登陆过系统/var/log/wtmp
last -f /var/log/wtmp
- CentOS 7使用通过二进制包安装MySQL 5.7.18
安装依赖 yum install -y libaio 下载 wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.18-linux- ...
- Redis主从同步分析(转)
一.Redis主从同步原理 1.1 Redis主从同步的过程 配置好slave服务器连接的master后,slave会建立和master的连接,然后发送sync命令.无论是第一次同步建立的连接还是连接 ...
- ASP.NET Web API中通过ETag实现缓存
通常情况下Server是无状态的,在ASP.NET Web API中,我们可以让服务端响应体中产生ETag属性,起到缓存的作用.大致实现原理是: 1.服务端的响应体中返回一个ETag属性2.客户端通过 ...