首先推荐elinux.org上一篇关于Device Tree的文章:
http://elinux.org/Device_Tree_Usage
这是一篇关于Device Tree的入门文章。对英文犯怵的童鞋也不要紧,我在csdn上找到了翻译稿:
http://blog.csdn.net/21cnbao/article/details/8457546
译文重新组织了部分语言,开头还写了一段关于DT的轶事,不过基本上还是忠于英文原文的。但还是要提个醒,这篇翻译稿比较早了,而英文版在后来又经过几次更新,所以中文翻译版的内容不及英文原稿详尽。
上面的文章对于Device Tree入门足够了,所以我不打算再重复已有的内容,仅写一些开发过程中可能会用到的杂七杂八的东西。这些东西有的来自对厂商SDK所含DT的研究,有的来自Linux源代码树下Documentation目录下关于Device Tree的内容。
1. compatible条目
compatible尽量采用精确名称。比如am33xx系列处理器,compatible要写成"TI,am3352",而不要写成“TI,am33xx”。这主要是为了防止芯片厂家什么时候脑袋抽抽了,比如弄出一个am3362处理器,和am3352还不兼容,那你原来写的“TI,am33xx”就可能造成曲解。
2. binding
在开始写你自己的DT之前,先看下内核源代码树下Documentation/devicetree目录,以及其下的binding子目录。binding子目录记录了内核所支持的所有处理器系列的DT文件规则,好好利用可以降低不少工作量。还是以am33xx系列处理器作例子,我手头有一块BBB,在它的GPMC口上连接了一个小东西,网上能找到的GPMC配置方法都是在自己的驱动里面对conf_pin_mux和gpmc_conf这两组寄存器作ioremap,也有部分文章会把conf_pin_mux放在DT里面,但gpmc还是在自己的驱动里面配置。而实际上pinmux和gpmc时序都是可以在DT里面配好的,ioremap和写寄存器工作由内核自带的GPMC驱动代为完成。配置方法在Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt。
3. Device Tree反编译
有时候你想看看编译完成的DT和你编写的源文件是不是一致,可以用如下命令对dtb进行反编译:
dtc -I dtb -O dts -o you_dt.dts your_dt.dtb
4. node的status属性
可以通过给外设节点加上如下属性以禁用该node:
status=disabled
这个属性应该厂家SDK用得比较多。因为厂家SDK理应提供所有外设的DT配置,但从使用者角度考虑,某个外设应能自由选择打开或关闭,所以芯片厂家SDK默认情况下应关闭所有可关闭的外设,由板级开发人员打开需要的部分。但要注意了,启用外设的值是okay而不是enabled。嗯,为什么要把这个拿出来说,因为我一开始弄DT的时候理所当然的把disabled覆写为enabled,死活不起作用,被坑惨了。
5. 值覆盖
如果在dtsi文件里,某个node已经对某个property赋值了,你可以用新值覆写旧值。就说上面的status属性,TI SDK的DT文件默认是关闭几乎所有外设的,然而你现在想用i2c0了,这个时候你就可以在你自己的DTS文件里包含TI SDK提供的dtsi文件(这个文件里对i2c0节点的status属性赋值为disabled),然后用你自己的值覆盖:
/* '&'符号表示引用已有的node */
&i2c0 {
status="okay"; /* 用新值覆写旧值 */
};
6. 节点引用(节点关联)
在配置外设节点时几乎总会用到节点关联,因为几乎所有外设都需要配置pinmux。仍然以GPMC作为例子,我们先要配置好GPMC的PINMUX:
gpmc_pinmux_default: gpmc_pinmux_default {
...
};
然后在GPMC节点里告诉kernel使用gpmc_pinmux_default这个引脚配置:
gpmc@50000000 {
...
pinctl-name=<default>;
pinctl-0 = <&gpmc_pinmux_default>; /* 注意'&'符号 */
};