nRF Connect SDK的OTA,默認都是使用MCUboot(或者帶B0功能),即一個開源的第三方bootloader程序;在這里我們重新理一下nRF Connect SDK OTA的整個流程:
簽名升級的image,注:app_update.bin已經(jīng)是簽過名的image了
上傳image,即把app_update.bin傳送到目標設備
列出image以獲得image的hash值
測試image,即寫magic字段,以讓MCUboot進入DFU模式復位設備,以重新進入MCUboot,從而MCUboot進入DFU模式,并執(zhí)行相應的swap操作,并完成兩個slot image之間的交換或者拷貝動作
Confirm image,即新image啟動成功后,對其image_ok字段進行置1操作
按照前面所述,為了實現(xiàn)OTA的功能,需要DFU協(xié)議來將新的image傳輸?shù)侥愕牡诙謪^(qū)里面即secondary slot,nRF Connect SDK里面最重要的DFU協(xié)議就是SMP——Simple Management Protocol,此協(xié)議用來管理整個升級流程,包括設備的分區(qū)狀態(tài),設備的復位,設備MCUboot交換文件的時候是test還是confirm等。
SMP協(xié)議是應用層協(xié)議,與鏈路層不是一個概念,或者說應用層協(xié)議是建立在鏈路層的基礎上的,所以物理通道上,最后我們可以使用多種方式,USB, UART,BLE,或者TCP UDP都是可以的。
本文重點講解的是SMP協(xié)議,以及它的數(shù)據(jù)格式,后面對升級過程中對每條指令進行講解。在講解SMP數(shù)據(jù)格式之前,我們先解說一下CBOR數(shù)據(jù)格式,因為SMP的payload里面的所有數(shù)據(jù)都必須使用這個數(shù)據(jù)格式。
一、CBOR格式和數(shù)據(jù)解讀
CBOR是一種數(shù)據(jù)格式,其設計目標包括極小的代碼大小、相當小的消息大小以及無需版本協(xié)商的可擴展性的可能性。該表示必須能夠明確地編碼互聯(lián)網(wǎng)標準中使用的最常見的數(shù)據(jù)格式。
編碼器或解碼器的代碼必須能夠緊湊,以便支持內(nèi)存、處理器能力和指令集非常有限的系統(tǒng)
數(shù)據(jù)必須能夠在沒有模式描述的情況下被解碼
序列化必須相當緊湊
該格式必須適用于受限節(jié)點和大容量應用程序
該格式必須支持所有 JSON 數(shù)據(jù)類型以便與 JSON 相互轉(zhuǎn)換
格式必須是可擴展的
單個 CBOR ,即一個數(shù)據(jù)項的結(jié)構(gòu)可以包含零個、一個或多個嵌套數(shù)據(jù)項,在基本(未擴展)通用數(shù)據(jù)模型中,數(shù)據(jù)項是以下之一:
0-正數(shù)
1-負數(shù)
2-字節(jié)串(byte string)
3-UTF-8字符串(text string)
4-數(shù)組
5-map(又稱字典)
6-tag(這個用得少)
7-浮點數(shù)或者特殊類型,其中特殊類型將short count 20–23定義為 false, true, null和undefined
CBOR包含數(shù)據(jù)格式眾多,在nRF Connect SDK里面使用最多的是下面幾種格式:
整數(shù)
文本字符串
數(shù)組
和字典
每個編碼數(shù)據(jù)項的初始字節(jié)包含有關主要類型的信息(高位 3 位,用來表示數(shù)據(jù)項)和附加信息(低位 5 位表示數(shù)據(jù)值),少數(shù)編碼例外:
小于 24:參數(shù)的值是附加信息的值。
24、25、26 或 27:參數(shù)的值按網(wǎng)絡字節(jié)順序分別保存在以下 1、2、4 或 8 個字節(jié)中。對于主類型 7 和附加信息值 25、26、27,這些字節(jié)不用作整數(shù)參數(shù),而是用作浮點值。
28、29、30:這些值被保留以供將來添加到 CBOR 格式中。在當前版本的 CBOR 中,編碼項的格式不正確。
31:沒有導出任何參數(shù)值。如果主要類型為 0、1 或 6,則編碼項的格式不正確。對于主要類型2至5,該項的長度是不定長的,對于主要類型7,該字節(jié)根本不構(gòu)成數(shù)據(jù)項,而是終止一個不定長項。
CBOR 解碼器實現(xiàn)可以基于包含初始字節(jié)的所有 256 個定義值的跳轉(zhuǎn)表,我們經(jīng)常使用的表格如下:
| Byte | Value | 
|---|---|
| 0x00….0x17 | 無符號整數(shù) 0x00….0x17 (0…...23) | 
| 0x18 | 無符號整數(shù)(后面是一字節(jié) uint8_t) | 
| 0x19 | 無符號整數(shù)(后面是兩字節(jié) uint16_t) | 
| 0x1a | 無符號整數(shù)(后面是四字節(jié) uint32_t) | 
| 0x1b | 無符號整數(shù)(后面是八字節(jié) uint64_t) | 
| 0x20….0x37 | 負整數(shù) -1-0x00….1-0x17 (-1….24) | 
| 0x38 | 負整數(shù)-1-n(后面是 n 的一字節(jié) uint8_t) | 
| 0x39 | 負整數(shù) -1-n (后面是 n 的兩字節(jié) uint16_t) | 
| 0x3a | 負整數(shù)-1-n(后面是 n 的四字節(jié) uint32_t) | 
| 0x3b | 負整數(shù) -1-n (后面是 n 的八字節(jié) uint64_t) | 
| 0x40….0x57 | 字節(jié)字符串(0x00….0x17 字節(jié)跟隨) | 
| 0x58 | 字節(jié)字符串(n 為一字節(jié) uint8_t,然后是 n 個字節(jié)) | 
| 0x59 | 字節(jié)字符串(n 為兩字節(jié) uint16_t,然后是 n 個字節(jié)) | 
| 0x5a | 字節(jié)字符串(四字節(jié) uint32_t 表示 n,然后是 n 個字節(jié)) | 
| 0x5b | 字節(jié)字符串(n 為八字節(jié) uint64_t,然后是 n 個字節(jié)) | 
| 0x5f | 字節(jié)字符串,字節(jié)字符串跟隨,以 “break” 終止 | 
| 0x60….0x77 | UTF-8 字符串(0x00….0x17 字節(jié)跟隨) | 
| 0x78 | UTF-8字符串(n為一字節(jié)uint8_t,然后是n個字節(jié)) | 
| 0x79 | UTF-8字符串(n為兩字節(jié)uint16_t,然后是n個字節(jié)) | 
| 0x7a | UTF-8字符串(四字節(jié)uint32_t表示n,然后是n個字節(jié)) | 
| 0x7b | UTF-8字符串(n為八字節(jié)uint64_t,然后是n個字節(jié)) | 
| 0x7f | UTF-8 字符串,UTF-8 字符串跟隨,以 “break” 結(jié)尾 | 
| 0x80….0x97 | 數(shù)組(0x00….0x17 數(shù)據(jù)項跟隨) | 
| 0x98 | 數(shù)組(n為一字節(jié)uint8_t,然后是n個數(shù)據(jù)項) | 
| 0x99 | 數(shù)組(n為兩字節(jié)uint16_t,然后是n個數(shù)據(jù)項) | 
| 0x9a | 數(shù)組(n為四字節(jié)uint32_t,然后是n個數(shù)據(jù)項) | 
| 0x9b | 數(shù)組(n為八字節(jié)uint64_t,然后是n個數(shù)據(jù)項) | 
| 0x9f | 數(shù)組,數(shù)據(jù)項跟隨,以 “break” 終止 | 
| 0xa0….0xb7 | 映射(0x00….0x17 對數(shù)據(jù)項跟隨) | 
| 0xb8 | map(n為一字節(jié)uint8_t,然后是n對數(shù)據(jù)項) | 
| 0xb9 | map(n為兩字節(jié)uint16_t,然后是n對數(shù)據(jù)項) | 
| 0xba | map(n為四字節(jié)uint32_t,然后是n對數(shù)據(jù)項) | 
| 0xbb | map(n為八字節(jié)uint64_t,然后是n對數(shù)據(jù)項) | 
| 0xbf | 映射,后面是成對的數(shù)據(jù)項,以 “break” 終止 | 
| 0xf4 | 錯誤的 | 
| 0xf5 | 真的 | 
| 0xf6 | 無效的 | 
| 0xf7 | 不明確的 | 
示例:
| Value | Encoding | 
|---|---|
| 0 | 0x00 | 
| 1 | 0x01 | 
| 10 | 0x0a | 
| 23 | 0x17 | 
| 24 | 0x1818 | 
| 100 | 0x1864 | 
| 1000 | 0x1903e8 | 
| 1000000 | 0x1a000f4240 | 
| -1 | 0x20 | 
| -10 | 0x29 | 
| -100 | 0x3863 | 
| -1000 | 0x3903e7 | 
| [] | 0x80 | 
| [1,2,3] | 0x83010203 | 
| [1,[2,3],[4,5]] | 0x8301820203820405 | 
| {“a”: 1, “b”: [2,3]} | 0xa26161016162820203 | 
| [“a”,{“b”: “c”}] | 0x826161a161626163 | 
| h'01020304' | 0x4401020304 | 
| 1(1363896240) | 0xc11a514b67b0 | 
| 錯誤的 | 0xf4 | 
| 真的 | 0xf5 | 
| 無效的 | 0xf6 | 
| [_] | 0x9fff | 
| “z” | 0x617a | 
| “aa” | 0x626161 | 
用定長和不定長數(shù)組來表示[1, [2, 3], [4, 5]]:
| Value | Representation | 
|---|---|
| [1,[2,3],[4,5]] | 0x8301820203820405 | 
| [1,[2,3],[4,5]] | 0x9f018202039f0405ffff | 
| [1,[2,3],[4,5]] | 0x9f01820203820405ff | 
| [1,[2,3],[4,5]] | 0x83018202039f0405ff | 
| [1,[2,3],[4,5]] | 0x83019f0203ff820405 | 
	
二、SMP的數(shù)據(jù)格式如下
	
注意: 原生SMP specification是支持Big-endian 和Little-endian, 但實際上mcumgr-library已經(jīng)固定使用Big-endian模式。
2.1 定義里面各數(shù)據(jù)域的解釋如下:
| Data | Definition | 
|---|---|
| Res | 保留,默認是 0. 可能將來給SMP的版本信息使用 | 
| OP | Operation code | 
| Flags | 標志位保留,默認使用 0 | 
| Data Length | Data field數(shù)據(jù)塊的長度 | 
| Group ID | Management Group ID’s | 
| Sequence Num | frame sequence number應該每發(fā)送一包數(shù)值增加一,而且應答包的 Sequence Num 應該跟發(fā)送包的包號碼相對應 | 
| Command ID | 和Group ID聯(lián)合使用 | 
| Data | 可選項,如果Data Length為0的話,這塊數(shù)據(jù)請忽略,表明沒有數(shù)據(jù)塊需要傳輸,只是一個控制指令 | 
2.1.1 Operation Code 對應的定義如下:
0:read request
1:read response
2:write request
3:write response
每一條request都有一條response指令作應:
read response就是read request的應答;
write response就是write request的應答。
21.2 跟 nRF Connect SDK 相關的 Management Group ID, 以及對應Group下面對應的Command ID如下:
0:Default/OS Management Group
0.Echo
4.System reset
5.MCUMGR parameter
1:Application/software image management group
0.State of images
1.Image upload
2.2 我們再列出 nRF Connect SDK dfu使用的指令
前言里 DFU 流程對應的命令如下:
1. mcumgr add myCOM type=“serial“ connstring=”dev=COM13,baud=115200,mtu=256” (UART升級和USB升級) 2. mcumgr parameter request 3. mcumgr image upload app_update.bin 4. mcumgr image list 5. mcumgr image test 6. mcumgr reset 7. mcumgr image confirm.
2.3 完整解讀SMP指令
2.3.1 mcumgr parameter
request:
| Type | Value | Command | 
|---|---|---|
| Operation Code | 0 | read request | 
| Group ID | 0 | OS Management Group | 
| Command id | 6 | MCUMGR parameter | 
示例數(shù)據(jù)為:00 00 00 01 00 FF 06 A0。
對應image header的8個字節(jié)就是 00 00 00 01 00 FF 06, A0表示一個空的字典。
response
| Type | Value | Command | 
|---|---|---|
| Operation Code | 1 | read response | 
| Group ID | 0 | OS Management Group | 
| Command id | 6 | MCUMGR parameter | 
示例數(shù)據(jù)為:
01 00 00 19 00 00 FF 06 BF 68 62 75 66 5F 73 69 7A 65 19 09 AB 69 62 75 66 5F 63 6F 75 6E 74 04 FF。
對應image header的8個字節(jié)為:01 00 00 19 00 00 FF 06
Payload對應為:
BF 68 62 75 66 5F 73 69 7A 65 19 09 AB 69 62 75 66 5F 63 6F 75 6E 74 04 FF。
我們解析一下這塊數(shù)據(jù)對應的數(shù)據(jù)格式:
BF                                    --------map 
  68                                  ------數(shù)組,8個字節(jié) 
      62 75 66 5F 73 69 7A 65         ------“buf_size” 
  19                                  ------整數(shù)值,用2字節(jié)表示 
      09 AB                           ------2475 
  69                                  ------數(shù)組,9個字節(jié) 
      62 75 66 5F 63 6F 75 6E 74      ------“buf_count” 
  04                                  ------整數(shù),數(shù)值就是4
FF                                    ------結(jié)束符 
那么我們?nèi)绾卫斫馕覀冞@個數(shù)據(jù)的意思呢,我們再看mcumgr parameter response的數(shù)據(jù)格式:
{
  (str)"buf_size"   :(uint) 
  (str)"buf_count"  :(uint) 
  (opt,str)"rc"     :(int)
}
???這里我們就可以理解了,這條指令就是看設備里面配置的參數(shù),我們的buf_size 設置的是多大,配置了多少個這么大的buf;對應我們再從機代碼里面設置的參數(shù)是什么呢?就是這兩條參數(shù):
CONFIG_MCUMGR_BUF_SIZE=2475 CONFIG_MCUMGR_BUF_COUNT=4
2.3.2 mcumgr image upload
request
| Type | Value | Command | 
|---|---|---|
| Operation Code | 2 | write request | 
| Group ID | 1 | Application/software image management group | 
| Command id | 1 | Upload images | 
數(shù)據(jù)為:02 00 09 A0 00 01 01 01 BF 64 64 61 74 61 59 09 80 ………payload (2432 bytes)…….63 6F 66 66 19 1C A0 FF。
對應image header的8個字節(jié)為:02 00 09 A0 00 01 01 01,這是第一包upload指令,sequence number為1。
Payload為:BF 64 64 61 74 61 59 09 80 ………payload (2432 bytes)…….63 6F 66 66 19 1C A0 FF。
我們解析一下這塊數(shù)據(jù)對應的數(shù)據(jù)格式:
BF                    ------字典的開始 
  64                  ------字節(jié)string數(shù)組,長度為4 
      64 61 74 61     ------“data” 字段 
  59                  ------長度為2字節(jié)字符串 
      09 80           ------這一包數(shù)據(jù)長度為 “2432” 
  63                  ------字節(jié)string數(shù)組,長度為3 
      6F 66 66        ------“off” 字段 
  19                  ------整數(shù)值,2字節(jié)表示 
      1C A0           ------這端數(shù)據(jù)偏移地址為1CA0 
