RP2040基于Pico SDK的ARM Semihosting:puts/printf无输出问题
解决ARM Semihosting下puts/printf无输出问题(Wizio-Pico + PlatformIO)
问题背景
在Wizio-Pico裸机平台配置ARM Semihosting以释放USB和UART端口时,puts_raw()可正常输出到调试控制台,但puts()和printf()无任何输出,断点调试时程序直接跳过这两个函数调用进入sleep_ms。需要让标准stdio函数正常工作,且无需根据构建标志修改业务代码。
解决方案
问题核心在于标准库stdio函数的重定向配置与调试器semihosting激活顺序的问题,通过调整PlatformIO配置即可解决:
1. 修改platformio.ini配置
调整构建标志与调试命令顺序,确保semihosting正确关联:
[env] platform = wizio-pico framework = baremetal board = raspberry-pi-pico lib_compat_mode = off lib_archive = false build_src_filter = +<*.h> +<App/main-${PIOENV}.cpp> +<App/main-${PIOENV}.c> +<Common/*.cpp> +<Common/*.c> build_flags = -D TARGET_RP2040 board_build.boot= w25q080 [DEBUG] upload_protocol = picoprobe debug_tool = picoprobe build_flags = -D DEBUG [env:semihosting] extends = DEBUG lib_deps= wiring build_unflags = -lnosys --specs=nosys.specs build_flags = ${env.build_flags} ${DEBUG.build_flags} -D PICO_STDIO_SEMIHOSTING -D PICO_STDIO_ENABLE_CRLF_SUPPORT=0 -D LIB_PICO_PRINTF_PICO -D __SEMIHOSTING__ --specs=rdimon.specs -l rdimon debug_extra_cmds = monitor reset halt monitor arm semihosting enable monitor arm semihosting_fileio enable monitor debug_level -2
关键修改点:
- 添加
-D __SEMIHOSTING__:明确告知编译器与Pico SDK启用semihosting路径,确保标准stdio函数关联到semihosting实现。 - 调整
debug_extra_cmds顺序:先复位暂停目标设备,再启用semihosting功能,避免程序初始化时semihosting未就绪。 - 确保
build_unflags完全移除nosys相关选项:防止nosys的空stdio实现覆盖rdimon的semihosting逻辑。
2. 保持业务代码不变
无需修改main-semihosting.c,原代码即可正常工作:
#include <stdio.h> #include "pico/stdlib.h" #include "pico/printf.h" int main(){ stdio_init_all(); while(1) { puts_raw("yo"); // Works! puts("ya\n"); // Will work now printf("ye\n"); // Will work now sleep_ms(1000); } }
原理说明
rdimon.specs与-l rdimon会让标准库的puts()/printf()调用ARM Semihosting系统调用,而非默认的空实现。PICO_STDIO_SEMIHOSTING配置Pico SDK将semihosting作为stdio后端,配合stdio_init_all()完成初始化。- 调试器提前启用semihosting功能,确保程序启动后输出能被正确捕获。
内容的提问来源于stack exchange,提问作者Dacoolinus
相关产品推荐
相关产品推荐

