1. 程式人生 > >C語言RL78 serial bootloader和C#語言bootloader PC端串列埠通訊程式

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 介面如下: