文章
  • 文章
搜索
首页 >> 技术文档 >>官方资料 >> AG32 bootloader 参考(9月更新)
详细内容

AG32 bootloader 参考(9月更新)

Bootloader 是在用户程序启动前运行的一个小程序。

在单片机中,一般被用于升级用户程序。


终端设备出厂后,常见的升级方式有两种:近端升级(二级烧录)和远程升级。


近端升级,是设备和 PC 有连线情况下的升级。

芯片原厂会提供原始烧录工具,这套烧录工具支持 jtag 和串口。但这套工具在串口烧录时,

需要操作 boot0 和 boot1 引脚,对终端用户来说,利用这种方式升级过程不够友好。

尤其是,终端设备在使用时是有串口连接 PC 的场景。这种场景下,开发者可以把升级功能

集成到 PC 工具内。这种升级方式会更好点。


远程升级,是设备有联网功能,能从服务器下载新固件,然后自己完成升级动作。

这种场景下,设备可以连接到服务器,从服务器下载新版本的 bin,然后设置好标记位,主

动重启设备。在设备重启后,进入 bootloader,判断到标记后,bootloader 将下载好的新版

本的 bin 覆盖掉本地的 bin,从而完成升级的任务。


这两种升级,都需要 bootloader 的参与。

这两种升级的 bootloader 要实现的功能,是不同的功能



近端升级:

一般的近端升级思路:

1. 设备端有两段程序:bootloader.bin 和 app.bin;

     bootloader 放置在 0x80000000 的位置,

     app 放置在约定好的位置(如:0x80008000);

 (如果不带 bootloader,app 会被放置在起始的 0x80000000 位置)

2. 设备启动后,先进入 bootloader;

    在 bootloader 中会等待几秒钟,等待 PC 的下发消息,

    如果没有等到消息,则跳转到 app 运行;

    如果有升级命令,则进入 boot 升级流程;

3. boot 升级流程,就是 PC 工具和 boot 交互的过程;

     这个过程中,bootloader 会一段一段接收 bin 的数据,并覆盖掉本地的 app.bin;


这个过程中,需要:

1、事先规划好 bootloader.bin、app.bin 的存放位置,并制定好 PC 和 bootloard 的交互协议;

2、Bootloader 中需要做:支持串口、实现与 PC 的协议交互、写数据到 flash;

3、PC 工具中需要做:实现跟设备端的协议交互;


在 AG32 中,除了 code.bin 以外,还有 logic.bin(VE 编译出来的)。

所以,在实际操作中,除了传输 code.bin 以外,还要多传输一个 logic.bin。

(注:code.bin 和 logic.bin 是相互独立的,升级时根据需要升级即可,不必一起升级)


上述为实现逻辑。

接下来以 dfu-uart(bootloader)工程为例,详述实现细节。


bootloader 样例说明:

该样例是网盘 bootLoader 下的 dfu-uart.rar。解压后,可把工程复制到 SDK 下的 examples 下。

该样例实现了下位机通过 UART 和上位机交互的过程,整个过程就是上位机对下位机 app 的

升级。


样例目录结构如下:

image.png


其中:

Dfu-uart.c 是 bootloard 的入口 main 函数所在文件。

      该文件中实现逻辑:启动 -> 使能自带的 logic -> 打开串口 -> 等待升级指令 ->

          等到指令 -> 进入升级流程 -> 升级完成后重启系统。

          等不到指令 -> 关闭串口 -> 恢复状态 -> 装载 APP 的 logic -> 跳转到 APP。

      在该代码中,使用了外部晶振。必须要在 ve 中正确配置。

      在该文件的顶部,有配置宏:APP 的 code 地址、APP 的 logic 地址、烧录串口号和波特

      率、等待超时(多长时间内没收到命令就进入 APP)、LED 灯。其中除了最后一项 LED

       灯,其他都是必选项。

Boot.c 是串口升级流程中的指令处理。

       在指令处理中,下位机是完全被动的,所有动作都是由上位机来发起。

       一次升级中的典型流程:

      A. 上位机 100ms 发送一次 0x7F,用以触发下位机进入升级流程;

        (下位机的 bootloader 收到 0x7F 时,不再往 APP 跳转,而是进入升级流程,同时回应上位机)

       B. 上位机收到回应后,发送准备升级指令;

           下位机准备升级并回应。

       C. 上位机收到回应后,下发擦除指令(给定地址和长度)

           下位机根据指令,擦除 code 或 logic 存放 flash 的区域。并回应。

        D. 上位机收到回应后,下发写数据命令(把 bin 拆分成一条条数据)

            下位机按给定的地址和长度写入下发的数据。并回应。

            这个 D 步骤会一直重复,直到整个 bin 全部写完。

        E. 上位机全部写完后,下发获取 crc 的命令

            下位机按指定的位置和长度计算 CRC,并回应。

        F. 上位机收到回应后,对比 crc 是否正常。如果正常,则发送重启命令;

            下位机收到命令后,重启。至此,完成升级任务。

         从以上流程中已经可以看出:升级过程中上位机完全主导。擦除、分段写、计算 CRC、重启等动作,都是由上位机来发起的。

Fpag_uart.inc 是该 bootloader 的 ve 对应编译出来的 logic.bin。

          这里是把 logic 内置到代码 code 中去。内置(不和 app 共享 logic)原因如下:

          在整个 flash 中,存在 3 部分内容:bootloader 代码,用户程序 app.bin,用户 logic.bin。

          bootloader 在升级时,可能同时要对后边两项都要升级。

          但 bootloader 本身也需要 logic 的引脚配置(即:VE 配置),又不能与用户 logic 冲突。

          当然,bootloader 可以和 app 共用一个用户 logic.bin。但如果要升级 logic.bin 并且刚好

          升级一半断电,则再次重启后,bootloader 拿不到 logic,设备就会变砖。

          因而,推荐是 bootloader 自带内置的 logic,这样可以避免升级 logic 时带来的各种隐患。

          也就是说,bootloader 跟普通应用一样,是有自己的 logic(VE)的。只不过这个 logic

          不再烧录到 flash 的最后 100K 去,而是嵌入到 code 中,在 code 运行时才解压释放出来。

Dfu.ve 是 dfu 自带的 ve 配置文件。

          该 VE 里,两个 clk 必须配置,升级串口必须配置,log 串口可选配,led 可选配。

          image.png

         使用时,要根据自己的板子对应来配置。

         注意:

         这里配置后,编译出来的 logic.bin,通过工具转换后,就是上边的 fpga_uart.inc 文件。

         编译和转换过程,后续会有详述。

Platformio.ini 是 dfu 的工程配置;

         在该配置文件中,使用方式同 example。有几个字段需要注意:

        board_build.boot_addr = upload 必配

        board_build.boot_mode= flash_sram 必配

        logger_if = UART1 配置 bootloader 是否输出 log,如果不输出 log,则不需该项

        -DDFU_FPGA_CONFIG=\"fpga_uart.inc\" 指定内置的 logic.bin。不指定则和 APP 共用 logic


整体而言,bootloader 在这里是个独立的程序,它的作用是作为一个桥梁,实现 PC 端对用户 code


APP 用户程序的设置:

         增加 bootloader 后,APP 程序部分正常开发即可,不受影响。

         只是在最终编译和烧录时,需要修改起始偏移和烧录位置。


         需要设置项:

        board_upload.address = 0x80010000

        board_build.boot_addr = 0x80010000

        以上两项分别设置:烧录起始地址 0x80010000,程序运行起始位置 0x80010000。

        这个地址,也是 bootloader 中要用到的跳转地址。


         除了以上两项,与 bootloader 中还有关联的设置是:

         board_logic.compress = true

         board_upload.logic_address = 0x800e7000

         第一项是 logic 是否压缩,如果压缩,则 bootloader 中最后恢复 APP 的 logic 时,需要使用 FCB_AutoDecompress 函数,否则使用 FCB_AutoConfig 函数。

         image.png

         第二项是 logic 要烧录到 flash 的位置。

        最好根据编译出来的大小自己配置位置。如果不配置,则默认是 flash 的最后 100K。

        这个地址,在 bootloader 里被使用,就是上图 FCB_AutoConfig 的参数(如果是 1M 的 flash,

        则最后 100K 的地址就是 924K 处,0x800e7000)。

        总结,以上的两个地址(code.bin 和 logic.bin 的偏移)和 logic 是否压缩,是影响到bootloader 中的设置的。


