在Zephyr构建过程简述一文中我们知道zephyr对dts的使用是将dts其生成C宏,由代码来使用宏,当时大体提到过dts生成C宏的流程,本文更详细的介绍dts如何生成宏,但生成宏规则不在本文介绍范围内。
概览
下图说明了dts生成宏的详细过程,摘自zephyr官方文档,链接详见文末参考
对于整个流程有4种输入文件:
sources (.dts) : 一般是board的dts文件
includes (.dtsi):被dts包含的dtsi文件,是soc或者驱动级的公用描述
overlays (.overlay):对于相同的应用采用不同的板子时,可以在应用下放不同overlay文件配置应用要用的设备
bindings (.yaml): binding文件,用于帮助dts生成宏
以上文件通常会出现在下面路径
1 | boards/<ARCH>/<BOARD>/<BOARD>.dts |
3种输出文件:
zephyr.dts:该文件是dts,dtsi,overlay合并为一个文件,作为调试参考用
devicetree.h:dts最后生成的宏,会被代码引用
devicetree.conf:dts生成的conf,会被Kconfig引用
下面我们分析详细流程
1 合并整个dts
合并生成dts
将dts和overlay合并为dts.pre.tmp文件
dts.cmake中取得board的dts, 该dts中会include其它dtsi部分
1 | set_ifndef(DTS_SOURCE ${BOARD_DIR}/${BOARD}.dts) |
加入到变量dts_files中
1 | set(dts_files |
将overlay放入dts_files中
1 | string(REPLACE " " ";" DTC_OVERLAY_FILE_AS_LIST ${DTC_OVERLAY_FILE}) |
读出dts文件作为编译的-i选项DTC_INCLUDE_FLAG_FOR_DTS
1 | foreach(dts_file ${dts_files}) |
通过预编译将所有的dts merge为一个dts文件${BOARD}.dts.pre.tmp
1 | execute_process( |
这里提一下empty_file.c,之前一直没搞清楚zephyr里面放个空文件搞什么,现在才知道是为了用来预编译帮助生成一些东西,除了在dts外,构建过程的其它地方也有使用。
检查dts语法
使用dtc工具检查merge后的dts.pre.tmp文件是否符合dts语法,在zephyr中dtc只用于检查合并后的dts.pre.tmp文件的正确性
1 | execute_process( |
2.生devicetree_unfixed.h和devicetree.conf
获取dts的binding文件,也就是dts/binding下的yaml文件
1 | foreach(dts_root ${DTS_ROOT}) |
使用gen_defines.py搭配yaml文件解析{BOARD}.dts.pre.tmp 生成devicetree.conf,devicetree_unfixed.h和zephyr.dts
zephyr.dts只是方便调试查看,不会对之后的构建有任何帮助。
1 | set(CMD_NEW_EXTRACT ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/dts/gen_defines.py |
3. 生成devicetree_fixed.h
在soc目录下不同的架构有一些dts_fixup.h文件,该文件是为了将dts生成的宏转为一些代码里面固定的宏,例如
1 | #define DT_RTC_0_NAME DT_NXP_IMX_GPT_COUNTER_1_LABEL |
这种方式将逐渐被废弃,但目前还在用,这里也说明一下生成过程:
dts_fixup.h合并成为devicetree_fixed.h,在根目录CMakeList.txt中处理。
取出各个地方的dts_fixup.h
1 | set_ifndef( DTS_BOARD_FIXUP_FILE ${BOARD_DIR}/dts_fixup.h) |
定义要生成文件devicetree_fixups.h路径DTS_CAT_OF_FIXUP_FILES
1 | set_ifndef(DTS_CAT_OF_FIXUP_FILES ${ZEPHYR_BINARY_DIR}/include/generated/devicetree_fixups.h) |
读出各个dts_fixup.h的内容将其写入devicetree_fixups.h
1 | file(WRITE ${DTS_CAT_OF_FIXUP_FILES} "/* May only be included by devicetree.h */\n\n") foreach(fixup_file ${DTS_BOARD_FIXUP_FILE} |
4. 生成devicetree.h
合并 devicetree_unfixed.h 和 devicetree_fixed.h 到devicetree.h,采用头文件直接include方式
1 | #include <devicetree_unfixed.h> |
参考
https://docs.zephyrproject.org/latest/guides/dts/intro.html#input-and-output-files