活动地址:CSDN21天学习挑战赛
本周: 2022-08-01——2202-08-07
计划: 完成 Linux设备树和Pinctrl 的学习
个人的状况:本人现已经大学毕业(2022届毕业生),有过3个多月的实习经历,实习期间主要做的事android 的BSP移植,目前主要工作是做驱动的移植,所以对本节学习的内容是有一定的基础的。
Linux设备树和Pinctrl
本专题的学习:CSDN21天学习挑战赛
1、Linux设备树和Pinctrl
一、Linux设备树
1.1 Linux设备树概述
1、设备树是什么
2、引入设备树的作用
3、什么样的硬件可以用设备树来描述
4、原始硬件信息(没采用设备树的时候)
设备树我把把它理解为对硬件的描述
简化了代码块量
采用了设备树之后,许多硬件的细节可以直接通过它传递给Linux,
而不再需要在内核中进行大量的冗余编码,它通过bootloader将硬件资源传给内核,
使得内核和硬件资源描述相对独立
CPU的数量和类别
内存基地址和大小
总线和桥
外设连接
中断控制器和中断使用情况
GPIO控制器和GPIO使用情况
Clock控制器和Clock使用情况
补充:
设备树对于可热插拔的热备不进行具体描述,它只描述用于控制该热插拔设备的控制器
注:
官网对设备树的描述:
https://www.kernel.org/doc/Documentation/devicetree/usage-model.txt
1.2 设备树
设备树的主要优势:
对于同一SOC的不同主板,只需更换设备树文件.dtb或者.dtbo文件即可实现不同主板的无差异支持,而无需更换内核文件,实现了内核和不同板级硬件数据的拆分。
设备树:
DTC (device tree compiler)
DTS/DTSI (device tree source)
DTB (device tree blob)
三者的关系:
dts和dtsi源文件会经过dtc编译器编译成dtb二进制文件,dtb文件最后会被放到系统中被内核解析
例如:
1 、dts/dtsi
DTS: .dts文件是设备树的源文件。
文件.dts是一种ASCII文本格式的设备树描述 ,
一个.dts文件对应一个ARM的设备,
一般放置在内核的arch/arm/boot/dts/目录中
DTSI:
由于一个SoC可能对应多个设备(一个SoC可以对应多个产品和电路板),
这些.dts文件势必须包含许多共同的部分,Linux内核为了简化,
把SoC公用的部分或者多个设备共同的部分一般提炼为.dtsi
,
类似于C语言的头文件。其他的设备对应的.dts就包括这个.dtsi
2、dtc
不深入了解的话,就是一个编译器
3、dtb
.dtb文件是 .dts 被 DTC 编译后的二进制格式的设备树文件,它由Linux内核解析
,也可以被bootloader进行解析
。通常在我们为电路板制作NAND、SD启动映像时,会为.dtb文件单独留
下一个很小的区域
以存放之,之后bootloader在引导内核的过程中
,会先读取该.dtb到内存。
1.3 设备树语法
1、框架
设备树用树状结构描述设备信息,它有以下几种特性:
- 每个设备树文件都有一个根节点,每个设备都是一个节点。
- 节点间可以嵌套,形成父子关系,这样就可以方便的描述设备间的关系。
- 每个设备的属性都用一组key-value对(键值对)来描述。
- 每个属性的描述用‘ ; ’结束
DeviceTree的结构非常简单,由两种元素组成:
Node(节点)
Property(属性)
[label:] node-name[@unit-address] {
[properties definitions]
[child nodes]
}
2、设备节点
在设备树中节点命名格式如下:
node-name@unit-address
node-name: 是设备节点的名称,为ASCII字符串,节点名字应该能够清晰的描述出节点的功能
unit-address: 一般表示设备的地址或寄存器首地址,如果某个节点没有地址或者寄存器的话 “unit-address” 可以不要
3. 设备节点的标准属性
compatible 属性
compatible 属性也叫做 “兼容性” 属性,这是非常重要的一个属性!
compatible 属性的值是一个字符串列表, compatible 属性用于将设备和驱动绑定起来。字符串列表用于选择设备所要使用的驱动程序。
compatible 属性值的推荐格式: “manufacturer , model ”
① manufacturer : 表示厂商;② model : 一般是模块对应的驱动名字。
Status 属性
address-cells、#size-cells和reg (寻址属性)
reg 属性的值一般是 (address, length)
对,reg 属性一般用于描述设备地址空间资源信息,一般都是某个外设的寄存器地址范围信息。
#address-cells 和 #size-cells的值都是无符号 32 位整型
,可以用在任何拥有子节点的设备中,用于描述子节点的地址信息。
#address-cells 属性值决定了子节点 reg 属性中地址
信息所占用的字长(32 位), #size-cells 属性值决定了子节点 reg 属性中长度
信息所占的字长(32 位)。
#address-cells 和 #size-cells 表明了子节点应该如何编写 reg 属性值,一般 reg 属性都是和地址有关的内容,和地址相关的信息有两种:起始地址和地址长度
ranges 属性(地址翻译)
ranges属性值可以为空或者按照 (child-bus-address,parent-bus-address,length) 格式编写的数字矩阵, ranges 是一个地址映射/转换表, ranges 属性每个项目由子地址、父地址和地址空间长度
这三部分组成:
- child-bus-address: 子总线地址空间的物理地址,由父节点的 #address-cells 确定此物理地址所占用的字长。
- parent-bus-address: 父总线地址空间的物理地址,同样由父节点的 #address-cells
确定此物理地址所占用的字长。 - length: 子地址空间的长度,由父节点的 #size-cells 确定此地址长度所占用的字长。
别名节点和 根节点
每个设备树文件只有一个根节点
,其他所有的设备节点都是它的子节点,它的路径是 /。根节点有以下属性:
4、设备和驱动的匹配方式
当设置driver_override时,只绑定匹配的驱动
OF 匹配
ACPI 匹配
id 表匹配
驱动名字匹配
匹配成功之后进入 probe 函数
5、imx415 sensor为实例
&i2c1 { //i2c设备
status = "okay";
clock-frequency = <400000>; //时钟频率
imx415: imx415@1a {
compatible = "sony,imx415"; //需要与驱动中的匹配字符串一致
reg = <0x1a>;//寄存器地址,具体可以根据硬件和datasheet(imx415手册)的决定
clocks = <&cru CLK_MIPICSI_OUT>;//sensor clickin配置
clock-names = "xvclk";
power-domains = <&power RV1126_PD_VI>;
pinctrl-names = "rockchip,camera_default";
pinctrl-0 = <&mipicsi_clk0>;//pinctl设置
avdd-supply = <&vcc3v3_sys>;
dovdd-supply = <&vcc_1v8>;
dvdd-supply = <&vcc_dvdd>;//供电引脚
//pwd-gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio1 RK_PD5 GPIO_ACTIVE_LOW>; //复位引脚
rockchip,camera-module-index = <1>; 模组编号,该编号不要重复
rockchip,camera-module-facing = "front";// 模组朝向,有"back"和"front"
rockchip,camera-module-name = "YT10092";// 模组名
rockchip,camera-module-lens-name = "IR0147-60IRC-8M-F20";//"IR0147-36IRC-8M-F20";//lens名
//sensor的效果文件
ir-cut = <&cam_ircut0>;//ir cut设备
port {
ucam_out0: endpoint {
remote-endpoint = <&mipi_in_ucam0>; mipi dphy端的port名
data-lanes = <1 2 3 4>; mipi lane数,1lane为 <1>, 4lane为 <1 2 3 4>
};
};
};
};