| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> 分析Linux下的LED驱动例程 -> 正文阅读 |
|
[系统运维]分析Linux下的LED驱动例程 |
Linux下的驱动与无操作系统的驱动的区别: 没有操作系统的时候,驱动程序直接访问相关寄存器的相应的位即可实现目标需求,当有操作系统的时候,我们则需要在驱动程序里面设计面向操作系统内核的接口,且这样的接口由操作系统规定,对一类设备而言结构一致,独立于具体的设备。可见,当系统中存在操作系统的时候,驱动变成了连接硬件和内核的桥梁,并不会直接服务于顶层应用程序,顶层程序需要通过系统调用访问VFS再间接调用驱动程序访问硬件。 那么问题来了,有了操作系统之后,驱动反而变得更复杂,那还需要操作系统做什么。首先操作系统的存在主要是为了高效实现多并发,还有就是虚拟内存管理机制。那么其对于驱动而言,说白了就是以复杂化底层驱动程序为代价便利顶层程序调用,当驱动程序都按照操作系统给出的独立于设备的接口而设计时,那么应用程序就可以使用统一的系统调用接口来访问各种设备。 接下来以Linux下的一个LED驱动为例看看驱动程序干了些什么,因为Linux的驱动框架庞大而复杂,这里只解释一下代码涉及到的部分,并不展开细谈。
补充: 可以发现在已经有了全局变量struct led_dev *led_devp的情况下,读写函数依旧要通过函数传进来的的inode和file来找到对应的cdev结构体,所以我猜想读写函数等操作函数无法访问到该程序的全局变量 接下来理一下整个驱动程序的逻辑关系(红色代表自定义函数) 加载函数主要实现: 1.申请设备号 - alloc_chrdev_region() 2.为自定义结构体分配动态内存 - kmalloc() 3.对自定义结构体里的cdev进行初始化 - led_setup_cdev() 4.初始化IO - led_gpio_init() cdev初始化函数主要实现: 1.初始化cdev - cdev_init() 2.添加一个字符设备 - cdev_add() 卸载函数主要实现: 1.注销字符设备 - cdev_del() 2.释放内存 - kfree() 3.注销设备号 - unregister_chrdev_region() 然后剩下的就是操作函数,还有变量、结构体的定义,程序中省略的部分就是对寄存器的操作,只要知道寄存器对应的虚拟地址,再进行位操作即可 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/15 23:58:35- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |