OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 16115|回复: 6

IAP程序跳转的奇怪现象

[复制链接]

12

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
100
金钱
100
注册时间
2011-10-11
在线时间
0 小时
发表于 2011-11-22 15:26:00 | 显示全部楼层 |阅读模式

想做一个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寄存器什么的成为一个定值了。。请各位帮忙看看,实在想不出原因。

 

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2011-11-22 18:21:51 | 显示全部楼层
 __set_MSP函数应该是无问题的。
你说的轮流跳转,不是很明白什么意思。
__set_MSP(*(__IO uint32_t*) high/low);
应该为:
__set_MSP(*(__IO uint32_t*) (high/low));
才对吧。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

12

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
100
金钱
100
注册时间
2011-10-11
在线时间
0 小时
 楼主| 发表于 2011-11-23 08:32:02 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
就是第一次烧写的是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);中为什么要在跳转的地址上加四呢
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2011-11-23 08:54:46 | 显示全部楼层
回复【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指针。



我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

12

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
100
金钱
100
注册时间
2011-10-11
在线时间
0 小时
 楼主| 发表于 2011-11-23 09:05:58 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
对的,就是这个意思。我发现进入A区后就再也不能进入B区了。。。而且判断标志标明运行的确实是跳转进入B区的函数。而且现在我还发现进入过一次A区后,我把BOOTLOADER区的程序重用ISP烧写,直接让它跳转进入B区,程序居然照样跳A区,这个我是直接通过修改HEX文件在A区加入程序结果发现跳转后运行的是A区的程序
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2011-11-23 09:18:40 | 显示全部楼层
那说明你的程序没弄对。
或者更新程序就更新错了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

12

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
100
金钱
100
注册时间
2011-10-11
在线时间
0 小时
 楼主| 发表于 2011-11-23 09:56:28 | 显示全部楼层
回复【6楼】正点原子:
---------------------------------
  试出来了,原来MDK里option of target里选择flash的起始地址不同生成的hex文件除了每行的4~7字节的地址不同以外后面的数据字节也是不一样的,而我想当然的以为只是前面的地址不同而已,所以在烧写的A区和B区的时候都是用起始地址是A区生成的HEX文件,只修改了4~7字节的地址。可能hex文件的前几行也是关于堆栈和pc指针的操作,所以应该是程序先跳转到了B区然后又跳回了A区,谢谢原子,纠结一周了   
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-24 13:30

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表