打印
[应用相关]

STM32F4单片机bootloader及在线升级IAP基本原理

[复制链接]
手机看帖
扫描二维码
随时随地手机跟帖
21
原厂BootLoader在0x1fff 0000 - 0x1fff 77ff的stm32内部存储器内,大小为30K。通过boot引脚设置 boot0= 1;boot1= 0即可进入。

使用特权

评论回复
22
发给她更好fh|  楼主 | 2023-9-30 23:54 | 只看该作者

使用特权

评论回复
23
发给她更好fh|  楼主 | 2023-9-30 23:54 | 只看该作者
STM32F407支持串口、can、USB进行自举升级程序。具体升级协议可自行参考stm32F407中文参考手册。原厂bootloader与flash的组合构成一种基本的升级模式,但会覆盖源程序。

使用特权

评论回复
24
发给她更好fh|  楼主 | 2023-9-30 23:54 | 只看该作者
自定义BootLoader
此部分位于用户操作的flash区域,定义为执行用户逻辑程序APP前的一段引导。

使用特权

评论回复
25
发给她更好fh|  楼主 | 2023-9-30 23:55 | 只看该作者

使用特权

评论回复
26
发给她更好fh|  楼主 | 2023-9-30 23:55 | 只看该作者

这部分可以引导具体执行从flash中哪个地址开始的程序。但基本流程是烧写两短代码BootLoader段和APP段。

使用特权

评论回复
27
发给她更好fh|  楼主 | 2023-9-30 23:55 | 只看该作者
跳转代码很简单,执行一个函数即可,如下:

使用特权

评论回复
28
发给她更好fh|  楼主 | 2023-9-30 23:55 | 只看该作者
iapfun jump2app; //定义函数指针
//跳转到应用程序段
//appxaddr:用户代码起始地址.
void iap_load_app(u32 appxaddr)
{
        if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)        //检查栈顶地址是否合法.
        {
                jump2app=(iapfun)*(vu32*)(appxaddr+4);                //用户代码区第二个字为程序开始地址(复位地址)               
                MSR_MSP(*(vu32*)appxaddr);                                        //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
                jump2app();                                                                        //跳转到APP.
        }
}       

使用特权

评论回复
29
发给她更好fh|  楼主 | 2023-9-30 23:55 | 只看该作者
总的来说是两个操作,一个是将复位函数地址赋值给函数指针,设置堆栈栈顶的地址,第二个是执行函数指针指向的复位函数的地址。
flash源码文件的正确执行就是要正确设置PC和堆栈指针。PC指针指向当前运行的函数,如复位函数;主堆栈指针MSP与函数的嵌套有关,没有这个函数之间的嵌套跳转无法实现。

使用特权

评论回复
30
发给她更好fh|  楼主 | 2023-9-30 23:55 | 只看该作者
具体使用可以这样,根据不同标志位跳转不同flash区域的代码,起到了一个引导加载不同程序的作用。

使用特权

评论回复
31
发给她更好fh|  楼主 | 2023-9-30 23:55 | 只看该作者
                switch (Flag_Table.ull_updaterun_flag)
                                {
                                        case 0x00000011://跳转APP1
                                                                {
                                                                        if(((*(vu32*)(STM32_FLASH_APP1_BASE+4))&0xFF000000)==0x08000000)//判断是否为Flash区域
                                                                        {       
                                                                                        if(Flag_Table.ull_vetofflen!=0x20000)
                                                                                        {
                                                                                                Flag_Table.ull_vetofflen =0x20000;//写入APP1的向量表偏移长度
                                                                                                WriteFlagTable(&Flag_Table);//将标志位的表写入       
                                                                                        }                                                                                               
                                                                                iap_load_app(STM32_FLASH_APP1_BASE);//程序跳转
                                                                        }
                                                       
                                                                }
                                                break;
                                        case 0x00000022://跳转APP2
                                                                {
                                                                        if(((*(vu32*)(STM32_FLASH_APP2_BASE+4))&0xFF000000)==0x08000000)//判断是否为Flash区域
                                                                        {         
                                                                                        if(Flag_Table.ull_vetofflen!=0x40000)
                                                                                        {
                                                                                                Flag_Table.ull_vetofflen =0x40000;//写入APP1的向量表偏移长度
                                                                                                WriteFlagTable(&Flag_Table);//将标志位的表写入       
                                                                                        }                                                               
                                                                                iap_load_app(STM32_FLASH_APP2_BASE);//程序跳转
                                                                        }               
                                                                       
                                                                }                                               
                                                break;
                                        default://默认在当前BootLoader中                                               
                                                break;
                                }

使用特权

评论回复
32
发给她更好fh|  楼主 | 2023-9-30 23:55 | 只看该作者
iap升级
单片机程序的烧录除了使用烧写器下载(ICP)和原厂BootLoader通过串口等外设烧录(ISP)外便是在源程序正常运行的过程中进行修改内部FLASH进行升级操作(IAP),如果对接IAP的外设是无线网模块则可实现远程空中升级(OTA)。

使用特权

评论回复
33
发给她更好fh|  楼主 | 2023-9-30 23:55 | 只看该作者
IAP升级意味着需要在程序运行过程中进行升级跳转,无需操作boot引脚,实现更加自由灵活的升级方式。

使用特权

评论回复
34
发给她更好fh|  楼主 | 2023-9-30 23:56 | 只看该作者
基本原理
IAP升级的基本原理就是流程图的后半段,通过BootLoader确定是否升级,升级的话去读写flash将代码写进入,不升级就跳转运行正常逻辑代码。

使用特权

评论回复
35
发给她更好fh|  楼主 | 2023-9-30 23:56 | 只看该作者

使用特权

评论回复
36
发给她更好fh|  楼主 | 2023-9-30 23:56 | 只看该作者
升级模式
升级模式大致分为以下几种更多的均在此基础上进行的演变。

使用特权

评论回复
37
发给她更好fh|  楼主 | 2023-9-30 23:56 | 只看该作者
原厂bootloader+app

使用特权

评论回复
38
发给她更好fh|  楼主 | 2023-9-30 23:56 | 只看该作者

使用特权

评论回复
39
发给她更好fh|  楼主 | 2023-9-30 23:56 | 只看该作者
此部分常用的名字叫做ISP自举下载。常规项操作,使用不方便需要操作外部boot的电平高低,基本不推荐。

使用特权

评论回复
40
发给她更好fh|  楼主 | 2023-9-30 23:56 | 只看该作者
、自定义bootloader+app

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则