树莓派Pico调用f_write导致程序冻结的原因排查求助
问题排查与修复建议
你的问题核心是Core1执行f_write时程序冻结,且无错误提示,优先从以下几个方向排查:
1. 核心栈溢出(最可能原因)
Core1默认栈大小仅16KB左右,但你定义的uint16_t data_buffer[32000]占用了64KB内存,直接超出栈的容纳范围,会导致内存越界、程序崩溃。
修复方案:
- 改用动态内存分配,在堆上创建缓冲区:
uint16_t *data_buffer = malloc(buf_size * sizeof(uint16_t)); if (!data_buffer) { // 处理内存分配失败,比如提示LCD clrLCD(); setString("!MEM"); brk = true; } // 程序结束后释放内存 free(data_buffer); - 或者减小
buf_size到8000(16KB)以内,适配默认栈大小。 - 进阶:修改Core1的栈大小,在项目的
CMakeLists.txt中添加:pico_set_core1_stack_size(your_project_name 65536) # 设置为64KB
2. 类型不匹配问题
FatFS的f_write第四个参数要求是UINT*类型,你代码中用了uint bytes_read,虽然部分平台uint和UINT等价,但可能存在兼容性问题,导致写入异常。
修复方案:
将bytes_read的类型改为UINT:
UINT bytes_read = 0;
3. FIFO阻塞与同步问题
当Core1卡在f_write时,Core0持续通过FIFO发送ADC数据,会导致FIFO填满后Core0也进入阻塞状态,表现为整个程序冻结。可以在Core0发送数据前检查FIFO是否有剩余空间:
修复方案:
在Core0的发送逻辑中添加:
while (!multicore_fifo_wready()) { // 等待FIFO有空间再发送 tight_loop_contents(); } multicore_fifo_push_blocking(sample);
4. 移除不必要的f_sync
每次写入后立即调用f_sync会大幅降低写入速度,且可能触发SD卡的长时间阻塞操作。可以改为在停止录音时再执行一次f_sync,或者每写入N次同步一次:
临时测试方案:
注释掉f_sync(&fil);,看程序是否还冻结,以此排除该函数的影响。
额外排查点
- 检查SD卡的SPI时钟频率是否过高,树莓派Pico的SPI驱动默认可能设置了较高频率,尝试降低到10MHz以内测试。
- 确认
filename_gen生成的文件名格式正确,避免FatFS不支持的字符或路径。
内容的提问来源于stack exchange,提问作者Jake A
相关产品推荐
相关产品推荐