FF                    ------結(jié)束符 
那么我們再來看一下這條寫指令對應的CBOR的數(shù)據(jù)格式:
{
  {
    (str,opt)"image"   :(uint)
    (str,opt)"len"     :(uint) 
    (str)"off"         :(uint)
    (str,opt)"sha"     :(str)
    (str,opt)"data"    :(byte str)
    (str,opt)"upgrade" :(bool)
  }
}
那么這條指令對應的意思就是向設備發(fā)送一條長度為2432字節(jié)的image數(shù)據(jù),它的偏移地址為1CA0;如此循環(huán)往復,第二包在第一包的基礎上增加偏移量,一直傳輸?shù)阶詈笠话?;對?432超過MTU的大小的話,那就需要對2432字節(jié)再次分包發(fā)送,并等待設備的image upload response.其中,sequence number會遞增加1。
response
| Type | Value | Command | 
|---|---|---|
| Operation Code | 3 | write response | 
| Group ID | 1 | Application/software image management group | 
| Command id | 1 | Upload images | 
數(shù)據(jù)為:03 00 00 0D 00 01 03 01 BF 62 72 63 00 63 6F 66 66 19 1C A0 FF。
對應image header的8個字節(jié)就是 03 00 00 0D 00 01 03 01,當中0x0D表示數(shù)據(jù)長度為13字節(jié)。
對應payload為:BF 62 72 63 00 63 6F 66 66 19 1C A0 FF。
我們解析一下這塊數(shù)據(jù)對應的數(shù)據(jù)格式:
BF                  ------字典的開始 
  62                ------字節(jié)string數(shù)組,長度為3 
      72 63         ------“rc” 字段 
  00                ------整數(shù),值為0 
  63                ------字節(jié)string數(shù)組,長度為3 
      6F 66 66      ------“off” 字段 
  19  
      1C A0         ------這端數(shù)據(jù)偏移地址為1CA0 
