打印
[学习笔记]

IAP升级的Bootloader和APP的程序跳转学习

[复制链接]
13072|22
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 wangjj19950516 于 2021-9-1 17:18 编辑

    最近很多客户问到升级的问题,各种协议的,有CAN,UART,LIN等。借着这个机会,学习了一下程序跳转的原理,在这里记录一下。本人在这方面是菜鸟,如有错误,还望指出。环境:keil 5.23
硬件:AC780X开发板


    IAP升级的话就需要两部分代码,一个是Bootloader(用于更新APP,并跳转至APP运行),另一个是APP(即真正的应用代码)。
一、Bootloader和APP的flash分配

      根据所用芯片的flash大小,划分boot loader和app的大小。AC7801的flash为128K,从0x08000000~0x08020000。     
      bootloader实现功能简单,一般代码量比较小,我这里分配20K(按实际代码量分配),即范围为0x08000000~0x08004FFF。
      APP则用剩下的108K,范围为0x08005000~0x08020000
      所以,APP的起始地址是0X08005000,这个地址很重要。
在keil下的option for target配置工程flash起始地址和大小。

图1.bootloader flash配置

图2.APP flash配置

二、Bootloader跳转到APP的代码解析

#define APP_ADDRESS   0X08005000  //为APP的起始地址,需要与工程配置中的起始地址一致
typedef void (*pFunction)(void);
static pFunction s_jumpToApp;  //跳转指针
void JumpToApp(void)
{
        uint32_t JumpAddress;
        
        if(((*(__IO uint32_t *)APP_ADDRESS) & 0x2FFE0000) == 0x20000000)  //判断栈顶指针内容是否有效(指向RAM)
        {
                __ASM("CPSID I");//关全局中断
                JumpAddress = *(__IO uint32_t *)(APP_ADDRESS + 4); //取复位中断向量的值
                s_jumpToApp = (pFunction)JumpAddress;
                __set_MSP(*(__IO uint32_t*)APP_ADDRESS);//设置主函数栈指针
                s_jumpToApp(); //执行复位函数
        }

}

第一句: if(((*(__IO uint32_t *)APP_ADDRESS) & 0x2FFE0000) == 0x20000000)
1.这句是判断栈顶地址值是否在0X20000000~0X20020000之间。APP_ADDRESS通过宏定义为0X08005000,即APP的起始地址。
2.(*(__IO uint32_t *)APP_ADDRESS),即取 0X08005000~0X08005003的4个字节的值。因为应用程序APP中设置把中断向量表放在0X08005000开始的位置,而中断向量表里第一个放的就是栈顶地址的值。即这里取出了栈顶地址的值。
3.堆栈指针(SP)必须在SRAM中,SRAM的地址范围都是从0X20000000处开始的,128K的SRAM的地址范围是0X20000000~0X2001FFFF。当APP运行的程序栈顶指针落在SRAM区域时,这个时候就是有效的栈顶指针。
4.也就是说,这句代码通过判断栈顶地址值是否正确(是否在0x20000000~0x2001FFFF之间)来判断是否应用程序已经下载了,因为应用程序的启动文件刚开始就去初始化栈空间。如果栈顶指针对了,说明应用程序已经下载了,启动文件的初始化也执行了,就可以进行跳转。
5.128K的SRAM是比较大的了,用&0x2FFE0000就能覆盖大部分SRAM了,也可以根据实际的SRAM大小修改。
第二句:__ASM("CPSID I")
这句是关掉全局中断。跳转前最好将中断关掉,以防中断向量表还没映射导致程序跑飞。
第三句:JumpAddress = *(__IO uint32_t *)(APP_ADDRESS + 4)
1.这句是取复位中断向量的值
2. (APP_ADDRESS+4)即为0x08005004,里面放的是中断向量表的第二项“复位地址”,执行完完该句后,将复位中断的中断函数地址赋值给JumpAddress。

第四句:s_jumpToApp = (pFunction)JumpAddress
1.这句的意思是将上一句取得的中断函数地址转为函数指针。void (*pFunction)(void);是声明了一个函数指针。
2.此时,s_jumpToApp指向了复位中断函数所在的地址。
第五句:__set_MSP(*(__IO uint32_t*)APP_ADDRESS)
1.这句是设置主函数栈指针
2.__set_MSP,该函数的功能就是设置主栈指针。
第六句:s_jumpToApp()
执行复位函数,跳转到APP运行。


