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)} 字节已发送"; });
解决方案
调用确认接口触发设备重置
在收到FirmwareUpgradeState.confirm事件时,直接调用updateManager.confirm()方法完成固件确认,触发设备重启切换新固件:else if (event == FirmwareUpgradeState.confirm) { try { await updateManager.confirm(); } catch (e) { print("确认固件失败: $e"); } }修复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, );补充设备重启后的验证逻辑
部分设备在调用confirm后不会主动发送success事件,需要监听蓝牙连接状态,重连后主动查询设备固件版本,确认版本更新即判定升级成功。
内容的提问来源于stack exchange,提问作者Nissaba
相关产品推荐
相关产品推荐