FF                  ------結(jié)束符
我們再來看一下這條寫應答對應的CBOR的數(shù)據(jù)格式:
{
  (str,opt)"off"  :(uint) 
  (str)"rc"       :(int)
  (str,opt)"rsn"  :(str)
}
這條應答指令的意思就是,剛才那條寫image命令沒有出錯(此處對應的rc為0),然后它的偏移地址為1CA0。
2.3.3 mcumgr image list
request :
| Type | Value | Command | 
|---|---|---|
| Operation Code | 0 | read request | 
| Group ID | 1 | Application/software image management group | 
| Command id | 0 | Statics of images | 
數(shù)據(jù)為:00 00 00 02 00 01 00 00 BF FF。
對應image header的8個字節(jié)就是 00 00 00 02 00 01 00 00,數(shù)據(jù)BF FF表示一個空的字典。
response
| Type | Value | Command | 
|---|---|---|
| Operation Code | 1 | read request | 
| Group ID | 1 | Application/software image management group | 
| Command id | 0 | Statics of images | 
數(shù)據(jù)為:
01 00 00 86 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 30 2E 30 64 68 61 73 68 58 20 68 3D BA 00 D2 7C 7A D4 98 A7 D5 BA 55 55 BB B4 E8 CA 9F EA 91 DD CC FC A2 F8 DD 13 40 A0 05 79 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 69 70 65 72 6D 61 6E 65 6E 74 F4 FF FF 6B 73 70 6C 69 74 53 74 61 74 75 73 00 FF。
對應image header的8個字節(jié)就是 01 00 00 86 00 01 00 00,86表示整段數(shù)據(jù)長度為0x86字節(jié)。
Payload為:
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 30 2E 30 64 68 61 73 68 58 20 68 3D BA 00 D2 7C 7A D4 98 A7 D5 BA 55 55 BB B4 E8 CA 9F EA 91 DD CC FC A2 F8 DD 13 40 A0 05 79 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 69 70 65 72 6D 61 6E 65 6E 74 F4 FF FF 6B 73 70 6C 69 74 53 74 61 74 75 73 00 FF。
我們解析一下這塊數(shù)據(jù)對應的數(shù)據(jù)格式:
BF
  66
      69 6D 61 67 65 73                   ------“images“ 字段 
  9F
        BF
        64
            73 6C 6F 74                   ------ “slot” 字段,值為0 
            00
        67
            76 65 72 73 69 6F 6E          ------“version” 字段 
        65
            30 2E 30 2E 30                ------值為”0.0.0” 
        64
            68 61 73 68                   ------ “hash” 字段 
        58 20
            68 3D BA 00 D2 7C 7A D4 98 A7 D5 BA 55 55 BB B4 E8 CA 9F EA 91 DD CC FC A2 F8 DD 13 40 A0 05 79   ------長度為32字節(jié)的hash值 
        68
            62 6F 6F 74 61 62 6C 65       ------ “bootable” 字段,值為false 
            F5
        67
            70 65 6E 64 69 6E 67          ------ “pending” 字段,值為 false. 
            F4
        69
            63 6F 6E 66 69 72 6D 65 64    ------ “confirmed” 字段,值為 true. 
            F5
        66
            61 63 74 69 76 65             ------“active” 字段,值為 true 
            F5
        69
            70 65 72 6D 61 6E 65 6E 74    ------ “permanent” 字段,值為 false 
            F4
        FF
  FF
  6B
      73 70 6C 69 74 53 74 61 74 75 73    ------  “splitstatus”  字段,值為false 
      00
