SMP协议原理与分析

分析依据:zephyrproject-rtos/mcumgr(原 mcu-tools/mcumgr,2026-08 版本)源码与
protocol.mdtransport/smp-console.mdtransport/smp-bluetooth.md,以及
mcu-tools/mcubootboot/boot_serial 实现。
适用对象:MCUboot 串口恢复(serial recovery)、mcumgr / newtmgr 设备管理、Zephyr/Mynewt 的 mcumgr 子系统。


1. 概述与定位

SMP(Simple Management Protocol)是 mcumgr 的设备管理协议,前身是 Apache Mynewt 的
NMP(Newt Manager Protocol)。它定义了一套命令-响应式的管理通道,命令包括:
镜像管理(列出/上传/擦除/复位)、系统信息、统计、配置、日志、崩溃转储、文件系统等。

  • 与 MCUboot 的关系:MCUboot 本身不做传输,它的官方配套是 mcumgr;MCUboot 的
    串口恢复模式boot_serial)实现了 SMP 的一个最小子集(镜像 state/upload +
    reset/echo),上位机用 mcumgrnewtmgr 命令即可通过串口给 bootloader 传固件。
  • 设计目标:二进制头(固定 8 字节)+ CBOR 载荷,极小、可移植、支持多传输
    (串口 / BLE / UDP),对 flash/内存占用友好(典型串口场景只需几 KB)。
  • 传输与校验分离:SMP 头里的 len 用于分帧重组,串口传输另有 CRC16;
    镜像是否可信由 MCUboot 安装时的 SHA-256 + 签名校验 决定,SMP 本身不做加密。

2. 报文格式(8 字节头 + CBOR 载荷)

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | OP | 保留(5bit)|    Flags    |          Length(16bit)         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         Group ID(16bit)      |   Sequence(8bit) | Command ID(8bit)|
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                         CBOR 载荷(Length 字节)                |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

对应源码结构(mgmt/mgmt.h):

#define MGMT_HDR_SIZE 8

struct mgmt_hdr {
    uint8_t  nh_op:3;     /* 操作码,低 3 位 */
    uint8_t  _res1:5;     /* 保留 */
    uint8_t  nh_flags;    /* 标志,当前恒为 0 */
    uint16_t nh_len;      /* 载荷长度(CBOR 部分),大端 */
    uint16_t nh_group;    /* 命令组 ID,大端 */
    uint8_t  nh_seq;      /* 序号,响应原样回显 */
    uint8_t  nh_id;       /* 组内命令 ID */
};

要点:

  • 大端序(>8bit 字段),头固定 8 字节
  • nh_len 只统计 CBOR 载荷,不含 8 字节头。
  • 响应头 = 请求头基础上 op + 1seq 原样回显、len 填响应载荷长度。

