如何利用Zephyr API将字符串字面量转为令牌适配UART枚举配置?
实现Devicetree字符串属性到UART枚举宏的编译时转换
问题场景
我在bindings.yaml中定义了如下parity属性:
parity: type: string required: false default: "NONE" description: Sets the necessary UART parity required by the sensor. enum: - "NONE" - "ODD" - "EVEN" - "MARK" - "SPACE"
通过Zephyr的Devicetree API,我可以用DT_PROP(device, parity);获取这些字符串字面量,但Zephyr的UART API对应的枚举宏是:
UART_CFG_PARITY_NONE UART_CFG_PARITY_ODD UART_CFG_PARITY_EVEN UART_CFG_PARITY_MARK UART_CFG_PARITY_SPACE
我需要编写一个宏SOME_MACRO(device, parity),让它在编译时把DT中的字符串转换成对应的UART枚举宏,最终展开成:
static const struct uart_config config = { .parity = UART_CFG_PARITY_<NONE/ODD/EVEN/MARK/SPACE>, };
解决方案
通过C预处理器的字符串拼接与宏映射特性,即可实现编译时的转换,具体步骤如下:
1. 定义字符串到枚举宏的映射辅助宏
先编写一层辅助宏,将每个字符串字面量直接映射到对应的UART枚举:
#define PARITY_STR_TO_ENUM(str) \ _PARITY_STR_TO_ENUM_##str #define _PARITY_STR_TO_ENUM_NONE UART_CFG_PARITY_NONE #define _PARITY_STR_TO_ENUM_ODD UART_CFG_PARITY_ODD #define _PARITY_STR_TO_ENUM_EVEN UART_CFG_PARITY_EVEN #define _PARITY_STR_TO_ENUM_MARK UART_CFG_PARITY_MARK #define _PARITY_STR_TO_ENUM_SPACE UART_CFG_PARITY_SPACE
2. 封装Devicetree属性处理宏
针对DT_PROP的输出做一层封装,让它自动完成字符串到枚举的转换:
#define DT_PARITY_TO_UART_ENUM(node_id, prop) \ PARITY_STR_TO_ENUM(DT_PROP(node_id, prop))
3. 实际使用示例
直接在UART配置结构体中调用这个宏即可:
static const struct uart_config config = { .parity = DT_PARITY_TO_UART_ENUM(device, parity), };
原理说明
预处理器会按以下顺序展开宏:
- 先执行
DT_PROP(device, parity),得到对应字符串(比如NONE); - 接着
PARITY_STR_TO_ENUM将字符串拼接成_PARITY_STR_TO_ENUM_NONE; - 最后预处理器把拼接后的标识符替换为对应的UART枚举宏
UART_CFG_PARITY_NONE。
可选的边界处理
如果担心出现未定义的parity值(尽管bindings.yaml已限制枚举范围),可以添加默认分支:
#define PARITY_STR_TO_ENUM(str) \ _PARITY_STR_TO_ENUM_WRAPPER(str) #define _PARITY_STR_TO_ENUM_WRAPPER(str) \ _PARITY_STR_TO_ENUM_##str #define _PARITY_STR_TO_ENUM_NONE UART_CFG_PARITY_NONE #define _PARITY_STR_TO_ENUM_ODD UART_CFG_PARITY_ODD #define _PARITY_STR_TO_ENUM_EVEN UART_CFG_PARITY_EVEN #define _PARITY_STR_TO_ENUM_MARK UART_CFG_PARITY_MARK #define _PARITY_STR_TO_ENUM_SPACE UART_CFG_PARITY_SPACE // 未匹配时的默认值 #define _PARITY_STR_TO_ENUM_DEFAULT UART_CFG_PARITY_NONE // 当无匹配宏时,自动回退到默认值 #define _PARITY_STR_TO_ENUM_WRAPPER(str) \ _PARITY_STR_TO_ENUM_DEFAULT
内容的提问来源于stack exchange,提问作者magnusmaehlum
相关产品推荐
相关产品推荐