FF 
此命令對應的CBOR數(shù)據(jù)格式如下:
{
  (str)"images":[
  {
    (str,opt)"image"      :(int)
    (str)"slot"           :(int)
    (str)"version"        :(str)
    (str)"hash"           :(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)
}
通過這條指令,可以看到1個或2個slot分區(qū)里面的image的狀態(tài)是不是confirmed,是不是active等等。
2.3.4 mcumgr image test
request:
| Type | Value | Command | 
|---|---|---|
| Operation Code | 2 | read request | 
| Group ID | 1 | Application/software image management group | 
| Command id | 0 | Statics of images | 
對應的數(shù)據(jù)為:
02 00 00 32 00 01 61 00 BF 67 63 6F 6E 66 69 72 6D F4 64 68 61 73 68 58 20 EF 71 9F 16 7C 06 8F 44 AC 53 DD 89 1C F9 CD 05 3F 0A 34 B2 A0 75 2F 62 87 C3 97 CC 68 7C AE 4A FF。
對應image header的8個字節(jié)就是 02 00 00 32 00 01 61 00。
對應payload為:
BF 67 63 6F 6E 66 69 72 6D F4 64 68 61 73 68 58 20 EF 71 9F 16 7C 06 8F 44 AC 53 DD 89 1C F9 CD 05 3F 0A 34 B2 A0 75 2F 62 87 C3 97 CC 68 7C AE 4A FF。
我們解析一下這塊數(shù)據(jù)對應的數(shù)據(jù)格式:
BF                            ------字典的開始
  67                          ------字節(jié)string數(shù)組,長度為7
      63 6F 6E 66 69 72 6D    ------ “confirm”  字段
  F4                          ------值為false
  64                          ------字節(jié)string數(shù)組,長度為4
      68 61 73 68             ------“hash” 字段
  58 20                       ------長度為0x20的bin string類型
  EF 71 9F 16 7C 06 8F 44 AC 53 DD 89 1C F9 CD 05 3F 0A 34 B2 A0 75 2F 62 87 C3 97 CC 68 7C AE 4A     ------32字節(jié)hash值
FF                            ------字典結(jié)束 
這條寫命令對應的CBOR的數(shù)據(jù)格式:
{
  (str,opt)"hash" :(str)
  (str)"confirm"  :(bool)
}
可以看出,這條指令對應的意思就是,下發(fā)confirm為false的帶hash值的寫命令。
Mcumgr Confirm request指令與其類似,zephyr文檔寫到:
如果“confirm”為 false,則將設置帶有“hash”的值進行測試,這意味著它將不會被標記為永久,并且在復位之后,以前的應用程序?qū)貪L到之前的image。如果“confirm” 為 true,則 “hash” 是可選的,當前運行的應用程序?qū)⒈辉O置為目標運行程序,意味著不再回滾到之前的版本。
response
| Type | Value | Command | 
|---|---|---|
| Operation Code | 3 | read request | 
| Group ID | 1 | Application/software image management group | 
| Command id | 0 | Statics of images | 
其應答與image list response應答相同,不再重復。
2.3.5 mcumgr reset
request
| Type | Value | Command | 
|---|---|---|
| Operation Code | 2 | read request | 
| Group ID | 0 | OS Management Group | 
| Command id | 5 | Reset Image | 
數(shù)據(jù)為:02 00 00 02 00 00 62 05 BF FF。
對應image header的02 00 00 02 00 00 62 05;
Payload為:BF FF,表示這是一個空的map,沒有實際數(shù)據(jù)。
response
| Type | Value | Command | 
|---|---|---|
| Operation Code | 3 | read request | 
| Group ID | 0 | OS Management Group | 
| Command id | 5 | Reset Image | 
數(shù)據(jù)為:03 00 00 02 00 00 62 05 BF FF。
對應image header的03 00 00 02 00 00 62 05。
Payload為:BF FF,表示這是一個空的map,沒有實際數(shù)據(jù)。
三、SMP central的實現(xiàn)
SMP central的實現(xiàn)按照上面所述流程操作,那么我們首先就是需要把升級文件放到內(nèi)部或者外部flash里面,central通過內(nèi)部代碼把flash操作讀出來,通過指令完成image upload操作。
上述有幾個步驟,可以通過發(fā)命令遠程去完成,也可以通過調(diào)用本地API自己去完成,兩種選擇都可以。
比如confirm image這一步,你可以等待新image啟動成功,然后重連主機,主機再發(fā)“confirm image”命令,這個時候升級才算真正完成;也可以在新image啟動成功后,在不連主機的情況下,通過調(diào)用前述API:boot_write_img_confirmed () 來完成這個確認過程。不管采用那種方法,本質(zhì)上都是調(diào)用 boot_write_img_confirmed () 來實現(xiàn),不同的是觸發(fā)方式或者時機,發(fā)命令的方式由主機遠程觸發(fā)(SMP DFU 就是選擇這種主機遠程發(fā)命令方式),而本地API方式則是設備自己選擇時機來觸發(fā)(nrf dfu 就是選擇這種本地API調(diào)用方式。
Mcumgr parameter指令也可以不通過request完成操作,我們只需要在central端和peripheral端統(tǒng)一好參數(shù)就可以。
3.1 Mcumgr reset指令:
SMP Payload
zcbor_map_start_encode(zse, CBOR_MAP_MAX_ELEMENT_CNT); zcbor_map_end_encode(zse, CBOR_MAP_MAX_ELEMENT_CNT);
SMP Header
smp_cmd.header.op = 2; /* Write */ smp_cmd.header.flags = 0; smp_cmd.header.len_h8 = (uint8_t)((payload_len >> 8) & 0xFF); smp_cmd.header.len_l8 = (uint8_t)((payload_len >> 0) & 0xFF); smp_cmd.header.group_h8 = 0; smp_cmd.header.group_l8 = 0; /* OS */ smp_cmd.header.seq = load_seq;
3.2 Mcumgr test指令:
SMP Payload
zcbor_map_start_encode(zse, CBOR_MAP_MAX_ELEMENT_CNT); zcbor_tstr_put_lit(zse, "confirm"); zcbor_bool_put(zse, false); zcbor_tstr_put_lit(zse, "hash"); zcbor_bstr_put_lit(zse, hash_value_secondary_slot);
SMP Header
smp_cmd.header.op = 2; /* Write */ smp_cmd.header.flags = 0; smp_cmd.header.len_h8 = (uint8_t)((payload_len >> 8) & 0xFF); smp_cmd.header.len_l8 = (uint8_t)((payload_len >> 0) & 0xFF); smp_cmd.header.group_h8 = 0; smp_cmd.header.group_l8 = 1; /* app/image */ smp_cmd.header.seq = load_seq;
3.3 Mcumgr upload指令:
SMP Payload
if(!zcbor_map_start_encode(zse, encode_len))
  LOG_INF("zcbor_map_start_encode(zse, encode_len) fail");
zcbor_tstr_put_lit(zse, "data");
if(!zcbor_bstr_encode_ptr(zse, data, upload_chunk))
  LOG_INF("zcbor_bstr_encode_ptr(zse, data, upload_chunk) fail");
zcbor_tstr_put_lit(zse, "len");
if(!zcbor_uint64_put(zse, (uint64_t)(last_addr-start_addr)))
  LOG_INF("zcbor_uint64_put(zse, (uint64_t)(last_addr-start_addr)) fail");
zcbor_tstr_put_lit(zse, "sha");
zcbor_bstr_put_lit(zse, "123");
zcbor_tstr_put_lit(zse, "off");
if(!zcbor_uint64_put(zse, curr_addr - start_addr))
LOG_INF("zcbor_uint64_put(zse, curr_addr - start_addr) fail");
SMP Header
smp_cmd.header.op = 2; /* write request */ smp_cmd.header.flags = 0; smp_cmd.header.len_h8 = (uint8_t)((payload_len >> 8) & 0xFF); smp_cmd.header.len_l8 = (uint8_t)((payload_len >> 0) & 0xFF); smp_cmd.header.group_h8 = 0; smp_cmd.header.group_l8 = 1; /* IMAGE */ smp_cmd.header.seq = load_seq; 審核編輯 黃宇
- 
                                SMP
                                +關注關注 0文章 80瀏覽量 20619
- 
                                OTA
                                +關注關注 7文章 623瀏覽量 37782
發(fā)布評論請先 登錄
SMP模塊推力測試指南:推拉力測試機的應用與操作
 
    
V5.2.1 A53 SMP啟動卡死的原因?怎么解決?
如何排除 USB 協(xié)議分析儀測試中的干擾源?
如何測試協(xié)議分析儀的實時響應效率?
協(xié)議分析儀支持哪些高級觸發(fā)選項?
協(xié)議分析儀能監(jiān)測哪些異常行為?
協(xié)議分析儀需要支持哪些常見協(xié)議?
如何使用協(xié)議分析儀進行數(shù)據(jù)分析與可視化
藍牙協(xié)議分析儀能檢測哪些問題?
SPI協(xié)議,寄存器解讀
MTP協(xié)議與FTP協(xié)議的比較分析
SMO與SMP的區(qū)別與聯(lián)系
DS320PR810-SMP-EVM用戶指南
 
    
力科Voyager M3x 分析儀平臺提供業(yè)界最準確可靠的 USB 協(xié)議捕獲
 
    
 
           
        
 
         SMP協(xié)議分析和解讀
SMP協(xié)議分析和解讀 
                 
  
     
            
             
             
                 
             工商網(wǎng)監(jiān)
工商網(wǎng)監(jiān)
        
評論