三、APP中配置处理
在APP中,进入main函数,首先应该重映射向量表,再使能全局中断。
int main(void)
{
    SCB->VTOR = APP_ADDRESS;    //重映射向量表
    __ASM("CPSIE I");           //使能全局中断
   
   /*用户代码 */
    GPIO_Config();
    TIMER_Config(1000);

    while(1)
    {
                        
    }
}
VTOR寄存器存放的是中断向量表的起始地址。对于APP,设置为flash基址+偏移量,即0X08005000,所以需要在APP的main函数最开头处添加SCB->VTOR = APP_ADDRESS,实现中断向量表的起始地址的重设。


四、跳转时对中断的处理
     ARM芯片可以实现多个APP,通过boot来控制APP,通过不同的地址选择跳转到不同的APP。
     常用的为Bootloader跳转到APP,若要实现逆向跳转,通过复位即可实现,因为复位后程序会从flash最开始处执行,即bootloader.
     每个APP包括boot loader都有各自的中断向量表,若在相应代码中有使用中断,跳转前需先关闭中断,以免刚跳转过去还没来得及重新设置中断向量表就产生中断,找不到中断入口和执行函数,程序跑飞。
     跳转到APP后,第一时间先将中断向量表的地址重新映射,再使能全局中断,就可以正常运行了。


需要注意的是:APP的工程配置中起始地址是0X08005000,所以程序中设置的APP_ADDRESS必须对应为0x08005000,否则无法正确跳转。



使用特权

评论回复

相关帖子

沙发
勇敢的大白菜| | 2021-9-6 10:01 | 只看该作者
这样操作,没毛病。

使用特权

评论回复
板凳
asmine| | 2021-9-6 10:30 | 只看该作者
太高级了,用的

使用特权

评论回复
地板
caigang13| | 2021-9-7 08:04 | 只看该作者
写的详细,谢谢分享。

使用特权

评论回复
5
两只袜子| | 2021-9-22 10:23 | 只看该作者
很高大上啊,写的很工整仔细

使用特权

评论回复
6
这是神魔节奏| | 2021-10-9 11:49 | 只看该作者
1、我理解的s_jumpToApp(); 应该不算一个复位函数吧,更像是一个指针跳转到特定地址执行程序的功能。
2、如果存储空间够用,可以在eflash中定义一个升级标志位,可以方便APP程序向Boot的跳转,并自动复位DSP跳转到BOOT。

使用特权

评论回复
7
skyred| | 2021-10-11 14:16 | 只看该作者
学习了,
顺便问下,
IROM1和IRAM1那里指的是什么意思

使用特权

评论回复
8
wangjj19950516|  楼主 | 2021-10-11 15:26 | 只看该作者
skyred 发表于 2021-10-11 14:16
学习了,
顺便问下,
IROM1和IRAM1那里指的是什么意思

就是分配flash和RAM的使用起始地址和大小

使用特权

评论回复
9
Q3sky| | 2022-1-26 15:39 | 只看该作者
AC78 车载mcu

使用特权

评论回复
10
LYHYYDS| | 2022-2-17 16:40 | 只看该作者
谢谢讲解

使用特权

评论回复
11
guijial511| | 2022-2-18 08:14 | 只看该作者
讲解详细,谢谢分享。

使用特权

评论回复
12
bartonalfred| | 2022-5-28 15:23 | 只看该作者
是官网的BootLoader吗  

使用特权

评论回复
13
cashrwood| | 2022-5-28 17:01 | 只看该作者
有iap的教程可以学习吗

使用特权

评论回复
14
xiaoyaodz| | 2022-5-29 08:38 | 只看该作者
IAP升级不是很复杂。  

使用特权

评论回复
15
51xlf| | 2022-5-29 09:01 | 只看该作者
app如何跳转?

使用特权

评论回复
16
xidaole| | 2022-12-13 19:36 | 只看该作者
还有吗?

使用特权

评论回复
17
chenci2013| | 2023-1-5 12:07 | 只看该作者
楼主有完整的设计方案的吗?              

使用特权

评论回复
18
i1mcu| | 2023-1-5 12:15 | 只看该作者
这个是应用的指针的吗?              

使用特权

评论回复
19
uptown| | 2023-1-5 15:04 | 只看该作者
这个跳转不成功一般是什么原因呢?

使用特权

评论回复
20
jimmhu| | 2023-1-5 16:03 | 只看该作者
可以实现网络升级单片机的固件的吗?

使用特权

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

本版积分规则

24

主题

86

帖子

2

粉丝