bootloader的作用:升级代码。
.
在单片机的代码升级时,一般需要额外做一个bootloader程序来实现该功能。不管哪种单片机,这里的逻辑是相似的。
正常逻辑:
- 芯片上电后,先运行bootloader;
- bootloader中检测是否要升级:
如果要升级则执行升级动作(用新的bin覆盖掉旧的bin);
如果不用升级,则跳转到用户程序(开始真正运行用户程序)。
为方便描述,bootloader后续简称boot,用户程序简称为app。
所以,boot程序是额外需要实现的一个应用程序。
可以理解为:
boot也是一个应用程序,只不过相比app稍微特殊点,是专用于升级功能而已。
在下位机上,需要同时装载两个程序:boot和app。
boot开发和app一样,可以使用芯片内的所有资源。调试程序可以在vscode下调试。
.
实际应用中,常见的升级方式有两种:近端升级(二级烧录)和远程升级。
近端升级:
是设备和PC有连线情况下的升级方式。
芯片原厂会提供原始烧录工具(称为一级烧录)。但这套工具在串口烧录时,需要操作boot0和boot1引脚,对终端用户来说,利用这种方式升级,操作过程太不友好。
希望的是,用户不用额外操作设备,直接通过串口线插上去就能很方便的升级。
远程升级:
是设备有联网功能,能从服务器下载新固件,然后自己完成升级动作。
这种方式下,不用用户的参与,直接可以服务器端推送来完成升级。
这种场景下,设备连接到服务器,从服务器下载新版本的bin,然后设置好标记位,主动重启设备进入boot,判断到标记后,boot将下载好的新版本的bin覆盖掉本地的bin,从而完成版本的升级。
这两种升级方式,都需要boot的参与。
但这两种升级的boot,要实现的功能是不同的。
.
AG32升级的特点:
1. AG32一套程序需要运行的bin有两个:code.bin和logic.bin;
boot部分需要这样的两个bin,app也需要这样的两个bin;
所以,共需要4个bin:boot_code、boot_logic、app_code、app_logic。
2. 升级,就是用app新的bin替换掉旧的bin;
可以只单独升级app_code或app_logic,
也可以code和logic一起升级;
3. boot和app的这4个bin,都是存储在flash上的;
boot的logic可以选择内置到code,也可以不内置;
app的logic也可以选择内置和不内置;
不管logic是否内置到code里去,这样的bin至少都应该是先制作出来,并最终放进flash。
4. boot+app模式下,芯片上电后的运行逻辑:
A. 芯片上电后,芯片内部rom程序先装载logic.bin到cpld的运行区;
---- 这段rom程序是芯片内部固化的启动程序,不可更改。
---- 这个logic.bin,是在制作batch.bin时指定的logic,样例中,是app_loigc。
B. 跳转到boot的code来运行;
C. boot自己启动后,先重新加载一次自己内置的logic到cpld运行区;
---- 样例中是内置logic方式。这里可以自行修改;
---- 注意:这次加载logic,会覆盖掉步骤A中加载的logic逻辑;
D. 加载完logic后,才真正执行boot的升级代码;
---- 所以,boot的代码真正跑起来,使用的是自己的logic(而不是app_logic);
E. 如果有升级动作,则boot会执行升级逻辑,升级完成后重启;
F. 如果没有升级动作,则跳转到app去运行:
---- 这个跳转动作,分为三步:
---- 1. 先释放掉boot使用的全部资源,并切回内部时钟;
---- 2. 加载app的logic到cpld到运行(该动作会再次覆盖boot的cpld逻辑);
---- 3. 跳转到app入口,开始运行app程序。
5. 关于cpld的运行区:
不管是boot_logic还是app_logic,都是释放到“cpld运行区”运行的。
而整颗芯片只有一个 cpld运行区。
boot的logic 释放过去,芯片运行的就是boot的logic,
app的logic 释放过去,芯片运行的就是app的logic。
如果有两次释放,后释放的,会覆盖掉先释放的。
在上边流程里:
A. 芯片上电后,内置rom程序先释放batch_bin里的logic(其实就是app的logic);
---然后再跳转到boot的程序。
B. 进入boot程序后,boot首先释放自己的logic,覆盖掉app的logic;
---然后再执行boot自己的程序逻辑;
C. boot代码最后跳转到app时,boot会再次释放app的logic,覆盖掉boot的logic;
---然后再程序跳转到app,开始运行app。
.
近端升级的样例逻辑:
1. 设备端有两段程序:boot.bin和app.bin;
boot放置在0x80000000的位置,(内置boot_logic.bin)
app放置在约定好的位置0x80008000(外置app_logic.bin);
(如果不带boot,app会被放置在起始的0x80000000位置)
2. 设备启动后,先进入boot;
在boot中会等待几秒钟,等待PC的下发消息,
如果没有等到消息,则跳转到app运行;
如果有升级命令,则进入boot升级流程;
3. boot升级的过程,就是PC工具和boot交互的过程;
过程中,boot会一段一段接收bin的数据,并覆盖掉本地的app.bin;
这个过程中,需要:
- 事先规划好boot.bin、app.bin的存放位置,并制定好PC和boot的交互协议;
- boot中需要实现:支持串口、实现与PC的协议交互、写数据到flash;
- PC工具中需要做:实现跟设备端的协议交互;
以上是原理部分。
充分理解原理后,可以针对以上原理开发boot程序。
.
从网盘中可以获取到基于407的近端升级的样例:
链接:https://pan.baidu.com/s/1wcBnqnray7bu4IURDIoDDQ?pwd=1205 里边的\其他文档\bootLoader相关\下边,有全部的文档和例程。其中的boot部分和PC工具,都是源码开放的。客户可以根据自己的实际情况来修改使用。
.
.
拓展:
在调试bootloader时,如果需要联调app,可以在vscode的console控制台里,使用如下命令加载app。加载后,就可以在执行完UTIL_JumpToAddress进入app继续跟踪(先是一段汇编,然后进入app的main)。
命令:add-symbol-file ./example_app_logicUncompress/.pio/build/debug/agm_example.elf
其中 add-symbol-file是加载debug信息,后边跟app编译出来的.elf文件。
正常情况下,跳转后如果app可以正常起来,就不用这么复杂了。【因为app直接就可以在vscode跟踪,没必要通过bootloader这层】
.