[Device Tree]是目前嵌入式 Linux 系统最常用的设备解耦工具, 所以要玩转嵌入式 Linux , 这个东西必须掌握.
DTB, DTS , DTSI?
在 tina sdk 代码中, 有 board.dts , sun20iw1p1.dtsi 这些文件, 这些就是 device tree 的源文件,或者说描述文件.
dts 通过 dtc 这个编译器可以编译成 dtb 以及后面我们要用到的 dtbo(dtb overlay) , 它们是二进制文件, Linux 和 uboot 可以使用.
DTC
Device Tree Compiler , dts 的编译工具, Linux 下面可以使用包管理工具按照
# redora sudo dnf install dtc
# ubuntu
sudo apt install device-tree-compiler
复制代码
windows 参考(未验证):
https://github.com/lbmeng/dtc
dtb overlay 示例代码
在之前给出的 demo 镜像中, pwm7 这个设备的驱动部分在 dts 中被注释了, 所以我们尝试用 dtb overlay 给他弄回来.
dtbo 的编译只要 dtc 就可以, 但是我们会看到 dtsi 中有 c 语言的 #include 宏,所以还会用到 c编译根据展开宏,如果没有 #include ,就不需要.
使用 #include 宏展开示例, include 里面都是 dt-bindings 目录下的文件,该目录在 tina 中的位置是: lichee/linux-5.4/include , 你要展开需要将 lichee/linux-5.4/include/dt-bindings 拷贝到 dts 目录中来
bash cpp -nostdinc -I. -undef -x assembler-with-cpp board.dts > board-with-include.dts
复制代码
执行后, board-with-include.dts 就是 include 展开后的代码.
pwm7-overlay.dts 示例代码
dts /dts-v1/; /plugin/;
/ { fragment@0 { target-path = "/soc/pinctrl@2000000"; __overlay__ { pwm7_pin_a: pwm7@0 { pins = "PD22"; function = "pwm7"; drive-strength = <10>; bias-pull-up; };
pwm7_pin_b: pwm7@1 { pins = "PD22"; function = "gpio_in"; }; }; };
fragment@1 { target-path = "/soc/pwm7@2000c17"; __overlay__ { pinctrl-names = "active", "sleep"; pinctrl-0 = <&pwm7_pin_a>; pinctrl-1 = <&pwm7_pin_b>; status = "okay"; }; };
};
复制代码
头部是作为一个 overlay 的描述, 和 dts 相比多了 /plugin/; 这个节点
后面同样有个 / 根节点, 然后需要覆盖的地方用 fragment@x 作为节点名称
fragment 里面 target-path 为需要覆盖的节点路径, 也可以用 target 使用的是引用.
后面 __overlay__ 里面就是需要覆盖的属性.
编译
bash dtc -I dts -O dtb -o ./pwm7-overlay.dtbo ./pwm7-overlay.dts
复制代码
这样得到的 pwm7-overlay.dtbo 文件就是我们所要的. 可以用
`fdtdump ./pwm7-overlay.dtbo` 查看结果
测试
一个测试程序 (pwm.sh, 来自 RVBoards) 和蜂鸣器扩展版
bash #!/bin/bash #pwm 节点 pwmnode=pwm$1 #输出提示pwm$1 通道 echo /sys/class/pwm/pwmchip0/${pwmnode} #申请pwm$1 通道 echo $1 > /sys/class/pwm/pwmchip0/export #指定pwm$1 通道的频率 echo $2 > /sys/class/pwm/pwmchip0/${pwmnode}/period #指定pwm$1 通道的占空比 echo $3 > /sys/class/pwm/pwmchip0/${pwmnode}/duty_cycle #使能pwm$1 通道 echo 1 > /sys/class/pwm/pwmchip0/${pwmnode}/enable #使能pwm$1 通道 工作时间10s sleep 10 #失能pwm$1 通道 echo 0 > /sys/class/pwm/pwmchip0/${pwmnode}/enable #等待pwm$1 通道 关闭 sleep 1 #注销pwm$1 通道 echo $1 > /sys/class/pwm/pwmchip0/unexport
复制代码
在没有配置 dtb overlay 的系统中执行
bash # 设置 7 号 pwm 引脚数据 ./pwm.sh 7 300000 150000
复制代码
会出现错误
然后将 `pwm7-overlay.dtbo` 复制到 boot 分区的 overlay 目录下, 在编辑 config.txt 添加配置
`dtboverlay=pwm7-overlay` , 配置中不需要加 `.dtbo`, 系统会自动添加.
重启后, 在执行
`./pwm.sh 7 300000 150000` , 蜂鸣器就会响了.
如果没有蜂鸣器扩展版,可以查看 `/sys/class/pwm/` 里面的内容,进行前后对比,也会发现 dtb overlay 生效了.
后记
dtb 以及相关技术需要去掌握,掌握了就可以把开发板玩的更溜了, 如果你去使用各种大的扩展板, 基本都会涉及到 dtb overlay.
原贴链接:https://bbs.aw-ol.com/topic/144/
全志在线开发者交流企鹅群(客服机器人24小时在线解答):498263967
资源获取、问题讨论可以到全志在线开发者社区进行:https://www.aw-ol.com/
全志及开发者最新动态可以关注全志在线微信公众号
|