设备树

1.不同板子的设备树文件都存放在 arch/arm/boot/dts中。并且将设备树的文件名放入对应的Makefile中,这样设备树才能被编译。

2.".dtsi"是设备树“dts”的头文件,一般用来描述SOC的共有信息,例如CPU、串口、GPIO、IIC,中断等等。板子设备的特有信息一般放在.dts中。

3.追加的信息如果与原有信息冲突,则会替换掉原有信息。

4.Node Names(节点名字)
node-name@unit-address: unit-address一般是外设寄存器的起始地址。(也有可能是i2c设备地址,或其它含义)

5.特殊节点名

点击查看代码
intc: interrupt-controller@00a01000 {      //冒号前是label,冒号后是节点名字。这样就可以通过label去方便地访问节点  如“&intc”。
	compatible = "arm,cortex-a7-gic";
	#interrupt-cells = <3>;
	interrupt-controller;
	reg = <0x00a01000 0x1000>,
	      <0x00a02000 0x100>;
};

6.系统启动以后,会解析设备树。可以在根文件系统里看到设备树的一级子节点信息。cd /proc/device-tree/
a.节点用文件夹表示
c.属性用文件夹表示

7.SOC一级子节点,用来描述芯片内部的外设信息。
8.make dtbs 编译设备树
9.特殊节点 aliases(别名),给外设起别名。可使用 "ls /dev"查看被使用的外设别名

点击查看代码
aliases {			//别名
	can0 = &flexcan1;
	can1 = &flexcan2;
	ethernet0 = &fec1;
	ethernet1 = &fec2;
	gpio0 = &gpio1;
	gpio1 = &gpio2;
	gpio2 = &gpio3;
	gpio3 = &gpio4;
	gpio4 = &gpio5;
	i2c0 = &i2c1;
	i2c1 = &i2c2;
	i2c2 = &i2c3;
	i2c3 = &i2c4;

10. 特殊节点 chosen,主要目的是,启动时将uboot里的bootargs环境变量值,传递给Linux内核,作为param of cmdline。

点击查看代码
chosen {
	stdout-path = &uart1;			//属性
};

11.子节点可以继承父节点属性。子节点的#address-cells 和#size-cells的reg属性,一定由父节点所决定的。例如

点击查看代码
i2c1: i2c@021a0000 {
	#address-cells = <1>;			//无用 由父节点所决定
	#size-cells = <0>;				//无用 由父节点所决定
	compatible = "fsl,imx6ul-i2c", "fsl,imx21-i2c";
	reg = <0x021a0000 0x4000>;		//#address-cells = <1>;  #size-cells = <1>;
	interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;		//GIC_SPI 共享中断
	clocks = <&clks IMX6UL_CLK_I2C1>;
	status = "disabled";
};

12.reg一般用来表示内存段,如果是iic设备,也被用作描述设备地址。

点击查看代码
i2c1: i2c@021a0000 {
	#address-cells = <1>;			//无用 由父节点所决定
	#size-cells = <0>;				//无用 由父节点所决定
	compatible = "fsl,imx6ul-i2c", "fsl,imx21-i2c";
	reg = <0x021a0000 0x4000>;		//#address-cells = <1>;  #size-cells = <1>;
	interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;		//GIC_SPI 共享中断
	clocks = <&clks IMX6UL_CLK_I2C1>;
	status = "disabled";
};

&i2c1 {
	clock-frequency = <100000>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_i2c1>;
	status = "okay";

	mag3110@0e {
		compatible = "fsl,mag3110";
		reg = <0x0e>;
		position = <2>;
	};

	ap3216c@1e {
		compatible = "ap3216c";
		reg = <0x1e>;
	};
};

13.1 imx6ull-pinfunc.h

点击查看代码
#define MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x0090 0x031C 0x0000 0x5 0x0----------<mux_reg conf_reg input_reg mux_mode input_val>
后面五个值对应: mux_reg(寄存器偏移地址):根据其reg属性可知IOMUXC外设寄存器起始地址为0x020e0000。因此0x020e0000+0x0090=0x020e0090,IOMUXC_SW_MUX_CTL_PAD_UART1_RTS_B 寄存器地址正好是 0x020e0090

conf_reg(寄存器偏移地址):和 mux_reg 一样,0x020e0000+0x031c=0x020e031c,这个就是寄存器 IOMUXC_SW_PAD_CTL_PAD_UART1_RTS_B 的地址。input_reg(寄存器偏移地址) 。config_reg 寄存器是在设备树里设置PIN的电气特性的

input_reg(寄存器偏移地址):没有的话就不需要设置

mux_mode(mux_reg寄存器的值):在这里就相当于设置IOMUXC_SW_MUX_CTL_PAD_UART1_RTS_B寄存器为0x5也即是设置 UART1_RTS_B 这个 PIN 复用为 GPIO1_IO19。

input_val(input_reg寄存器值):这里无效

13.2 imx6ull-pinfunc.h

点击查看代码
#define MX6UL_PAD_GPIO1_IO09__GPIO1_IO09                          0x0080 0x030C 0x0000 0x5 0x0

每一个宏定义后面都有5个参数,再加上刚刚我们在&iomuxc节点下配置的pad_ctrl:0x17059一共是6个参数,通过它们就可以完成一个GPIO的配置了,这6个参数分别为:

mux_ctrl_ofs:MUX寄存器偏移地址

pad_ctrl_ofs:PAD寄存器偏移地址

sel_input_ofs:输入选择寄存器偏移地址

mux_mode:MUX寄存器值

sel_input:输入选择寄存器值

pad_ctrl:PAD寄存器值
https://baijiahao.baidu.com/s?id=1740378373755307950&wfr=spider&for=pc
https://www.cnblogs.com/yinsedeyinse/p/16369416.html

posted @   Charles_hui  阅读(86)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示