应用/软件映像管理组

应用/软件映像管理组定义了以下命令:

Command ID

命令描述

0

映像状态

1

映像上传

2

文件(保留,Zephyr 不支持)

3

核心列表(保留,Zephyr 不支持)

4

核心加载(保留,Zephyr 不支持)

5

映像擦除

6

槽位信息

Zephyr 中“槽位”和“映像”的概念

“槽位”和“映像”的定义来自 mcuboot:一个“映像”由两个“槽位”组成,分别称为“主槽位”和“副槽位”;应用应当从“主槽位”运行,更新应上传到“副槽位”;mcuboot 负责在启动时交换槽位。这意味着这一对槽位专用于单个可升级应用。在 Zephyr 中这一点会有些令人困惑,因为 DTS 会使用 “slot0_partition” 和 “slot1_partition” 作为专用于单个应用的 fixed-partitions 或 zephyr,mapped-partition 的标签,但又分别将它们命名为 “image-0” 和 “image-1”。

目前 Zephyr 最多支持两个映像,此时的映射关系如下:

映像

槽位标签

槽位名称

1

“slot0_partition” “slot1_partition”

“image-0” “image-1”

2

“slot2_partition” “slot3_partition”

“image-2” “image-3”

State of images

该命令用于设置映像状态,并获取映像及其当前状态的列表。

获取映像状态请求

获取映像状态请求头部字段:

OP

Group ID

Command ID

0

1

0

该命令发送一个空的 CBOR 映射作为数据。

获取映像状态响应

获取映像状态响应头部字段:

OP

Group ID

Command ID

1

1

0

备注

下面的响应定义包含被标记为可选(opt)的“image”字段:当目标应用不支持多个映像时,该字段可以不出现在响应中。当应用支持多个应用映像时,该字段为必需,以便标识所列出的是哪个映像的信息。

响应只包含有效映像的信息;如果某个映像无法被识别为有效,则直接跳过。

成功响应的 CBOR 数据:

{
    (str)"images" : [
        {
            (str,opt)"image"        : (uint)
            (str)"slot"             : (uint)
            (str)"version"          : (str)
            (str,opt*)"hash"        : (byte str)
            (str,opt)"bootable"     : (bool)
            (str,opt)"pending"      : (bool)
            (str,opt)"confirmed"    : (bool)
            (str,opt)"active"       : (bool)
            (str,opt)"permanent"    : (bool)
        }
        ...
    ]
    (str,opt)"splitStatus" : (int)
}

出错时,CBOR 数据的形式如下:

{
    (str)"err" : {
        (str)"group"    : (uint)
        (str)"rc"       : (uint)
    }
}

其中:

“image”

半可选的映像编号;当正在运行的应用只支持一个映像时,该字段不是必需的。

“slot”

“image”内的槽位编号;每个映像有两个槽位:主槽位(正在运行的槽位)= 0,副槽位(用于 DFU 双区)= 1。

“version”

表示映像版本的字符串,由 imgtool 设置。

“hash”

映像头部和主体的 SHA256 哈希值。注意,这与整个文件的 SHA256 不同,它是 MCUboot TLV 区段中包含数据哈希的字段,用于签名验证。该字段为可选,但仅在使用 MCUboot 的串行恢复功能且只有一对映像槽位时为可选;在此配置下可以禁用 Kconfig CONFIG_BOOT_SERIAL_IMG_GRP_HASH 以移除对哈希的支持。应用中的 MCUmgr 必须支持发送哈希。

备注

请参见下方 MCUboot 映像格式文档链接中的 IMAGE_TLV_SHA256。

“bootable”

如果映像设置了 bootable 标志则为 true;该字段为 false 时不必出现。

“pending”

如果映像被设置为下次交换则为 true;该字段为 false 时不必出现。

“confirmed”

如果映像已被确认则为 true;该字段为 false 时不必出现。

“active”

如果映像是当前活动的应用则为 true;该字段为 false 时不必出现。

“permanent”

如果映像在下次启动后保留在主槽位中则为 true;该字段为 false 时不必出现。

“splitStatus”

说明拆分映像的加载器是否与应用部分兼容;Zephyr 不使用此项。

“err” -> “group”

mcumgr_group_t 基于分组的错误码所属的组。仅在使用 SMP 版本 2 且返回错误时出现。

“err” -> “rc”

包含基于分组的错误码的索引。仅在使用 SMP 版本 2 且该值非零(错误状态)时出现。

“rc”

