STM32
直播中

周润艺

7年用户 199经验值
私信 关注
[问答]

IAP程序只能跳转到high地址或者low地址中的一个

想做一个IAP,将应用程序轮流的写入两块不同的flash地址中。参照AN2557中的函数写了以下的跳转函数:                                             
#define     __IO    volatile
#define __ASM            __asm
#define low   0x8002000
#define high  0x8008000
typedef unsigned           int uint32_t;
typedef  void (*pFunction)(void);
pFunction Jump_To_Application;
unsigned int JumpAddress;
__ASM void __set_MSP(uint32_t mainStackPointer)
{
msr msp, r0
bx lr
}

JumpAddress = *(__IO uint32_t*) (high/low+4);
Jump_To_Application = (pFunction) JumpAddress;
            __set_MSP(*(__IO uint32_t*) high/low);
      Jump_To_Application();
发现程序只能跳转到high地址或者low地址中的一个,而无论函数            __set_MSP(*(__IO uint32_t*) high/low)中的变量是啥。。。
就算这时候重新烧写IAP程序将其中的变量改成其他的值也还是往原来的地址里跳。
怀疑是函数
__ASM void __set_MSP(uint32_t mainStackPointer)
{
msr msp, r0
bx lr
}
没用对,这个函数我是照抄的没怎么看懂,汇编不会,可能是lr寄存器什么的成为一个定值了。。请各位帮忙看看,实在想不出原因。

回帖(6)

姚伟达

2019-5-31 08:11:04
 __set_MSP函数应该是无问题的。
你说的轮流跳转,不是很明白什么意思。
__set_MSP(*(__IO uint32_t*) high/low);
应该为:
__set_MSP(*(__IO uint32_t*) (high/low));
才对吧。
举报

刘鹏

2019-5-31 08:28:36
就是第一次烧写的是high地址区,运行的代码是
JumpAddress = *(__IO uint32_t*) (high+4);
Jump_To_Application = (pFunction) JumpAddress;
__set_MSP(*(__IO uint32_t*) high);
Jump_To_Application();
而应用程序触发IAP事件后再烧写low地址区:
JumpAddress = *(__IO uint32_t*) (low+4);
Jump_To_Application = (pFunction) JumpAddress;
__set_MSP(*(__IO uint32_t*) low);
Jump_To_Application();
这样可以防止在烧写的过程中发生问题还可以回到上一次烧写的区域继续运行程序
但是我发现第一次进入high地址之后就再也不能跳转到low了,而运行的代码确确实实是
JumpAddress = *(__IO uint32_t*) (low+4);
Jump_To_Application = (pFunction) JumpAddress;
__set_MSP(*(__IO uint32_t*) low);
Jump_To_Application();我用串口在之前输出标志了的。
然后JumpAddress = *(__IO uint32_t*) (high+4);中为什么要在跳转的地址上加四呢
举报

郭武莱

2019-5-31 08:43:37
回复【3楼】zxl6534:
--------------------------------
还是不太明白你的意思。
你这样是把FLASH分为3个区是吧?
BootLoader区
A区(high区)
B区(Low区)
程序一次只能运行一个区的,也就是你从BootLoader区跳到A区还是B区,是通过一些判断标志来决定的,最先下载的肯定是Bootloader区,然后通过BootLoader下载APP代码到A区,某个时刻你想更新了,那么BootLoader通过判断,把程序写入B区,如果写入OK,则设定首先执行的代码是B区代码,如果写入失败,则还是运行A区代码。从而保证无论是否更新成功,都不会导致程序无法运行。
+4是因为最开始的4个字节是用来记录堆栈地址的,而随后的4个字节才是PC指针。
举报

陈茗卓

2019-5-31 08:55:50
对的,就是这个意思。我发现进入A区后就再也不能进入B区了。。。而且判断标志标明运行的确实是跳转进入B区的函数。而且现在我还发现进入过一次A区后,我把BOOTLOADER区的程序重用ISP烧写,直接让它跳转进入B区,程序居然照样跳A区,这个我是直接通过修改HEX文件在A区加入程序结果发现跳转后运行的是A区的程序
举报

更多回帖

发帖
×
20
完善资料,
赚取积分