Zephyr RTOS设备树覆盖与修改:一块开发板上的“偷梁换柱”实战
从一次GPIO死活拉不高的调试说起
去年做一款工业数据采集器,主控用nRF52840,外挂一颗SPI接口的ADC。板子打样回来,上电,SPI通信正常,但ADC的片选信号——一个普通的GPIO——死活拉不高。示波器点上去,波形只有1.2V,逻辑分析仪显示电平始终在阈值附近抖动。查原理图,查焊接,查驱动代码,折腾两天。
最后发现是设备树里这个GPIO被默认配置成了开漏输出,而我在overlay文件里只改了pinmux,没动驱动强度。Zephyr的设备树覆盖机制,就在这种“你以为你改了,其实没完全改”的坑里,让我交了学费。
设备树覆盖不是“覆盖”,是“叠加”
很多刚接触Zephyr的朋友,看到“覆盖”两个字,以为就是拿一个新文件把原设备树整个替换掉。这是第一个要纠正的认知。Zephyr的设备树覆盖机制,本质上是多层叠加——就像Photoshop的图层,上层文件只修改你指定的节点,其他所有内容继承自底层。
默认的设备树文件(比如nrf52840dk_nrf52840.dts)是基础层。你写的app.overlay是上层。编译时,Zephyr的gen_defines.py脚本会把它们合并成一个完整的设备树。合并规则很简单:同路径节点,上层属性覆盖下层;不同路径节点,全部保留。
这个机制的好处是,你不需要复制整个几百行的设备树