C語言RL78 serial bootloader和C#語言bootloader PC端串列埠通訊程式
瞭解更多關於bootloader 的C語言實現,請加我QQ: 1273623966 (驗證資訊請填 bootloader),歡迎諮詢或定製bootloader(線上升級程式)。
前段時間完成的hyperboot_rl78, 是專門為Renesas 16-bit微控制器RL78 通過串列埠更新程式的bootloader. 由於它是通過超級終端採用Send File的方式來傳送Hex檔案,文字原文傳送,沒有協議,所以基本上hyperboot_rl78是不會使用到產品上,只能在實驗室用用。但是今天我要介紹的RL78 bootloader是可靠性非常高的一款串列埠bootloader。 它分兩部分, 一部分是RL78 MCU 端boot程式 rl78Boot, 另一部分是PC端host 程式 rl78Loader. 他們之間有通訊協定,所以快速,可靠,可以使用到最終的產品上。
rl78Boot是使用CS+ 和CC-RL開發的boot程式,rl78Boot和application 的memory map 設計和 hyperboot_rl78 是一樣的,interrupt vector remap 也和hyperboot_rl78 一樣,詳見我上一篇博文。rl78Boot上電的時候就執行,3~4秒後如果沒有接收到PC 端host 程式 rl78Loader發過來的更新程式請求。就跳轉到正常的application去。如果接收到更新請求,就接收 rl78Loader傳送過來的資料,並根據資料中的命令欄位來執行相應的動作, 並根據結果返回ACK (0x15) 或 NACK (0x51)。
命令欄位有以下幾種
0x6F: HAND_SHAKE (握手,或叫更新請求)
0x02: WR_MEM (Flash 燒寫)
0x03: ER_MEM (Flash 擦除)
0x04: VF_MEM (Flash 驗證)
0x1F: RUN_APP (跳轉到application)
rl78Boot的程式框架如下
void BTLD_BootProcess(void) { if (R_UART0_RcvFlag()) { if (BTLD_FramePtr == 0) { uint8_t sof = R_UART0_FlagedReceive(); if ( sof != 0x02 && sof != 0x03 && sof != 0x04 && sof != 0x1F ) { ; } else { BTLD_ReceiveFrame[BTLD_FramePtr++] = sof; } } else { BTLD_ReceiveFrame[BTLD_FramePtr++] = R_UART0_FlagedReceive(); } } if (BTLD_FramePtr == FRAME_BUFF_SIZE) { uint8_t cmd = BTLD_ReceiveFrame[CMD_INDEX]; uint8_t addL = BTLD_ReceiveFrame[ADDRL_INDEX]; uint8_t addH = BTLD_ReceiveFrame[ADDRH_INDEX]; uint8_t addU = BTLD_ReceiveFrame[ADDRU_INDEX]; uint32_t add32 = ((uint32_t)addU << 16)|((uint32_t)addH << 8) | addL; BTLD_FramePtr = 0; switch (cmd) { case ER_MEM: BTLD_FlashErase(add32); resetDataBuffer(BTLD_ReceiveFrame, FRAME_BUFF_SIZE); break; case WR_MEM: BTLD_FlashWrite(add32); resetDataBuffer(BTLD_ReceiveFrame, FRAME_BUFF_SIZE); break; case VF_MEM: BTLD_FlashVerify(add32); break; case RUN_APP: Jump_To_Application(add32); break; default: break; } } }
rl78Loader是使用Visual Studio 2013和C#開發的帶UI介面的PC端host程式, rl78Loader 介面上可以選擇COM口,Baud rate, 載入要燒寫的hex(目前只支援Motorola S-Record格式)。並將record資料轉換成Bin資料。我為rl78Loader 和rl78Boot之間的互動,設計總共5種類型的幀分別對應到5種不同的命令,也就是 HAND_SHAKE, WR_MEM, ER_MEM, VF_MEM, RUN_APP。 5種幀的統一格式如下:
<CMD><ADDR_L><ADDR_H><ADDR_U><DATA_1><DATA_2>.....<DATA_n><CHECK_SUM>
上面就是自定義的通訊協定,規定了每個幀包含命令欄位一個(<CMD>), 地址欄位三個(<ADDR_L>, <ADDR_H>和<ADDR_U>),組合起來就是24-bit地址。 資料欄位n個<DATA_1>....<DATA_n>, 以及最後的校驗和<CHECK_SUM>。每個欄位都是1個Byte(8-bit)。 當某些欄位不用時,可以填充0xFF。 比如握手幀在<CMD>段為0x6F, 在<ADDR_L>, <ADDR_H>, <ADDR_U>都為0xFF, 因為握手幀不需要地址內容。
UI 介面上"Start" 按鈕按下後, 首先發送握手幀(CMD=0x6F),並重復多次,如果重複多次仍然沒接受到ACK, Log視窗就會列印“bootloader not found".
但握手時一旦接收到ACK, 就會接著傳送擦除幀(CMD=0x03),並等待ACK, 接著就是燒寫幀(CMD=0x02), 驗證幀(CMD=0x04), 最後是跳轉幀(CMD=0x1F)。這個就是整個燒寫流程。
rl78Loader 的UI 介面如下: