====== DTS简述 ====== 参考: * [[https://blog.csdn.net/qq_53144843/article/details/123829747|Linux DTS(Device Tree Source)]] * [[http://kernel.meizu.com/device-tree.html|Device Tree 详解]] ===== - DTS文件 ===== DTS文件引用树: kernel/arch/arm64/boot/dts/rockchip/ ./rk3568-firefly-mplayer.dts ├─./rk3568-firefly-mplayer.dtsi │ └─./rk3568-firefly-port.dtsi │ ├─./rk3568-firefly-core.dtsi │ │ └─./rk3568.dtsi │ │ ├─./rk3568-dram-default-timing.dtsi │ │ └─./rk3568-pinctrl.dtsi │ │ └─./rockchip-pinconf.dtsi │ ├─./rk356x-firefly-demo.dtsi │ └─./rk3568-linux.dtsi └─./rk3568-firefly-aioj-cam-8ms1m.dtsi ===== - node节点 ===== {}包围起来的结构称之为节点,dts中最开头的/ {},称为根节点。 \\ 节点的标准结构是xxx@yyy{属性1;属性2;...},其中: xxx:节点名 \\ yyy(可选):节点的地址(寄存器地址或其他地址) \\ 例: \\ i2c1:i2c@021a0000 \\ rtc:pcf8523@68 ==== - 一般属性 ==== === - reg === reg的格式通常为
\\ 例:reg = <0x021a0000 0x4000>; 0x021a0000是寄存器基地址,0x4000是长度。 \\ address 和length的个数是可变的,由父节点的属性#address-cells 和#size-cells 决定, \\ 比如节点i2c@021a0000的父节点是aips-bus@02000000,其#address-cells 和#size-cells均为1,所以下面的i2c节点的reg属性就有一个address 和length, \\ 而i2c节点本身#address-cells 和#size-cells 分别为1和0,所以其下的rtc: pcf8523@68 的reg属性就只有一个0x68(i2c地址)了 i2c1: i2c@021a0000 { #address-cells = <1>; #size-cells = <0>; compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c"; reg = <0x021a0000 0x4000>; interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX6QDL_CLK_I2C1>; status = "disabled"; }; 配置node可以根据compatible,在kernel/Documentation/devicetree/bindings中查到说明, \\ 或在 kernel/drivers/tty/serial/ 早到驱动代码。例如: v2m_serial0: uart@090000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x090000 0x1000>; interrupts = <5>; clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; clock-names = "uartclk", "apb_pclk"; }; &i2c1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hummingboard_i2c1>; rtc: pcf8523@68 { compatible = "nxp,pcf8523"; reg = <0x68>; }; === - compatible === 如果一个节点是设备节点,那么它一定要有compatible(兼容性),因为这将作为驱动和设备(设备节点)的匹配依据, \\ compatible(兼容性)的值可以有不止一个字符串以满足不同的需求。 \\ 而根节点的compatible也是非常重要的,因为系统启动后,将根据根节点的compatible来判断cpu信息,并由此进行初始化。 === - pinctrl-names === pinctrl-names:定义设备不同的工作状态,一般包括下面几个: \\ default、init、sleep、idle \\ 其中,sleep、idle用于系统的电源管理,以达到控制系统功耗的目的。\\ pinctrl-0:定义了一个phandles的列表,每个phandle指向一个pinctrl的节点。 \\ 该配置项定义了该设备的一种工作状态,其对应于pinctrl-names中首个工作状态。 下面举例说明一下: deviceA { pinctrl-names = “defalut”, “idle”; pinctrl-0 = <&state_0_node_a>; pinctrl-1 = <&state_1_node_a &state_1_node_b>; }; deviceA节点,定义了"default","idle"两种工作状态,随后依次定义了pinctrl-0和pinctrl-1两个pins列表,分别对应于两个状态。 === - 属性的编写说明 === == - 参考SDK中第的属性说明 == # cd kernel cd Documentation/devicetree/bindings/ grep "arm,pl011" -rn * == - 在代码中获取属性编写格式 == # cd kernel/drivers/tty/serial/ grep "arm,pl011" -rn * ==== - 节点之间的联系 ==== * 节点与节点之间的关联,通常通过“标号引用”和“包含”来实现 - 标号引用,就是在节点名称前加上标号,这样设备树的其他位置就能够通过&符号来调用/访问该节点 - 包含则是最基本的方式,比如我们要在i2c1接口添加一个i2c外设,那么就必须要在i2c1下面添加一个节点 * 标号引用常常还作为节点的重写方式 * 如果一个节点是属性节点(即仅仅是作为属性被其他节点调用),可定义在任意位置 属性节点定义在哪里其实无所谓,重要的是调用的位置,比如lcd屏幕的时序, \\ 其实我们完全可以把它定义在任何地方,然后在lcd节点下用&来调用它。 \\ 这有点类似于函数:在哪定义不重要,重要的是在哪调用。 ===== - DTS相关工具 ===== ==== - devicetree(linux) ==== 工具主页:https://gitee.com/yuwenhai/device-tree-tools * 安装: wget https://gitee.com/yuwenhai/device-tree-tools/raw/master/devicetree/dt.py;mv dt.py ~/bin/dt;chmod 755 ~/bin/dt * 参数 usage: 从设置的根节点预览或搜索指定关键字 设备树查看器(0.9) options: -s SET_CONF, -set SET_CONF, --set SET_CONF 设置dtv.conf文件 -c, -config, --config 显示当前使用的dtv.conf文件路径 -r, -root, --root 显示当前的根节点路径 -z, -hp, --hidePath, -short, --short 按照最短路径显示 -f FIND_KEYWORD, -find FIND_KEYWORD, --find FIND_KEYWORD 搜索指定内容 -x {re,all}, -flag {re,all}, --flag {re,all} re:启用正则表达式搜索 all:在所有树中显示 -d, -debug, --debug Debug模式运行 -no-color, --no-color 禁用颜色显示 -v, --version 显示当前版本 --history 显示历史变更记录 -h, --help 显示帮助页 * 设置: dt -set ~/linux_sdk/kernel/arch/arm64/boot/dts/rockchip/rk3568-firefly-mplayer.dts * 运行: dt -h dt -z dt -z -find pinctrl