mcumgr_err_t,仅在使用 SMP 版本 1 且该值非零(错误状态)时出现,或在使用 SMP 版本 2 且出现 SMP 错误时出现。

“rsn”

用于说明错误原因的可选字符串;当 rc 为 MGMT_ERR_EUNKNOWN 时尤其有用。

备注

有关映像/槽位工作方式的更多信息,请参阅 MCUboot 文档 https://docs.mcuboot.com/design.html#image-slots ;有关 MCUboot 映像格式的信息,请参阅 MCUboot 文档 https://docs.mcuboot.com/design.html#image-format。

设置映像状态请求

设置映像状态请求头部字段:

OP

Group ID

Command ID

2

1

0

请求的 CBOR 数据:

{
    (str,opt)"hash"     : (byte str)
    (str)"confirm"      : (bool)
}

如果“confirm”为 false 或未提供,则会将具有该“hash”的映像设置为测试状态,这意味着它不会被标记为永久,并且在硬复位后会将之前的应用恢复到主槽位。当“confirm”为 true 时,“hash”为可选,因为会假定当前正在运行的应用为要确认的目标。

设置映像状态响应

该响应采用与 获取映像状态响应 相同的格式

Image upload

映像上传命令用于更新应用映像。

映像上传请求

每上传映像的一个数据块都会发送一次映像上传请求,直到完整的映像被上传到设备。

映像上传请求头部字段:

OP

Group ID

Command ID

2

1

1

请求的 CBOR 数据:

{
    (str,opt)"image"    : (uint)
    (str,opt)"len"      : (uint)
    (str)"off"          : (uint)
    (str,opt)"sha"      : (byte str)
    (str)"data"         : (byte str)
    (str,opt)"upgrade"  : (bool)
}

其中:

“image”

可选的映像编号,完全可以不出现在请求中,此时假定为 0。仅当“off”为 0 时才应出现。

“len”

可选的映像长度。当“off”为 0 时必须出现。

“off”

请求所携带的映像数据块的偏移量。

“sha”

上传内容的 SHA256 哈希值;用于标识一次上传会话(例如允许 MCUmgr 继续中断的会话),以及用于映像校验。这必须是所上传整个映像的完整 SHA256 哈希值;如果无法获得哈希值,则不应包含该字段(此时上传会话续传和映像校验功能将不可用)。仅当“off”为 0 时才应出现。

“data”

要写入到指定偏移处的映像数据。

“upgrade”

可选标志,表示只允许升级,因此如果上传的软件版本不高于设备上已有的版本,映像上传将被拒绝。Zephyr 默认比较主版本号、次版本号和修订号(x.y.z),除非设置了 CONFIG_MCUMGR_GRP_IMG_VERSION_CMP_USE_BUILD_NUMBER,此时还会比较构建号。仅当“off”为 0 时才应出现。

备注

没有表示“data”所携带数据块大小的字段,因为该信息已嵌入“data”字段本身。

备注

服务器可能以“off”为 0 响应一次上传,这种情况可能发生在另一传输通道(或完全在 MCUmgr 之外)启动了上传、设备已重启,或数据包丢失时。如果发生这种情况,客户端必须重新发送它在最初的第一个数据包中发送的所有必需和可选字段,以便服务器重新创建上传状态。如果未包含原有字段,上传将无法继续。

MCUmgr 库使用“sha”字段标记正在进行的更新会话,以便在会话中断时继续,并用于上传校验。如果库收到的请求中“off”等于 0,它会检查其状态中保存的“sha”,如果匹配,则会将应继续使用的偏移量响应给更新客户端应用。如果该哈希值不可用(例如因为文件是流式传输的),则不得提供该字段,此时映像校验和上传会话续传功能将不可用。

映像上传响应

映像上传响应头部字段:

OP

Group ID

Command ID

3

1

1

成功响应的 CBOR 数据:

{
    (str,opt)"off"    : (uint)
    (str,opt)"match"  : (bool)
}

出错时,CBOR 数据的形式如下:

{
    (str)"err" : {
        (str)"group"    : (uint)
        (str)"rc"       : (uint)
    }
}

其中:

“off”

更新中最后一个成功写入字节的偏移量。

“match”

指示上传的数据是否与提供的 SHA256 哈希值成功匹配;仅在启用 CONFIG_IMG_ENABLE_IMAGE_CHECK 时于最后一个数据包中发送。

“err” -> “group”

mcumgr_group_t 基于分组的错误码所属的组。仅在使用 SMP 版本 2 且返回错误时出现。

