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

mcumgr_flutter固件传输100%后无法触发success状态求助

问题:mcumgr_flutter固件升级卡在Confirm状态,无法触发Success事件

从mcumgr插件迁移至mcumgr_flutter后,固件传输到100%后,状态流仅收到FirmwareUpgradeState.confirm事件,无后续的success事件触发,找不到updateManager的确认方法来触发设备重置,始终无法进入成功状态。

终端日志

flutter: A 升级启动,使用'Confirm Only'模式,共1个镜像
flutter: W 设备不支持该功能。
flutter: I 因设备不支持,取消'Erase App Settings'操作。
flutter: I 验证响应: {"splitStatus" : 0, "images" : {{"version" : "0.0.10.6", "pending" : false, "active" : true, "bootable" : true, "hash" : 0x6A953AFF74B69E7DBFA84BCF4F44C04B907A5C417450152331D64F4A946E8B68, "permanent" : false, "slot" : 0, "confirmed" : true}, {"slot" : 1, "permanent" : false, "version" : "0.0.10.6", "confirmed" : false, "hash" : 0x6A953AFF74B69E7DBFA84BCF4F44C04B907A5C417450152331D64F4A946E8B68, "pending" : false, "active" : false, "bootable" : true}}}
flutter: E 请求(组: image, 序列号: 1)失败: MTU不足: 249.)
flutter: I MTU已设置为249
.....
.....
flutter: Confirm

代码实现

final managerFactory = FirmwareUpdateManagerFactory();
// `deviceId` 是设备的MAC地址(Android)或UUID(iOS)字符串
final updateManager = await managerFactory.getUpdateManager(_deviceID!);
// 使用manager前先调用`setup`
final updateStream = updateManager.setup();

Uint8List content = loadFirmware();

// `firmware` 是数据与索引配对的列表
final List<Tuple2<int, Uint8List>> firmwareScheme = [Tuple2(1, content)];
const configuration = FirmwareUpgradeConfiguration(
  estimatedSwapTime: Duration(seconds: 0),
  byteAlignment: ImageUploadAlignment.fourByte,
  eraseAppSettings: true,
  pipelineDepth: 1,
);
// `configuration` 是可选参数,若不提供则使用默认值

final logger = updateManager.logger;
_loggerSub = logger.logMessageStream.listen((event) {
  for (var msg in event) {
    print("${msg.level.shortName} ${msg.message}");
  }
});

updateManager.update(firmwareScheme, configuration: configuration).catchError((e) {
  AlertDialog alert = const AlertDialog(
    title: Text('固件上传错误'),
    content: Text('上传固件时发生错误,请手动重置设备'),
  );
  showDialog(
      context: locator.get<NavigationService>().navigatorKey.currentContext!,
      builder: (ctx) {
        return alert;
      });
  return e;
});

_updateStateStreamSub = updateManager.updateStateStream?.listen((event) async {
  print(event);
  if (event == FirmwareUpgradeState.success) {
  // 从未被调用
    await _updateStateStreamSub?.cancel();
    await _progressStreamSub?.cancel();
    await connection?.cancel();
  } else if (event == FirmwareUpgradeState.confirm) {
     // 这里该做什么?
  } else {}
});

_progressStreamSub = updateManager.progressStream.listen((event) {
  locator.get<BikeViewModel>().firmwareProgres = event.bytesSent / event.imageSize * 100;
  locator.get<BikeViewModel>().firmwareProgressUpdate =
      "${event.bytesSent.fileSize(round: 1)} / ${event.imageSize.fileSize(round: 1)} 字节已发送";
});

解决方案
  1. 调用确认接口触发设备重置
    在收到FirmwareUpgradeState.confirm事件时,直接调用updateManager.confirm()方法完成固件确认,触发设备重启切换新固件:

    else if (event == FirmwareUpgradeState.confirm) {
      try {
        await updateManager.confirm();
      } catch (e) {
        print("确认固件失败: $e");
      }
    }
    
  2. 修复MTU与配置不兼容问题
    日志显示存在MTU不足错误,虽然已自动调整,但建议手动设置更大的MTU值(如512),同时关闭设备不支持的eraseAppSettings选项:

    // 获取manager后手动设置MTU
    await updateManager.setMtu(512);
    
    // 调整升级配置
    const configuration = FirmwareUpgradeConfiguration(
      estimatedSwapTime: Duration(seconds: 10), // 设为设备实际重启时长
      byteAlignment: ImageUploadAlignment.fourByte,
      eraseAppSettings: false,
      pipelineDepth: 1,
    );
    
  3. 补充设备重启后的验证逻辑
    部分设备在调用confirm后不会主动发送success事件,需要监听蓝牙连接状态,重连后主动查询设备固件版本,确认版本更新即判定升级成功。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 00:37:10