Flutter设备管理插件mcumgr_flutter的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter设备管理插件mcumgr_flutter的使用

1. 概述

nRF Connect Device Manager 是一个基于 Flutter 的插件,用于管理和更新设备固件。该插件基于 Nordic Semiconductor 提供的 Android 和 iOS 版本的 nRF Connect Device Manager 库开发。它支持以下平台:

  • Android: 最低 API 级别为 19
  • iOS: 最低系统版本为 13.0

2. 快速上手

2.1 创建管理器

要创建一个 FirmwareUpdateManager 实例,可以使用 UpdateManagerFactory。你需要提供设备的唯一标识符(在 Android 上是 MAC 地址,在 iOS 上是 UUID)。

final managerFactory = FirmwareUpdateManagerFactory();
// `deviceId` 是设备的 MAC 地址(Android)或 UUID(iOS)
final updateManager = await managerFactory.getUpdateManager(deviceId);
// 在使用管理器之前调用 `setup`
final updateStream = updateManager.setup();
2.2 更新设备

你可以通过 update 方法来更新设备固件。你需要提供一个包含固件图像的 List<Image>,并可以选择性地提供 FirmwareUpgradeConfiguration 来配置更新过程。

// `firmwareImages` 是一个包含固件图像的列表
List<Image> firmwareImages = [];
for (final file in manifest.files) {
  final image = Image(
    image: file.image,
    data: firmwareFileData,
  );
  firmwareImages.add(image);
}

final configuration = const FirmwareUpgradeConfiguration(
  estimatedSwapTime: const Duration(seconds: 0),
  byteAlignment: ImageUploadAlignment.fourByte,
  eraseAppSettings: true,
  pipelineDepth: 1,
);

// 开始更新
updateManager.update(firmwareImages, configuration: configuration);

你也可以使用 updateWithImageData 方法来更新单个固件图像:

await updateManager.updateWithImageData(image: fwImage!);

提示: updateupdateWithImageData 方法是异步的,但它们不会返回更新结果。它们只会启动更新过程。要监听更新进度,请订阅 updateStreamprogressStream

2.3 监听更新

为了监听更新状态和进度,你可以订阅 updateStreamprogressStream

// 监听更新状态
updateManager.updateStateStream?.listen((event) {
  if (event == FirmwareUpgradeState.success) {
    print("更新成功");
  } else {
    print(event);
  }
});

// 监听更新进度
updateManager.progressStream.listen((event) {
  print("${event.bytesSent} / ${event.imageSize} 字节已发送");
});
2.4 控制更新

你可以使用 FirmwareUpdateManager 提供的方法来控制更新过程:

/// 暂停更新
Future<void> pause();

/// 恢复更新
Future<void> resume();

/// 取消更新
Future<void> cancel();

/// 检查更新是否正在进行
Future<bool> inProgress();

/// 检查更新是否已暂停
Future<bool> isPaused();
2.5 结束管理器

更新完成后,记得调用 kill 方法来结束管理器,以避免内存泄漏和其他问题:

updateManager.kill();

3. 日志管理

3.1 监听日志

你可以订阅 logger.logMessageStream 来监听日志消息,并根据需要过滤日志级别:

updateManager.logger.logMessageStream
  .where((log) => log.level.rawValue > 1) // 过滤掉调试信息
  .listen((log) {
    print(log.message);
  });
3.2 读取设备日志

你可以使用 readLogs 方法从设备读取日志:

List<McuLogMessage> logs = await updateManager.logger.readLogs(clearLogs: false);

4. 完整示例 Demo

下面是一个完整的示例应用,展示了如何使用 mcumgr_flutter 插件来选择固件、选择设备并进行固件更新。这个示例使用了 Stepper 组件来引导用户完成更新流程。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => FirmwareUpdateRequestProvider(),
      builder: (context, child) => _materialApp(context),
    );
  }

  MaterialApp _materialApp(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('MCU Manager'),
        ),
        body: _body(context),
      ),
    );
  }

  Widget _body(BuildContext context) {
    final provider = context.watch<FirmwareUpdateRequestProvider>();
    return Stepper(
      currentStep: provider.currentStep,
      onStepContinue: () {
        setState(() {
          provider.nextStep();
        });
      },
      onStepCancel: () {
        setState(() {
          provider.previousStep();
        });
      },
      controlsBuilder: _controlBuilder,
      steps: [
        Step(
          title: Text('选择固件'),
          content: Center(child: FirmwareSelect()),
          isActive: provider.currentStep == 0,
        ),
        Step(
          title: Text('选择设备'),
          content: Center(child: PeripheralSelect()),
          isActive: provider.currentStep == 1,
        ),
        Step(
          title: Text('更新'),
          content: Text('更新'),
          isActive: provider.currentStep == 2,
        ),
      ],
    );
  }

  Widget _controlBuilder(BuildContext context, ControlsDetails details) {
    final provider = context.watch<FirmwareUpdateRequestProvider>();
    FirmwareUpdateRequest parameters = provider.updateParameters;
    switch (provider.currentStep) {
      case 0:
        if (parameters.firmware == null) {
          return Container();
        }
        return Row(
          children: [
            ElevatedButton(
              onPressed: details.onStepContinue,
              child: Text('下一步'),
            ),
          ],
        );
      case 1:
        if (parameters.peripheral == null) {
          return Container();
        }
        return Row(
          children: [
            TextButton(
              onPressed: details.onStepCancel,
              child: Text('返回'),
            ),
            ElevatedButton(
              onPressed: details.onStepContinue,
              child: Text('下一步'),
            ),
          ],
        );
      case 2:
        return BlocProvider(
          create: (context) => UpdateBloc(firmwareUpdateRequest: parameters),
          child: UpdateStepView(),
        );
      default:
        throw Exception('未知步骤');
    }
  }
}

// 假设这些类和组件已经定义好
class FirmwareUpdateRequestProvider with ChangeNotifier {
  int _currentStep = 0;
  FirmwareUpdateRequest _updateParameters = FirmwareUpdateRequest();

  int get currentStep => _currentStep;
  FirmwareUpdateRequest get updateParameters => _updateParameters;

  void nextStep() {
    _currentStep++;
    notifyListeners();
  }

  void previousStep() {
    _currentStep--;
    notifyListeners();
  }

  void setFirmware(Firmware firmware) {
    _updateParameters = _updateParameters.copyWith(firmware: firmware);
    notifyListeners();
  }

  void setPeripheral(Peripheral peripheral) {
    _updateParameters = _updateParameters.copyWith(peripheral: peripheral);
    notifyListeners();
  }
}

class FirmwareUpdateRequest {
  Firmware? firmware;
  Peripheral? peripheral;

  FirmwareUpdateRequest copyWith({
    Firmware? firmware,
    Peripheral? peripheral,
  }) {
    return FirmwareUpdateRequest()
      ..firmware = firmware ?? this.firmware
      ..peripheral = peripheral ?? this.peripheral;
  }
}

class Firmware {
  // 固件相关属性
}

class Peripheral {
  // 设备相关属性
}

class FirmwareSelect extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('选择固件文件'),
        // 这里可以添加文件选择器或其他方式选择固件
      ],
    );
  }
}

class PeripheralSelect extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('选择要更新的设备'),
        // 这里可以添加设备选择器或其他方式选择设备
      ],
    );
  }
}

class UpdateStepView extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('正在更新...'),
        // 这里可以显示更新进度条或其他更新状态
      ],
    );
  }
}

更多关于Flutter设备管理插件mcumgr_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter设备管理插件mcumgr_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter项目中集成和使用mcumgr_flutter插件进行设备管理,需要几个步骤来确保插件被正确引入并使用。mcumgr是一个用于管理MCU(微控制器单元)设备的工具集,而mcumgr_flutter则是其Flutter插件版本。

以下是一个基本的示例,展示如何在Flutter项目中集成和使用mcumgr_flutter插件:

1. 添加依赖

首先,在你的Flutter项目的pubspec.yaml文件中添加mcumgr_flutter依赖:

dependencies:
  flutter:
    sdk: flutter
  mcumgr_flutter: ^最新版本号 # 替换为实际的最新版本号

然后运行flutter pub get来安装依赖。

2. 导入插件

在你需要使用mcumgr_flutter的Dart文件中导入插件:

import 'package:mcumgr_flutter/mcumgr_flutter.dart';

3. 初始化和使用

接下来,你可以使用McumgrFlutter类来初始化并管理MCU设备。以下是一个简单的示例,展示了如何连接到MCU设备并获取其信息:

import 'package:flutter/material.dart';
import 'package:mcumgr_flutter/mcumgr_flutter.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  McumgrFlutter? _mcumgr;
  String? _deviceInfo;

  @override
  void initState() {
    super.initState();
    initMcumgr();
  }

  void initMcumgr() async {
    // 假设你已经有了MCU的连接信息,比如IP地址和端口
    String deviceAddress = "192.168.1.100";
    int port = 8080;

    _mcumgr = McumgrFlutter(address: deviceAddress, port: port);

    try {
      // 连接到MCU设备
      await _mcumgr?.connect();

      // 获取设备信息
      var info = await _mcumgr?.getDeviceInfo();
      setState(() {
        _deviceInfo = info?.toString();
      });
    } catch (e) {
      print("Error connecting to MCU: $e");
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('MCU Manager'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('Device Info:'),
              Text(_deviceInfo ?? 'Loading...'),
            ],
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    _mcumgr?.disconnect();
    super.dispose();
  }
}

注意事项

  1. 权限:确保你的应用有必要的网络权限,特别是如果你正在尝试通过TCP/IP连接到MCU设备。
  2. 错误处理:在实际应用中,你应该添加更多的错误处理逻辑,以处理可能发生的各种异常情况。
  3. 依赖版本:始终检查并使用mcumgr_flutter的最新版本,以确保获得最新的功能和修复。

这个示例展示了基本的设备连接和信息获取。mcumgr_flutter插件还提供了更多的功能,如固件更新、资源管理、日志获取等,你可以根据需求查阅插件的官方文档或源代码,以了解更多详细用法。

回到顶部