“err” -> “rc”

包含基于分组的错误码的索引。仅在使用 SMP 版本 2 且该值非零(错误状态)时出现。

“rc”

mcumgr_err_t,仅在使用 SMP 版本 1 且该值非零(错误状态)时出现,或在使用 SMP 版本 2 且出现 SMP 错误时出现。

“rsn”

用于说明错误原因的可选字符串;当 rc 为 MGMT_ERR_EUNKNOWN 时尤其有用。

“off”字段只包含在对成功处理的请求的响应中;如果“rc”为负数,则“off”可能不出现。

Image erase

该命令用于擦除目标设备上的映像槽位。

备注

这是同步命令,意味着在命令完成之前请求发送方不会收到响应,而该过程可能耗时较长。

映像擦除请求

映像擦除请求头部字段:

OP

Group ID

Command ID

2

1

5

请求的 CBOR 数据:

{
    (str,opt)"slot"     : (uint)
}

其中:

“slot”

可选的槽位编号,完全可以不出现在请求中,此时假定为 1。

映像擦除响应

映像擦除响应头部字段:

OP

Group ID

Command ID

3

1

5

成功时,该命令发送一个空的 CBOR 映射作为数据。出错时,CBOR 数据的形式如下:

{
    (str)"err" : {
        (str)"group"    : (uint)
        (str)"rc"       : (uint)
    }
}

其中:

“err” -> “group”

mcumgr_group_t 基于分组的错误码所属的组。仅在使用 SMP 版本 2 且返回错误时出现。

“err” -> “rc”

包含基于分组的错误码的索引。仅在使用 SMP 版本 2 且该值非零(错误状态)时出现。

“rc”

mcumgr_err_t,仅在使用 SMP 版本 1 且该值非零(错误状态)时出现,或在使用 SMP 版本 2 且出现 SMP 错误时出现。

“rsn”

用于说明错误原因的可选字符串;当 rc 为 MGMT_ERR_EUNKNOWN 时尤其有用。

备注

运行 Zephyr 的设备返回的响应中“rc”可能为 MGMT_ERR_EBADSTATE,这意味着副映像已被标记为下次启动使用,因此不能被擦除。

Slot info

该命令用于获取可用槽位的信息。可通过 CONFIG_MCUMGR_GRP_IMG_SLOT_INFO 启用该命令。

槽位信息请求

槽位信息请求头部字段:

OP

Group ID

Command ID

0

1

6

该命令发送一个空的 CBOR 映射作为数据。

槽位信息响应

槽位信息响应头部字段:

OP

Group ID

Command ID

1

1

6

成功响应的 CBOR 数据:

{
    (str)"images" : [
        {
            (str)"image"                        : (uint)
            (str)"slots" : [
                {
                    (str)"slot"                 : (uint)
                    (str)"size"                 : (uint)
                    (str,opt)"upload_image_id"  : (uint)
                }
                ...
            ]
            (str,opt)"max_image_size"           : (uint)
        }
        ...
    ]
}

出错时,CBOR 数据的形式如下:

{
    (str)"err" : {
        (str)"group"    : (uint)
        (str)"rc"       : (uint)
    }
}

其中:

“image”

正在枚举的映像编号。

“slot”

正在枚举的映像内的槽位(注意:该值为 0 或 1,是映像内的槽位编号,而不是物理槽位编号)。

“size”

槽位的大小。

“upload_image_id”

可选字段(仅在启用 CONFIG_MCUMGR_GRP_IMG_DIRECT_UPLOAD 以允许直接上传映像时出现),用于指定外部工具可以用来将映像上传到该槽位的映像 ID。

“max_image_size”

可选字段(仅在启用 CONFIG_MCUMGR_GRP_IMG_TOO_LARGE_SYSBUILD 或 CONFIG_MCUMGR_GRP_IMG_TOO_LARGE_BOOTLOADER_INFO 时出现),用于指定可以上传到该映像编号的应用的最大大小。

“err” -> “group”

mcumgr_group_t 基于分组的错误码所属的组。仅在使用 SMP 版本 2 且返回错误时出现。

“err” -> “rc”

包含基于分组的错误码的索引。仅在使用 SMP 版本 2 且该值非零(错误状态)时出现。

“rc”

mcumgr_err_t,仅在使用 SMP 版本 1 且该值非零(错误状态)时出现,或在使用 SMP 版本 2 且出现 SMP 错误时出现。