Zephyr中overlay文件GPIO节点未在devicetree_generated.h定义致编译失败
在nRF52840开发板上使用Zephyr v3.2.99(基于NCS v2.2.0)开发应用时,已配置nrf52840dk_nrf52840.overlay且CMake已读取该文件,但生成的devicetree_generated.h中缺少自定义GPIO节点的定义,导致编译失败。
overlay文件内容
/ { aliases { pwr0 = &pinpwr0; eu0 = &pineu0; psw0 = &pinsw0; }; pinpwr0: pin_pwr_0 { gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; label = "power"; }; pineu0: pin_eu_0 { gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>; label = "eu"; }; pinsw0: pin_sw_0 { gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>; label = "switch"; }; chosen { nordic,nus-uart = &uart0; }; };
C文件相关代码
#define PWR_IO DT_ALIAS(pwr0) #if DT_NODE_HAS_STATUS(PWR_IO, okay) #define PWR_IO_PIN DT_GPIO_PIN(PWR_IO, gpios) #else #error "Cannot find the board" #define PWR_IO_PIN 0 #endif static const struct gpio_dt_spec pwr = GPIO_DT_SPEC_GET(PWR_IO, gpios);
编译错误信息
zephyr/include/generated/devicetree_generated.h:701:32: error:
'DT_N_S_pin_pwr_0_P_gpios_IDX_0_VAL_pin' undeclared here (not in a
function); did you mean 'DT_N_S_leds_S_led_0_P_gpios_IDX_0_VAL_pin'?
701 | #define DT_N_ALIAS_pwr0 DT_N_S_pin_pwr_0
| ^~~~~~~~~~~~~~~~ F:/ncs/v2.2.0/zephyr/include/zephyr/devicetree.h:3901:9: note: in
definition of macro 'DT_CAT7' 3901 | a1 ## a2 ## a3 ## a4 ##
a5 ## a6 ## a7
| ^~ F:/ncs/v2.2.0/zephyr/include/zephyr/devicetree/gpio.h:164:9: note: in
expansion of macro 'DT_PHA_BY_IDX' 164 |
DT_PHA_BY_IDX(node_id, gpio_pha, idx, pin)
| ^~~~~~~~~~~~~ F:/ncs/v2.2.0/zephyr/include/zephyr/drivers/gpio.h:341:24: note: in
expansion of macro 'DT_GPIO_PIN_BY_IDX' 341 | .pin =
DT_GPIO_PIN_BY_IDX(node_id, prop, idx),
| ^~~~~~~~~~~~~~~~~~ F:/ncs/v2.2.0/zephyr/include/zephyr/drivers/gpio.h:376:9: note: in
expansion of macro 'GPIO_DT_SPEC_GET_BY_IDX' 376 |
GPIO_DT_SPEC_GET_BY_IDX(node_id, prop, 0)
| ^~~~~~~~~~~~~~~~~~~~~~~ ../src/tvunit.c:25:40: note: in expansion of macro 'GPIO_DT_SPEC_GET' 25 | static const struct
gpio_dt_spec pwr = GPIO_DT_SPEC_GET(PWR_IO, gpios);
检查devicetree_generated.h发现,DT_N_S_pin_pwr_0宏未被定义(仅在注释中提及),请问哪里操作错误?
问题出在自定义GPIO节点缺少status = "okay";属性。Zephyr的Devicetree处理逻辑中,只有标记为status = "okay";的节点才会被视为启用状态,编译器才会为其生成对应的宏定义并写入devicetree_generated.h。
修改overlay文件,为每个自定义GPIO节点添加status = "okay";属性即可解决问题:
/ { aliases { pwr0 = &pinpwr0; eu0 = &pineu0; psw0 = &pinsw0; }; pinpwr0: pin_pwr_0 { gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; label = "power"; status = "okay"; // 新增属性 }; pineu0: pin_eu_0 { gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>; label = "eu"; status = "okay"; // 新增属性 }; pinsw0: pin_sw_0 { gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>; label = "switch"; status = "okay"; // 新增属性 }; chosen { nordic,nus-uart = &uart0; }; };
修改完成后,重新编译项目:
- 清理之前的构建产物:
west build -t clean - 重新构建:
west build -b nrf52840dk_nrf52840
此时devicetree_generated.h中会生成DT_N_S_pin_pwr_0等相关宏,编译错误将消失。
内容的提问来源于stack exchange,提问作者jfarjona

