STM32F4开发板Zephyr下DAC设备树Overlay构建报错求助
STM32F4 Discovery + Zephyr DAC驱动构建错误排查
问题背景
尝试在STM32F4 Discovery开发板上使用Zephyr框架驱动PA4引脚的DAC功能,由于开发板主DTS文件未配置DAC,自行编写了设备树overlay文件,但构建时出现设备树节点未找到的错误。
设备树Overlay文件
/ { soc { dac1: dac@40007400 { compatible = "st,stm32-dac"; reg = <0x40007400 0x400>; status = "okay"; label = "DAC_1"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x20000000>; pinctrl-0 = <&dac_out1_pa4>; pinctrl-names = "default"; }; }; };
prj.conf配置
CONFIG_DAC=y CONFIG_DAC_STM32=y
测试代码
#include <zephyr/kernel.h> #include <zephyr/device.h> #include <zephyr/drivers/dac.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define DAC_DEVICE_NODE DT_NODELABEL(dac1) #define DAC_CHANNEL_ID 0 // Use DAC_OUT1 (PA4) as the output pin #define DAC_RESOLUTION 12 // 12-bit resolution static const struct device *const dac_dev = DEVICE_DT_GET(DAC_DEVICE_NODE); int main(void) { if (!dac_dev) { printk("Cannot find %s!\n", DAC_DEVICE_NODE); return 1; } struct dac_channel_cfg channel_cfg = { .channel_id = DAC_CHANNEL_ID, .resolution = DAC_RESOLUTION, }; if (dac_channel_setup(dac_dev, &channel_cfg) != 0) { printk("Setting up of channel %d failed!\n", DAC_CHANNEL_ID); return 1; } /* .... do something.. */ return 0; }
构建错误信息
$ west build -b stm32f4_disco -p auto [28/40] Building C object CMakeFiles/app.dir/src/main.c.obj FAILED: CMakeFiles/app.dir/src/main.c.obj ccache /home/mitch/bin/zephyr-sdk-0.16.0/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc -DCORE_CM4 -DHSE_VALUE=8000000 -DKERNEL -DSTM32F407xx -DUSE_FULL_LL_DRIVER -DUSE_HAL_DRIVER -D__PROGRAM_START -D__ZEPHYR__=1 -I/home/mitch/git/myproject/zephyr/include -I/home/mitch/git/myproject/build/zephyr/include/generated -I/home/mitch/git/myproject/zephyr/soc/arm/st_stm32/stm32f4 -I/home/mitch/git/myproject/zephyr/drivers -I/home/mitch/git/myproject/zephyr/soc/arm/st_stm32/common -I/home/mitch/git/myproject/modules/hal/cmsis/CMSIS/Core/Include -I/home/mitch/git/myproject/modules/hal/stm32/stm32cube/stm32f4xx/soc -I/home/mitch/git/myproject/modules/hal/stm32/stm32cube/stm32f4xx/drivers/include -I/home/mitch/git/myproject/modules/hal/stm32/stm32cube/stm32f4xx/drivers/include/Legacy -I/home/mitch/git/myproject/modules/hal/stm32/stm32cube/common_ll/include -isystem /home/mitch/git/myproject/zephyr/lib/libc/minimal/include -isystem /home/mitch/bin/zephyr-sdk-0.16.0/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/include -isystem /home/mitch/bin/zephyr-sdk-0.16.0/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/include-fixed -fno-strict-aliasing -Os -imacros /home/mitch/git/myproject/build/zephyr/include/generated/autoconf.h -ffreestanding -fno-common -g -gdwarf-4 -fdiagnostics-color=always -mcpu=cortex-m4 -mthumb -mabi=aapcs --sysroot=/home/mitch/bin/zephyr-sdk-0.16.0/arm-zephyr-eabi/arm-zephyr-eabi -imacros /home/mitch/git/myproject/zephyr/include/zephyr/toolchain/zephyr_stdint.h -Wall -Wformat -Wformat-security -Wno-format-zero-length -Wno-pointer-sign -Wpointer-arith -Wexpansion-to-defined -Wno-unused-but-set-variable -Werror=implicit-int -fno-pic -fno-pie -fno-asynchronous-unwind-tables -fno-reorder-functions --param=min-pagesize=0 -fno-defer-pop -fmacro-prefix-map=/home/mitch/git/myproject=CMAKE_SOURCE_DIR -fmacro-prefix-map=/home/mitch/git/myproject/zephyr=ZEPHYR_BASE -fmacro-prefix-map=/home/mitch/git/myproject=WEST_TOPDIR -ffunction-sections -fdata-sections -std=c99 -nostdinc -MD -MT CMakeFiles/app.dir/src/main.c.obj -MF CMakeFiles/app.dir/src/main.c.obj.d -o CMakeFiles/app.dir/src/main.c.obj -c /home/mitch/git/myproject/src/main.c In file included from /home/mitch/git/myproject/zephyr/include/zephyr/devicetree.h:19, from /home/mitch/git/myproject/zephyr/include/zephyr/arch/arm/aarch32/arch.h:20, from /home/mitch/git/myproject/zephyr/include/zephyr/arch/cpu.h:19, from /home/mitch/git/myproject/zephyr/include/zephyr/kernel_includes.h:33, from /home/mitch/git/myproject/zephyr/include/zephyr/kernel.h:17, from /home/mitch/git/myproject/src/main.c:1: /home/mitch/git/myproject/src/main.c: In function 'main': /home/mitch/git/myproject/build/zephyr/include/generated/devicetree_generated.h:4816:34: error: 'DT_N_S_soc_S_dac_40007400' undeclared (first use in this function); did you mean 'DT_N_S_soc_S_dac_40007400_ORD'? 4816 | #define DT_N_NODELABEL_dac1 DT_N_S_soc_S_dac_40007400 | ^~~~~~~~~~~~~~~~~~~~~~~~~ /home/mitch/git/myproject/zephyr/include/zephyr/devicetree.h:4096:24: note: in expansion of macro 'DT_N_NODELABEL_dac1' 4096 | #define DT_CAT(a1, a2) a1 ## a2 | ^~ /home/mitch/git/myproject/zephyr/include/zephyr/devicetree.h:192:29: note: in expansion of macro 'DT_CAT' 192 | #define DT_NODELABEL(label) DT_CAT(DT_N_NODELABEL_, label) | ^~~~~~ /home/mitch/git/myproject/src/main.c:13:25: note: in expansion of macro 'DT_NODELABEL' 13 | #define DAC_DEVICE_NODE DT_NODELABEL(dac1) | ^~~~~~~~~~~~ /home/mitch/git/myproject/src/main.c:103:33: note: in expansion of macro 'DAC_DEVICE_NODE' 103 | printk("Cannot find %s!\n", DAC_DEVICE_NODE); | ^~~~~~~~~~~~~~~ /home/mitch/git/myproject/build/zephyr/include/generated/devicetree_generated.h:4816:34: note: each undeclared identifier is reported only once for each function it appears in 4816 | #define DT_N_NODELABEL_dac1 DT_N_S_soc_S_dac_40007400 | ^~~~~~~~~~~~~~~~~~~~~~~~~ /home/mitch/git/myproject/zephyr/include/zephyr/devicetree.h:4096:24: note: in expansion of macro 'DT_N_NODELABEL_dac1' 4096 | #define DT_CAT(a1, a2) a1 ## a2 | ^~ /home/mitch/git/myproject/zephyr/include/zephyr/devicetree.h:192:29: note: in expansion of macro 'DT_CAT' 192 | #define DT_NODELABEL(label) DT_CAT(DT_N_NODELABEL_, label) | ^~~~~~ /home/mitch/git/myproject/src/main.c:13:25: note: in expansion of macro 'DT_NODELABEL' 13 | #define DAC_DEVICE_NODE DT_NODELABEL(dac1) | ^~~~~~~~~~~~ /home/mitch/git/myproject/src/main.c:103:33: note: in expansion of macro 'DAC_DEVICE_NODE' 103 | printk("Cannot find %s!\n", DAC_DEVICE_NODE); | ^~~~~~~~~~~~~~~ ninja: build stopped: subcommand failed. FATAL ERROR: command exited with status 1: /usr/bin/cmake --build /home/mitch/git/myproject/build
错误原因与解决方案
核心问题分析
错误提示DT_N_S_soc_S_dac_40007400未声明,本质是设备树节点未被正确解析,同时存在两个关键问题:
- 原overlay未定义
dac_out1_pa4引脚组,主DTS中无此预设节点 - 代码中直接将
DT_NODELABEL(dac1)作为字符串传入printk,该宏展开的是设备树节点的内部标识,不是可读字符串
分步修复
1. 修正设备树Overlay(添加引脚配置与标准属性)
补充引脚复用配置,并添加Zephyr DAC设备树要求的属性:
/ { soc { dac1: dac@40007400 { compatible = "st,stm32-dac"; reg = <0x40007400 0x400>; status = "okay"; label = "DAC_1"; clocks = <&rcc STM32_CLOCK_BUS_APB1 0x20000000>; pinctrl-0 = <&dac_out1_pa4>; pinctrl-names = "default"; #dac-channel-cells = <1>; // 必须添加,指定通道标识的单元格数量 }; }; }; &gpioa { dac_out1_pa4: dac-out1-pa4 { pinmux = <STM32_PINMUX('A', 4, ANALOG)>; // 配置PA4为模拟模式 bias-disable; // 禁用上下拉 }; };
2. 修正代码中的printk错误
替换错误的字符串输出方式,使用DEVICE_DT_NAME宏获取设备名称:
// 替换原错误行 if (!device_is_ready(dac_dev)) { printk("DAC device %s not ready!\n", DEVICE_DT_NAME(DAC_DEVICE_NODE)); return 1; }
3. 确保Overlay被正确加载
- 将Overlay文件命名为
stm32f4_disco.overlay,放在项目根目录的boards/文件夹下 - 或通过构建命令手动指定:
west build -b stm32f4_disco -p auto -- -DDTC_OVERLAY_FILE=./path/to/your/overlay.dts
4. 添加编译时节点验证
在代码开头添加节点存在性检查,提前发现问题:
#if !DT_NODE_EXISTS(DAC_DEVICE_NODE) #error "DAC node dac1 not found in devicetree!" #endif
最终测试代码修正版
#include <zephyr/kernel.h> #include <zephyr/device.h> #include <zephyr/drivers/dac.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define DAC_DEVICE_NODE DT_NODELABEL(dac1) #define DAC_CHANNEL_ID 0 // DAC_OUT1对应通道0 #define DAC_RESOLUTION 12 // 12位分辨率 #if !DT_NODE_EXISTS(DAC_DEVICE_NODE) #error "DAC node dac1 not found in devicetree!" #endif static const struct device *const dac_dev = DEVICE_DT_GET(DAC_DEVICE_NODE); int main(void) { if (!device_is_ready(dac_dev)) { printk("DAC device %s not ready!\n", DEVICE_DT_NAME(DAC_DEVICE_NODE)); return 1; } struct dac_channel_cfg channel_cfg = { .channel_id = DAC_CHANNEL_ID, .resolution = DAC_RESOLUTION, }; if (dac_channel_setup(dac_dev, &channel_cfg) != 0) { printk("Failed to setup DAC channel %d!\n", DAC_CHANNEL_ID); return 1; } // 测试输出:生成12位中间值(对应1.65V左右,假设Vref=3.3V) uint32_t value = (1 << DAC_RESOLUTION) / 2; if (dac_write_value(dac_dev, DAC_CHANNEL_ID, value) != 0) { printk("Failed to write value to DAC channel %d!\n", DAC_CHANNEL_ID); return 1; } printk("DAC channel %d configured, value %u written!\n", DAC_CHANNEL_ID, value); return 0; }
内容的提问来源于stack exchange,提问作者smthingshwere
相关产品推荐
相关产品推荐

