C语言RL78 serial bootloader和C#语言bootloader PC端串口通信程序

            了解更多关于bootloader 的C语言实现,请加我Q扣: 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 界面如下:

 

posted @ 2018-11-11 00:07  GeekyGeek  阅读(1390)  评论(0编辑  收藏  举报