操作码(nh_op

名称方向
0MGMT_OP_READ请求:读取
1MGMT_OP_READ_RSP响应:读结果
2MGMT_OP_WRITE请求:写入/执行
3MGMT_OP_WRITE_RSP响应:写结果

命令组(nh_group

组 ID名称用途
0MGMT_GROUP_ID_OS系统:echo、复位、任务统计等
1MGMT_GROUP_ID_IMAGE镜像管理(OTA 核心)
2MGMT_GROUP_ID_STAT统计
3MGMT_GROUP_ID_CONFIG配置
4MGMT_GROUP_ID_LOG日志
5MGMT_GROUP_ID_CRASH崩溃转储
6MGMT_GROUP_ID_SPLIT双核 split 镜像
7MGMT_GROUP_ID_RUN运行时命令
8MGMT_GROUP_ID_FS文件系统
9MGMT_GROUP_ID_SHELLshell
64+MGMT_GROUP_ID_PERUSER用户自定义组

组内命令(nh_id

OS 组(cmd/os_mgmt):

ID名称说明
0OS_MGMT_ID_ECHO回显
1OS_MGMT_ID_CONS_ECHO_CTRL控制台回显开关
2OS_MGMT_ID_TASKSTAT任务统计
3OS_MGMT_ID_MPSTAT内存池统计
4OS_MGMT_ID_DATETIME_STR日期时间
5OS_MGMT_ID_RESET复位设备

IMAGE 组(cmd/img_mgmt):

ID名称说明
0IMG_MGMT_ID_STATE查询镜像列表/状态,或 test/confirm
1IMG_MGMT_ID_UPLOAD上传镜像分片(OTA 关键命令)
2IMG_MGMT_ID_FILE上传文件
3IMG_MGMT_ID_CORELIST列出崩溃转储
4IMG_MGMT_ID_CORELOAD读取崩溃转储
5IMG_MGMT_ID_ERASE擦除镜像

错误码(响应 CBOR 中的 rc 字段)

名称含义
0MGMT_ERR_EOK成功
1MGMT_ERR_EUNKNOWN未知错误
2MGMT_ERR_ENOMEM内存不足
3MGMT_ERR_EINVAL参数非法
4MGMT_ERR_ETIMEOUT超时
5MGMT_ERR_ENOENT不存在
6MGMT_ERR_EBADSTATE状态不允许
7MGMT_ERR_EMSGSIZE响应过大
8MGMT_ERR_ENOTSUP不支持
9MGMT_ERR_ECORRUPT数据损坏
256MGMT_ERR_EPERUSER用户自定义起始

多请求拼接

一个 SMP 报文可以拼接多个请求,每个请求头 + 载荷连续存放,每个请求起始偏移必须是
4 的倍数
(不足补填充字节)。服务器按顺序处理,每个请求单独回一帧;一旦某个请求出错,
剩余请求不再处理。


3. CBOR 载荷

载荷是 CBOR(RFC 7049) 编码的键值映射。选 CBOR 是因为它比 JSON 紧凑、编码解码
代码量小(tinycbor),且天然支持二进制数据。

  • 键通常是文本字符串,如 "images""off""len""data""rc""hash"
  • 数组/映射常用不定长编码(首字节 0x9f / 0xbf,结束符 0xff)。
  • 二进制数据(镜像分片)用 base64 编码成字符串放入 "data" 字段(保持文本帧兼容)。

例:image list 响应(组=1,id=0,op=READ_RSP)

抓包字节(来自 mcumgr protocol.md):

01 01 00 7b 00 01 00 00  bf 66 69 6d 61 67 65 73 9f bf 64 73 6c 6f 74 00
67 76 65 72 73 69 6f 6e 65 30 2e 33 2e 30 64 68 61 73 68 58 20 d2 4c b3
05 13 54 17 2b b5 10 9f 9c b4 ae 78 61 d9 6d 6a fd fc 46 db 48 2c eb 2d
34 a8 a7 8e d0 68 62 6f 6f 74 61 62 6c 65 f5 67 70 65 6e 64 69 6e 67 f4
69 63 6f 6e 66 69 72 6d 65 64 f5 66 61 63 74 69 76 65 f5 ff ff 6b 73 70
6c 69 74 53 74 61 74 75 73 00 ff

解析:

  • 头:01(op=READ_RSP) 01(flags) 00 7b(len=123) 00 01(group=IMAGE) 00(seq) 00(id=STATE)
  • CBOR:bf 不定长 map → "images" → 不定长数组 → 每项 {slot, version, hash(32B), bootable, pending, confirmed, active}"splitStatus":0
  • 这是 MCUboot / mcumgr 判断“当前固件、待更新固件”的标准查询。

4. 传输层

4.1 串口(console / MCUboot serial recovery)—— 重点

帧格式(transport/smp-console.md + MCUboot boot_serial.c):

首帧:
  0x06 0x09            <- 帧起始标记(SHELL_NLIP_PKT_START1/2)
  base64( <16bit 包长度> <8字节SMP头> <CBOR载荷> <16bit CRC16> )
  0x0A                 <- 换行结束
续帧(长度超过 127 字节时):
  0x04 0x14
  base64( <续传数据> <16bit CRC16>(若为最后一帧) )
  0x0A
  • 包长度:大端 16bit,值 = 未编码的 body + 2 字节 CRC 的总长度。
  • CRC16:多项式 0x1021、初值 0、无反射(CRC16-CCITT 变体),覆盖“未编码的
    SMP 头 + 载荷”,以大端附加在末尾;接收端对“长度字段之后、含 CRC 的整段”再算一次,
    结果为 0 即通过(MCUboot 的校验方式)。
  • 分帧:整帧(含头、CRC、换行)不超过 127 字节,超长拆成多个续帧。
  • base64:整帧(除 06 09 / 0A 外)做 base64,使协议对任意终端/中转都安全。
  • MCUboot 的 boot_serial单帧简化实现:直接发 06 09 + base64(整包) + \n\r
    接收缓冲 512 字节,不做续帧;帧内校验逻辑与上述一致。

4.2 UDP

  • 端口 133(newtmgr/mcumgr 约定),每个 UDP 数据报 = 8 字节 SMP 头 + CBOR 载荷,
    无额外帧格式,请求-响应一对一。
  • 校验:UDP 数据报自带 16bit 校验和;链路可靠性靠超时重发(应用层或 UDP 之上)。
  • 典型用法:Zephyr 的 smp_udp 传输 + lwIP/原生 IP 栈,上位机 mcumgr -c udp

4.3 BLE

  • GATT 服务 UUID:8D53DC1D-1DB7-4CD3-868B-8A527460AA84
  • 特征 UUID:DA2E7828-FBCE-4E01-AE9E-261174997C48
  • 请求用 Write / WriteWithoutResponse,响应用同一特征的 Notification
  • 大报文直接按 GATT 命令切片,无额外分帧(BLE 保证有序)。
  • 校验:链路层 CRC + 可选配对加密(应用层不额外加 CRC)。
传输分帧校验典型延迟/吞吐
串口 console06 09 / 04 14 + base64 + 127B 分帧CRC16-CCITT115200bps,几十 KB/s
MCUboot serial recovery06 09 + base64 单帧CRC16-CCITT同上
UDP无(一报一帧)UDP 校验和 + 重发取决于网络
BLEGATT 切片链路层 + 可选加密取决于 MTU/连接间隔

5. 固件上传流程(image upload,组 1 / id 1)

上传请求是 WRITE(op=2)命令,CBOR 载荷:

{
  "off"  : <本片在镜像中的偏移>,
  "len"  : <镜像总长度>,        // 仅 off==0 的首片携带
  "data" : <base64 编码的本片二进制>,
  "sha"  : <base64 编码的镜像 SHA-256>,   // MCUboot serial recovery 可选校验
}

服务器响应(WRITE_RSP,op=3):

{ "off" : <已接收到的下一偏移>, "rc" : 0 }

流程:

  1. 上位机按 MTU(如 512B/片)把签名固件分片,逐片发 image upload(off 递增)。
  2. 每片回 off(= 收到的累计偏移);上位机用返回值推进,实现流控与续传
  3. 首片带 len,服务器据此知道总大小;可选带 sha 做整镜像摘要校验。
  4. 最后一片的 off + 片长 == len 时上传完成,服务器落盘到 UPDATE 分区。
  5. 上位机发 image state(WRITE)携带 "confirm":true(或 "test":true)激活镜像;
    再发 OS 组 reset(组 0 / id 5)让设备重启。
  6. 重启后 MCUboot 对 UPDATE 分区做 SHA-256 完整性 + 签名认证,通过则 swap/安装并
    按需回滚,实现“确认成功后才固化”。

MCUboot serial recovery 只实现了这个流程的最小子集(state、upload、reset、echo),
其余组返回空响应;CDDL 定义见 boot/boot_serial/src/serial_recovery.cddl


6. 报文实例(手工构造,便于抓包对照)

6.1 image list 请求 → 串口帧

请求头:op=READ(0)、flags=0、len=0、group=1(IMAGE)、seq=0、id=0(STATE)

SMP 报文 : 00 00 00 00 00 01 00 00
包长度   : 0x000A(8 头 + 2 CRC)
CRC16   : D8A8
串口帧   : 06 09 41 41 6F 41 41 41 41 41 41 41 45 41 41 4E 69 6F 0A
        = 06 09 + base64("00 0A 00 00 00 00 00 01 00 00 D8 A8") + 0A
        = 06 09 + "AAoAAAAAAAEAANio" + 0A

6.2 image upload 首片请求(off=0,len=16,16 字节数据)

SMP 头   : 02 00 00 2A 00 01 00 01   (op=WRITE, len=0x2A, group=1, seq=0, id=UPLOAD)
CBOR     : A3 63 6F 66 66 00 63 6C 65 6E 10 64 64 61 74 61 4C 18
           41 41 45 43 41 77 51 46 42 67 63 49 43 51 6F 4C 44 41 30 4F 44 77 3D 3D
          = { "off":0, "len":16, "data":bstr("AAECAwQFBgcICQoLDA0ODw==") }
包长度   : 0x0034(头 8 + CBOR 42 + CRC 2)
CRC16   : 9AA5

解码验证:

  • A3 = map(3);63 6F 66 66 = 文本(3) “off”;00 = 0
  • 63 6C 65 6E = 文本(3) “len”;10 = 16
  • 64 64 61 74 61 = 文本(4) “data”;4C 18 = 字节串(24),
    解码 AAECAwQFBgcICQoLDA0ODw==00 01 02 ... 0F

7. 校验与安全机制总结

机制作用
串口传输层06 09 帧同步 + base64 + CRC16-CCITT检错/防误码,重发靠上位机
UDP 传输层UDP 16bit 校验和 + 应用超时重发检错
BLE 传输层链路 CRC + 可选配对加密检错/可选机密性
SMP 应用层len/off 校验、rc 错误码逻辑正确性
镜像层(MCUboot)SHA-256 完整性 + ECDSA/Ed25519/RSA 签名最终信任根

注意:SMP 本身没有加密和认证,它假定传输链路可信(串口物理可信、UDP 走可信网络、
BLE 可加配对)。真正的安全边界在 MCUboot 的镜像签名校验——即使传输被篡改,签名验证
也会失败。


8. 调试与工具

  • 上位机:mcumgrapache/mynewt-mcumgr-cli)或旧版 newtmgr
    • 串口:mcumgr -c serial -l DEBUG image list
    • UDP:mcumgr -c udp image upload -n <image>
    • -l DEBUG 可看到请求/响应头字段与原始字节(如 protocol.md 中的抓包输出)。
  • 抓包:串口用带时间戳的串口记录/逻辑分析仪;UDP 用 Wireshark 过滤 udp.port==133
  • 参考实现源码:
    • mcumgr-master\protocol.md —— 协议笔记与抓包
    • mcumgr-master\mgmt\include\mgmt\mgmt.h —— 头结构、组、错误码
    • mcumgr-master\smp\src\smp.c —— 请求处理/多请求拼接
    • mcumgr-master\transport\smp-console.mdsmp-bluetooth.md —— 传输规范
    • ...\mcumgr-master\cmd\img_mgmt —— 镜像上传实现
    • mcuboot-master\boot\boot_serial\src\boot_serial.c —— MCUboot 串口恢复(帧收发 + CRC)

内容概要:本文研究了一种针对四机并联孤岛微电网的协同控制策略,通过集成DoS攻击模拟、分布式二次控制、下垂控制事件触发式负荷控制,旨在实现微电网在遭受网络安全威胁等异常工况下的电压频率恢复以及有功/无功功率的精确共享分配。基于Simulink平台构建了完整的微电网仿真系统,包含多台分布式发电单元(DG),采用下垂控制实现无需通信的功率自主分配,并引入分布式二次控制以补偿由下垂特性引起的电压和频率偏差,从而提升电能质量。为进一步降低通信负担并提高系统效率,设计了事件触发机制,仅在必要时刻进行信息交互。研究重点在于多时间尺度下的协同控制架构设计,全面验证了该策略在正常运行遭受DoS攻击等扰动情形下的稳定性、鲁棒性恢复能力。; 适合人群:具备电力系统、自动控制理论基础,熟悉Simulink/Matlab仿真工具,从事微电网、分布式能源、智能电网及相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①研究孤岛微电网中电压频率恢复功率均分的多时间尺度协同控制机制;②分析DoS网络攻击对微电网控制性能的影响及其应对策略;③掌握事件触发控制在减少通信开销中的实际应用方法;④复现并拓展具备网络安全防护能力的高级微电网控制算法仿真模型。; 阅读建议:此资源以Simulink仿真实现为核心,建议读者结合现代控制理论网络安全知识,逐步搭建系统模型,重点关注控制器参数整定、事件触发阈值设计及DoS攻击注入方式,通过对比实验深入理解控制策略的有效性鲁棒性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值