OpenEdv-开源电子网

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

求助原子哥关于IAP代码的问题

[复制链接]

5

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2016-8-19
在线时间
23 小时
发表于 2016-9-30 10:29:41 | 显示全部楼层 |阅读模式
5金钱
官方的IAP跳转如下
else
  {
    /* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */
    if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
    {
      /* Jump to user application */
      JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
      Jump_To_Application = (pFunction) JumpAddress;
      /* Initialize user application's Stack Pointer */
      __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
      Jump_To_Application();
    }
  }


原子哥的如下
if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
                        {         
                                iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码
                        }

求助大家红体部分 0x2FFE0000 ) == 0x20000000)    0xFF000000)==0x08000000)
这有什么区别,还有APP地址后面+4是为了向量表吗?谢谢


最佳答案

查看完整内容[请看2#楼]

前者是判断是否属于内存范围。后者是判断是否属于FLASH范围。 +4是指向reset 向量地址。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2016-9-30 10:29:42 | 显示全部楼层
前者是判断是否属于内存范围。后者是判断是否属于FLASH范围。  +4是指向reset 向量地址。
回复

使用道具 举报

19

主题

430

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1341
金钱
1341
注册时间
2016-4-22
在线时间
187 小时
发表于 2016-9-30 11:14:48 | 显示全部楼层
你搞错了吧。APPLICATION_ADDRESS  跟 FLASH_APP1_ADDR+4 不是一个地址

原子的是在函数里判断
void iap_load_app(u32 appxaddr)
{
        if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)        //¼ì2éÕ»¶¥μØÖ·êÇ·ñoÏ·¨.
        {
                jump2app=(iapfun)*(vu32*)(appxaddr+4);                //óû§′úÂëÇøμú¶t¸ö×ÖÎa3ìDò¿aê¼μØÖ·(¸′λμØÖ·)               
                MSR_MSP(*(vu32*)appxaddr);                                        //3õê¼»ˉAPP¶ÑÕ»Ö¸Õë(óû§′úÂëÇøμÄμúò»¸ö×ÖóÃóú′æ·ÅÕ»¶¥μØÖ·)
                jump2app();                                                                        //ìø×aμ½APP.
        }
}       
伤情最是晚凉天,憔悴斯人不堪怜。
邀酒摧肠三杯醉,寻香惊梦五更寒。
钗头凤斜卿有泪,荼蘼花了我无缘。
小楼寂寞新雨月,也难如钩也难圆。
回复

使用道具 举报

15

主题

34

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
224
金钱
224
注册时间
2016-11-30
在线时间
42 小时
发表于 2017-1-10 22:28:53 | 显示全部楼层
同问,求解
回复

使用道具 举报

16

主题

216

帖子

1

精华

高级会员

Rank: 4

积分
970
金钱
970
注册时间
2016-11-24
在线时间
156 小时
发表于 2017-1-11 09:33:14 | 显示全部楼层
这两个的区别是0x20000000是跳转到RAM去运行,0x08000000是跳转到FLASH去运行,至于是0x20000000还是0x08000000这个就是我们跳转的APP的bin文件设置的,也就是说这个APP程序在编写的时候,在option for Target里面IROM1设置的地址。原子哥的跳转是把bin文件的内容拷贝到指定的RAM,然后在跳转运行的,所以是判断0x20000000,如果你要跳转的程序是在FLASH里面运行,那就是0x08000000。需要注意的是原子哥的跳转,由于RAM的大小有限,所以对bin文件有大小限制,在100K左右。+4我看了好像就是向量表的地址偏移。
回复

使用道具 举报

70

主题

6761

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13092
金钱
13092
注册时间
2012-11-26
在线时间
3810 小时
发表于 2017-1-11 09:42:04 | 显示全部楼层
lzq12 发表于 2017-1-11 09:33
这两个的区别是0x20000000是跳转到RAM去运行,0x08000000是跳转到FLASH去运行,至于是0x20000000还是0x0800 ...

正解
学无止境
回复

使用道具 举报

0

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
192
金钱
192
注册时间
2017-9-17
在线时间
19 小时
发表于 2017-10-30 09:40:22 | 显示全部楼层
lzq12 发表于 2017-1-11 09:33
这两个的区别是0x20000000是跳转到RAM去运行,0x08000000是跳转到FLASH去运行,至于是0x20000000还是0x0800 ...

请问一下:
原子哥的代码里
#define FLASH_APP1_ADDR                0x08010000          //第一个应用程序起始地址(存放在FLASH)
                if(key==KEY1_PRES)
                {
                        printf("开始执行FLASH用户代码!!\r\n");
                        if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
                        {         
                                iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码
                        }else
                        {
                                printf("非FLASH应用程序,无法执行!\r\n");
                                LCD_ShowString(30,210,200,16,16,"Illegal FLASH APP!");          
                        }                                                                         
                        clearflag=7;//标志更新了显示,并且设置7*300ms后清除显示          
                }

//跳转到应用程序段
//appxaddr:用户代码起始地址.
void iap_load_app(u32 appxaddr)
{
        if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)        //检查栈顶地址是否合法.
        {
                jump2app=(iapfun)*(vu32*)(appxaddr+4);                //用户代码区第二个字为程序开始地址(复位地址)               
                MSR_MSP(*(vu32*)appxaddr);                                        //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
                jump2app();                                                                        //跳转到APP.
        }
}       

执行的是Flash里的代码,为什么调用void iap_load_app(u32 appxaddr) 里面开始就判断if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)  麻烦解惑一下,感谢!!!
回复

使用道具 举报

16

主题

216

帖子

1

精华

高级会员

Rank: 4

积分
970
金钱
970
注册时间
2016-11-24
在线时间
156 小时
发表于 2017-11-3 10:47:11 | 显示全部楼层
zhanminlove 发表于 2017-10-30 09:40
请问一下:
原子哥的代码里
#define FLASH_APP1_ADDR                0x08010000          //第一个应用程序起始地址(存放在FL ...

你这个是要跳转到FLASH里面去的,要改成==0x08000000,因为程序存放在FLASH里面,地址是从0x08000000开始的,如果你的程序是存放在RAM里面,那就是要判断==0x20000000
回复

使用道具 举报

0

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
192
金钱
192
注册时间
2017-9-17
在线时间
19 小时
发表于 2017-11-4 10:21:41 | 显示全部楼层
lzq12 发表于 2017-11-3 10:47
你这个是要跳转到FLASH里面去的,要改成==0x08000000,因为程序存放在FLASH里面,地址是从0x08000000开始 ...

谢谢回复!
后面我重新理解下 ,觉得可能是没问题的,if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)        //检查栈顶地址是否合法.   ,我把(*(vu32*)appxaddr))这个值 打印出来 发现就是堆栈SP的值0x20000EB8, 就像原子哥的注释里写的判断栈顶地址是否合法, &0x2FFE0000 是因为SRAM大小为64k,
if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.   这里FLASH_APP1_ADDR+4 是复位中断向量的地址(*(vu32*)(FLASH_APP1_ADDR+4)) 打印出来是PC指针的值0x0800578C  &0xFF000000==0x08000000,应该就是你说的程序存放在FLASH里面  
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-19 01:55

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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