转换工具:

        bootloader 代码中需要自带 VE 编译出来的 logic.bin。操作如下:

        1. 先配置好 VE 选项(如前图);

        2. 编译出 logic.bin,在\dfu-uart\.pio\logic\下的可看到 dfu.bin;

        image.png

       3. 将 dfu.bin 复制到 bin2char.exe 工具的路径下,打开工具并生成:

      image.png

       4. 将生成好的 dfu.txt 重命名成 fpga_uart.inc,覆盖掉 dfu-uart 下的即可;

       5. bootloader 代码中对这部分的使用如下:

     image.png


交互协议:

       这里列举下位机升级时,与 PC 的协议交互。

      (只是样例,如果使用中有其他需求,请自行修改该协议)

        1. 通用回应字 ACK 和 NACK:

              Cmd:ACK - 0x79, NACK - 0x1F

              ACK 和 NACK 是下位机回应上位机的字节,由下位机发给 PC。

       2. 探测字:

             Cmd:0x7F

            上位机 100ms 发送一次。下位机 bootloader 中收到后,会回应 ACK。

            上位机收到 ACK 后,进入启动升级。

        3. 启动升级:

             Cmd:0x7F ~0x7F

              Rsp: ACK

             注意:这里开始 cmd 有两位,分别是 cmd 和 0xFF-cmd。第二位用以安全验证。

             bootloader 收到会,回应 ACK。

         4. 擦除 flash:

             Cmd:0x44 ~0x44       addr(4) + crc(1)         len(4) + crc(1)

             Rsp:                        ACK                           ACK                          ACK

              这里一条完整的命令,有三个 ACK。

              发送多字节数据时,高位在前。

              数据段意义:

                     addr:要擦除的起始地址。该值范围:0x80000000 ~ 0x80100000 (1M)

                      len:擦除的长度

              内置 flash 最小可擦除单位为 sector(4K)。

              这里的擦除,可以是 code 区也可以是 logic 区,看上位机要更新哪段 bin。

           5. 写数据到 flash:

               Cmd:0x31 ~0x31      addr(4) + crc(1)              len(1) + data(len) + crc(1)

                Rsp:                         ACK                           ACK                                             ACK

                这条完整命令,有三个 ACK。

                地址范围:0x80000000 ~ 0x80100000 (1M)

              6. 计算整个 bin 的 CRC:

                  Cmd:0xA1 ~0xA1        addr(4) + crc(1)         len(4) + crc(1)

                   Rsp:                         ACK                          ACK                          ACK CRC(4)

                   这条完整命令,有三个 ACK 和一个 CRC 回复。

                  CRC 回复 4 字节,高位在前。标准的 CRC32 算法(但参数不同)。

             7. 重启 mcu:

                  Cmd:0xA2 ~0xA2

                  Rsp: ACK  ACK

                  这条命令,回复有两个 ACK。

                  下位机在收到这条命令后,重启。

上位机工具:

             上位机工具及源码也位于 bootLoader 目录下(和 bin2Char 在一个路径下)。

             这里给出的工具,是配合下位机的 bootloader 程序使用的。

             源码是 c#实现,在代码里 UI 和协议逻辑实现是分离的。如果要集成到自己的工具里,

             可参考协议部分的代码。

             这里简要介绍下如何使用(更多细节参考源码)。

             1. 版本升级时,上位机工具选择好要升级的 bin,点击【START】

            这里可以选单纯升级 code、单纯升级 cpld、或者两项都选择一起升级。

            这里的串口,连接的是下位机的 UART0. 

            就是 APP 里设定好的 code 和 logic 的偏移地址。

           image.png


          2. 然后重启设备,会看到进入升级程序的进度条。

           (注:这里点击 START 后,PC 会持续发出探测包 0x7F。重启设备,设备进入 bootloader,

            检测到 0x7F 后,进入升级模式。开始跟 PC 交互。工具上出现 UI 进度条)


           3. 升级完成后提示:

           image.png

           注:PC 端还不支持对 createBatch 后的二合一的 bin 进行升级。只支持 code 和 logic 的分开升级。(分开升级,其实就是写两段 bin 到 flash 去)


