预处理后DTS文件的最终状态及dtc兼容问题咨询
DTS预处理与dtc兼容问题解答
1. 预处理后合法DTS的最终状态
预处理后的DTS必须是纯设备树语法文本,绝对不能包含任何C语言特有的语法元素——比如typedef、struct定义、C风格单行注释//、宏展开后残留的C代码片段等。最终文本只能保留:
- 设备树的节点、属性、标签等核心语法结构
#define宏展开后的合法设备树内容(比如引脚编号、寄存器地址这类数值或字符串宏)- 预处理阶段正确展开的设备树片段(来自
.dtsi或设备树专用头文件)
2. #include指令的正确保留内容
只有当#include引入的是设备树专用头文件时,其展开内容才是合法的。这类文件包括:
- 设备树片段文件
.dtsi - 仅包含
#define宏定义的头文件(比如Linux下dt-bindings/目录下的文件)
如果引入了普通C头文件(比如标准库、平台驱动的C头文件),会把C的类型声明、函数原型等无关内容带进来,直接导致dtc报错。
3. dtc对预处理内容的兼容边界
dtc是纯设备树编译器,完全不兼容任何C语言语法。它只能处理符合设备树规范的文本,任何C特有关键字、语法结构都会触发报错。dtc仅支持有限的预处理特性:
- 简单的
#define宏展开(仅限数值、字符串替换) - 正确展开设备树相关的
#include内容 - 处理
#ifdef/#ifndef/#endif等条件编译指令,但最终输出不能残留这些指令
4. Linux头文件对DTS的适配
Linux内核里的设备树相关头文件(比如dt-bindings/gpio.h、dt-bindings/interrupt-controller/irq.h等)是专门为DTS设计的:
- 仅包含
#define宏定义(比如引脚功能编码、中断类型标识) - 完全没有C语言的类型声明、函数原型等内容
- 部分文件会用
#ifdef __ASSEMBLY__或#ifdef __DTS__这类条件编译,确保预处理DTS时只保留宏定义,过滤掉C相关代码
普通Linux内核C头文件(比如linux/types.h)不适合在DTS中引入,因为它们包含大量C语法元素。
5. 你的预处理命令可能存在的问题
大概率是预处理命令没有正确过滤C语言内容,常见问题包括:
- 未指定
-x assembler-with-cpp参数:gcc默认将输入当作C文件处理,会保留typedef等C语法。指定该参数后,gcc会以汇编预处理模式处理,忽略C特有的语法,只处理宏和#include。 - 引入了非设备树专用头文件:检查你的DTS代码,确保所有
#include的都是设备树相关文件,不要包含平台驱动的C头文件。 - 未定义专用宏触发条件编译:比如没有添加
-D__DTS__参数,导致头文件中原本为DTS准备的条件分支未生效,C代码被意外展开。
给你一个参考的正确预处理命令:
gcc -E -x assembler-with-cpp -D__DTS__ input.dts -o preprocessed.dts
内容的提问来源于stack exchange,提问作者MysteryMoose
相关产品推荐
相关产品推荐

