这边有一篇博客详细解释了zephyr devicetree,这篇文章则实战一下,看看是否可以帮助大家进一步理解devicetree,并且可以快速使用devicetree。
https://www.cnblogs.com/jayant97/articles/17209392.html
使用devicetree主要需要关心几个东西:
1. 找到相关devicetree文件的所处位置,这边列出目前所有的文件目录。
假如文件结构如下:
/repository
-- /bootloader
-- /modules
-- /nrf
-- /nrfxlib
-- /zephyr
那么所涉及到的所有devicetree文件如下:
\zephyr\dts 在zephyr原生目录下找到
\zephyr\boards
\nrf\dts 在应用目录下找到
\nrf\boards
\nrf\samples\bluetooth\peripheral_uart\board 在你创建的应用目录下也可以找到
\nrf\samples\bluetooth\peripheral_uart
也可以先编译,然后在如下目录中查看用到了哪些与devicetree相关的文件
\build\zephyr\zephyr.dts.d
如下这个dts文件是将所有相关dts、dtsi、overlay整合在一起形成的最终device tree文件。
所以如果你的同事或者供应商已经提供了devicetree,你可以首先观察这个zephyr.dts,然后进行编程,而不必关心其它devicetree文件。
\build\zephyr\zephyr.dts
2. 找到应用层获取节点信息的接口文件
zephyr\include\zephyr\devicetree.h
此文件中所有的宏都是DT_****
zephyr\include\zephyr\device.h
此文件中所有的宏都是DEVICE_**** 或 Z_DEVICE_****
build\zephyr\include\generated\devicetree_generated.h
3. 打开相关Kconfig宏
用到什么外设,就要打开什么外设的宏,这些宏会在CMakefile中出现,用来控制是否编译这个驱动文件,每个目录下都有一个CMakefile,这个CMakefile会控制编译哪些文件。
4. 获取device tree 节点
DEVICE_DT_GET(DT_NODELABEL( ))
DEVICE_DT_GET(DT_ALIAS( ))
get_binding()
还有很多花式获取节点的方式,有时候我就不太理解,为什么不能统一,仔细想想,可能是因为各供应商写devicetree时为了适配自己外设的特性,写法都不一样,所以导致应用层要构建很多获取节点的方式才可以适配更多厂家的外设。
5. 调用zephyr提供的通用接口
比如我们在zephyr中想要控制gpio,那么自然而然想到gpio驱动,所以我们要去zephyr\drivers里面找到gpio的驱动文件,这里面的驱动文件都是和硬件平台无关的,都是zephyr自带的接口。我们在zephyr下编程的时候理论上讲,通用外设都要用zephyr提供的接口,这样才可以做到统一,并且为移植带来便利。特例是,如果芯片中有特殊外设,比如nordic中有一个ppi外设,这个外设就无法通过zephyr通用接口来控制,我们只能调用nrfx_****接口来使用ppi外设。
6. 如何寻找例程
例程可以到zephyr或者应用目录下去找samples目录,其中的例子相当丰富,烧录到开发板中可以直接看到效果,但是和特定板子强绑定后,不便于我们真正理解devicetree。这个时候需要我们自己去改变device tree的结构,然后测试,
那么在yaml文件中我们可以找到一些device tree的写法。
7. 如果找不到相关开发板的例程应该从哪里获得启发
有一种杀手锏,我们直接定位到驱动文件,然后查看这个驱动是如何通过DTS_****宏获取节点信息的。这种方法可以说是你彻底理解devicetree的必经之路。
接下来我们建造一些例程:
……