- 最无益,只怕一日曝十日寒,贵在有恒。
目录- 2025-01-18
- 1、基础内容
- 2、通用GPIO操作
- 3、硬件操作
- 4、驱动涉及的思想_面向对象_分层_分离
- 1)面向对象
- 2)分层
- 3)分离
- 5、驱动进化之路_总线设备驱动模型
- 6、驱动进化之路_设备树的语法
- 7、驱动进化之路_内核对设备树的处理与使用
2025-01-18
1、基础内容
- 应用、驱动、硬件:
- 应用程序通过标准的接口访问文件,访问到驱动程序,最终到达硬件:
- 应用程序和驱动程序涉及到用户数据和驱动数据的拷贝;
- 驱动程序和硬件涉及到硬件寄存器实际地址和虚拟地址变量的映射;
- 物理地址和虚拟地址映射:
ioremap
; - CPU看到的是MMU映射的虚拟地址,使得启动两次的相同应用程序虽然在内存实际不同地址上但其中变量可以打印相同的虚拟地址,其他硬件也类似;
- 物理地址和虚拟地址映射:
- 应用程序通过标准的接口访问文件,访问到驱动程序,最终到达硬件:
- 驱动程序编写步骤:
- 1)提供主设备号;
- 2)定义file_operations 结构体,应用的标准接口能够调用起来 =》 驱动程序里也提供对应的接口;
- 3)注册设备驱动;
- 4)提供入口函数,放到
module_init()
宏; - 5)提供出口函数,放到'module_exit()`宏;
- 6)提供 class_create 和 device_create 创建设备节点;
2、通用GPIO操作
- 1)使能GPIO:用到的时候开启时钟、配置使能等;
- 2)通过MUX_MODE将引脚配置为GPIO功能(可能有多功能复用);
- 3)配置输入输出模式:用于输入还是用于输出,Dir;
- 4)设置输出数据或者读取输入数据;
3、硬件操作
- 根据硬件地址操作对应硬件位置的值或者读取——定义指针指向该地址即可;
volatile
(易变的)使用:- 程序中对于同一变量连续两次赋值编译器可能会优化只执行后面的语句,因为最终结果相同;
- 但是对于硬件来说,连续的操作可能是为了作不同的事情,不能这样优化,必须一步一步来——加上
volatile
声明,要求编译器不做优化;
4、驱动涉及的思想_面向对象_分层_分离
- Linux驱动 = 驱动框架 + 硬件操作;
1)面向对象
- 把事件抽象为结构体,如字符设备驱动程序抽象出一个 file_operations 结构体;
2)分层
- 上下分层:将硬件无关操作和硬件相关操作分开为上下两层;
3)分离
- 左右分离:将资源类型文件和硬件通用代码分离为左右两侧;
5、驱动进化之路_总线设备驱动模型
- 驱动编写的3种方法:
- 1)传统写法:
- 2)总线设备驱动模型:
- 左右分离思想的更好扩展实现 ,分别用 platform_device 结构体和 platform_driver 结构体来对应分离的硬件具体引脚等和通用硬件操作代码;
- 然后用总线来管理他们,总线左边一系列 device,总线右边一系列 driver,通过总线将他们两两匹配;
- 对于各种不同设备 device 的定义,可以直接用一个 .c 文件来管理 platform_device,但是会因为各种不同硬件设备出现一堆的 .c 文件;
- 通过 .c 文件定义 dev 与 driver 的匹配:
- 3)使用dts文件来实现 device 的配置,dts 文件可编译为 dtb 文件,传递给内核成为 platform_device 结构体;