简要使用流程:

            以上的几个部分在初次验证时,不是全部必须的。

            初次验证时,使用以下步骤即可:

            1. 修改 APP 的 platformio.ini 里的两处设定:

                 board_upload.address = 0x80010000

                 board_build.boot_addr = 0x80010000

            2. 使用上边提供的 bootloader 工程:

                 注意,例程中的内置 logic.bin 是用的外部 8M 晶振。如果开发板上不是 8M,需要参照上边描述生成内置 logic.bin 并替换。

            3. 烧录 bootloader 的 code,烧录 app 的 code,烧录 app 的 ve;

                (不用烧录 bootloader 的 logic,因为它已经内置在 code 里了)

            4. app 部分,修改 code 中闪灯的快慢,修改 ve 中闪灯引脚的定义,并重新编译出来新版本的 code 和 logic;

                  注意,这里是只编译,不烧录。(可以断开 jlink 编译)

            5. 从.pio/build 和.pio/logic 下分别拿出 code 和 logic 的新版本的 bin;

            6. 用 PC 更新工具,分别对这两个 bin 进行升级测试。


以上只是作为升级样例供使用。具体使用中请按自己的需求进行修改。


远端升级:

一般的远程升级思路:

1. 设备端有两段程序:bootloader.bin 和 app.bin;

      bootloader 放置在 0x80000000 的位置,

      app 放置在后续约定好的位置(如:0x80008000);

     (如果不带 bootloader,app 会被放置在 0x80000000 位置)

2. 设备启动后,先进入 bootloader;

     在 bootloader 中会判定是否有“升级标记”(该标记来自于 flash 中的记录,app 改写),

     如果没有,则直接跳转到 app;

      如果有,则从约定好的位置,搬新的 app 覆盖掉本地的 app;搬完再跳转;

3. app 在正常运行时,如果服务器有升级需求;

      app 需要先下载好新版本的 code.bin 和 logic.bin;

       然后更改“升级标记”(重启时 bootloader 使用),生成 crc 等验证信息;

       再重启系统;

       这次重启后,会触发 2 中的升级条件。


这个过程中,需要:

1. 事先规划好 bootloader.bin、app.bin、update_app.bin 的存放位置;

2. Bootloader 中需要做:判别标记、校验 crc、搬运 bin、跳转到 app;

3. app 中需要做:下载 update_app.bin、crc 校验、写入标记/crc 值等;


在 AG32 中,除了 code.bin 以外,还有 logic.bin。

所以,在实际操作中,搬运 code.bin 的时候,还要多搬运一个 logic.bin。


说明:

这种模式下的 bootloader,只是个简单的“搬运工”,这里暂时不再提供样例代码,需要的

话可以参考上边的 dfu-uart 进行改写(甚至不必使用外部晶振,不必配置 VE)。

这种模式,需要的 flash 空间至少是 code+logic 的双倍,因为需要存储新版本。

“升级标记”,是 bootloader 和 app 关于升级部分的共享信息,需要存储到 flash 上。


bootLoader.zip



需要获取更多的“资料”和“支持”和“批量采购”可以联系我们

提供“芯片测样-发送资料-技术支持-批量采购”


联系方式: 姚工 13661545024(VX同号)

(加的时候备注下公司名和个人名字)

在线商城:agm-micro.taobao.com

公司网站:www.agm-micro.com

资料网站: www.tcx-micro.com

在线商城.png



关于我们

品牌中心

产品中心

新闻动态

咨询热线:13661545024(全国技术销售热线)

上海天晨芯科技有限公司

销售邮箱:sales@chipmorn.com

技术邮箱:jun.yao@chipmorn.com

公司地址:上海浦东新区东方路1365号5号楼

seo seo