You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Arduino GIGA Wifi在loop中写入QSPI USB存储时崩溃求助

问题分析与解决

核心原因:局部变量生命周期失效

你在setup()中声明的mbed::BlockDevice、FATFileSystem、MBRBlockDevice均为局部变量,当setup()执行完毕后,这些对象会被自动销毁,但文件系统仍处于挂载状态。后续在loop()中尝试操作文件时,会访问已经失效的对象内存,直接导致系统崩溃。

解决方案步骤

1. 将mbed相关对象改为全局变量

把这些对象的声明移到函数外部,确保它们的生命周期覆盖整个程序运行期间:

// 全局声明,保证对象全程有效
mbed::BlockDevice *raw_qspi;
mbed::FATFileSystem ota("ota");
mbed::MBRBlockDevice *ota_data;

void setup() {
  raw_qspi = mbed::BlockDevice::get_default_instance();
  ota_data = new mbed::MBRBlockDevice(raw_qspi, 2);
  ota.mount(ota_data);

  // 原setup中的写入逻辑,增加空指针检查
  FILE *f = fopen("/ota/settings.txt", "w");
  if (f != NULL) {
    fprintf(f, "%d\n", 0);
    fprintf(f, "%d\n", 0);
    fprintf(f, "%d\n", 1500);
    fprintf(f, "%d\n", 0);
    fprintf(f, "%d\n", 1);
    fprintf(f, "%d\n", 0);
    fprintf(f, "%s\n", machineId);
    fflush(f);
    fclose(f);
  }
  writeLcd("ACME");
}

2. 在loop()中安全执行写入操作

确保每次操作文件前检查文件指针有效性,同时避免重复初始化mbed对象:

void loop() {
  // 假设按钮引脚为buttonPin,根据实际硬件调整
  if (digitalRead(buttonPin) == LOW) {
    delay(50); // 按钮消抖,避免单次按压触发多次操作
    if (digitalRead(buttonPin) == LOW) {
      FILE *f = fopen("/ota/settings.txt", "w");
      if (f != NULL) {
        fprintf(f, "%d\n", 0);
        fprintf(f, "%d\n", 0);
        fprintf(f, "%d\n", 1500);
        fprintf(f, "%d\n", 0);
        fprintf(f, "%d\n", 1);
        fprintf(f, "%d\n", 0);
        fprintf(f, "%s\n", machineId);
        fflush(f);
        fclose(f); // 务必关闭文件,释放资源
        writeLcd("Settings saved");
      } else {
        writeLcd("Open file failed");
      }
      while(digitalRead(buttonPin) == LOW); // 等待按钮释放,防止重复触发
    }
  }
}

3. 额外注意事项

  • 必须做错误检查:所有fopen调用后都要验证返回值,避免空指针访问引发崩溃。
  • 资源管理:每次文件操作完成后必须调用fclose,释放文件描述符;若程序需要长期运行,避免因资源耗尽导致异常。
  • 按钮处理:除了软件延时消抖,也可使用硬件RC电路消抖,提升稳定性。

内容的提问来源于stack exchange,提问作者NiBE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 10:15:31