6854|18

67

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

STM32IAP问题。求助 [复制链接]



最近在搞STM32 的IAP。发现一个很奇怪的问题。
在程序A里面,跳转到程序B执行。
A存放在0x08000000,B存放在0x0800e000.

起初,B使用的内存大概6K,其中堆栈使用了4K。此时如果从程序A跳到程序B,B出现死机。但是如果用仿真器直接运行B是可以运行的。

实在不知道什么问题,后来B的堆栈改小,设为1K,这是就正常了。能从程序A跳转到程序B,并且B也能正常运行。

请问这是什么原因?程序B的运行为什么后它的内存大小的影响呢?
片子是STM32F103R8T6.

望高手解答!! 谢谢了。
此帖出自stm32/stm8论坛

最新回复

                                  还得再啰嗦几句,楼主所说的“把PSP和MSP都重新设置”指的是在函数JumpBootloaderProgram中又加入了一句__set_PSP(*(volatile unsigned int*) ApplicationAddress)吗?如果是这样,貌似跳转到B之后还有隐患,因为由A跳到B后,主程序用的是PSP,而中断服务程序仍要使用MSP,因为CM3的中断服务是“处理模式”,只能使用MSP。如果在跳转到B之前把MSP和PSP设为同样值的话,那么B程序的中断服务程序在使用堆栈的同时,很可能也改写了主程序的堆栈中的内容。所以我觉得最好在由A跳转到B之前,在调用__set_MSP(*(volatile unsigned int*) ApplicationAddress)之前,把当前使用的堆栈指针由PSP改回MSP,然后再设置MSP,再跳转,这样比较好一些,跳转到B之后,无论主程序还是中断服务程序都只使用MSP,也就不会冲突了。  详情 回复 发表于 2010-3-18 14:59
点赞 关注
 

回复
举报

66

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
感觉是否内存冲突啊————(0x0800e000+6K+4k)>内存上限
       没做过STM32 的IAP的人路过
此帖出自stm32/stm8论坛
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
谢谢。呵呵。
0x0800e000是flash的地址。
内存用的6K包括了堆栈的4K。

继续等待。。。
此帖出自stm32/stm8论坛
 
 

回复

87

帖子

0

TA的资源

一粒金砂(初级)

4
 
                                 感觉是你在跳转到B的时候没有把程序B的主堆栈进行初始化,这样程序B在运行的时候还在使用程序A的堆栈指针,很可能会与程序B的全局变量区混到一起了,执行情况就没法预知了,会有某些奇怪现象发生。
此帖出自stm32/stm8论坛
 
 
 

回复

88

帖子

0

TA的资源

一粒金砂(初级)

5
 
                                 呵呵,发现楼主的结贴率是0%啊
此帖出自stm32/stm8论坛
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

6
 
                                 同意4楼观点。
此帖出自stm32/stm8论坛
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

7
 
呵呵。新手,很少灌水,见谅啊。

那程序B在开始运行的时候,不会进行初始化吗?
还是在A调用B之前,需要做什么工作?
A跳转B的代码如下:
void BSP_GPIO_Config(void);
void BSP_Int_Config(void);

#define ApplicationAddress 0x0800e000
typedef  void (*pFunction)(void);

void DisableAllNVIC(void)
{
  for(int i=19; i < 59; i++)
  {
    NVIC->ICER[i >> 0x05] =(unsigned int )0x01 << (i & (unsigned char)0x1F);
  }
}

void DisableAllGPIO(void)
{
    GPIO_InitTypeDef       gpio_init;
    gpio_init.GPIO_Pin    = 0xffff;
    gpio_init.GPIO_Speed  = GPIO_Speed_50MHz;
    gpio_init.GPIO_Mode   = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &gpio_init);
    GPIO_Init(GPIOB, &gpio_init);
    GPIO_Init(GPIOC, &gpio_init);
    GPIO_Init(GPIOD, &gpio_init);
    GPIO_Init(GPIOE, &gpio_init);
    GPIO_Init(GPIOF, &gpio_init);

}


void JumpBootloaderProgram(void)
{
    int JumpAddress;
    pFunction Jump_To_Application;
   
    DisableAllNVIC();
    DisableAllGPIO();
   
    JumpAddress = *(volatile unsigned int*) (ApplicationAddress + 4);
    Jump_To_Application = (pFunction) JumpAddress;
    __set_MSP(*(volatile unsigned int*) ApplicationAddress);
    Jump_To_Application();
}
此帖出自stm32/stm8论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

8
 
猜错了,不是我猜的问题。
应该不是从A刚跳到B就死机了吧,从A跳到B后有一段编译器生成的启动代码,有可能是在那里出现问题了,然后进入fault了。单步调试看看吧,从A跳到B后,单步运行,看在哪里跳到fault的,不过得先找到B程序的fault的地址,因为在仿真环境下由程序A跳到B,是看不到B的代码的,只能看到汇编码和机器码。
此帖出自stm32/stm8论坛
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

9
 
有没有程序A和程序B的map文件
看一下他们空间的使用的情况

JumpBootloaderProgram是在什么时候调用的
中断向量表是如何处理的?
此帖出自stm32/stm8论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

10
 
A和B的flash区 是肯定分开的。。
但是ram区,应该是有重叠的,因为我是2个独立的工程。
贴出他们的icf文件:
______________________
A:
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
define symbol __ICFEDIT_region_ROM_end__   = 0x0800dFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__   = 0x20004FFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x1000;
define symbol __ICFEDIT_size_heap__   = 0x200;
/**** End of ICF editor section. ###ICF###*/


define memory mem with size = 4G;
define region ROM_region   = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
define region RAM_region   = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];

define symbol __region_USB_PKG_RAM_start__  = 0x40006000;
define symbol __region_USB_PKG_RAM_end__    = 0x400063FF;
define region USB_PKG_RAM_region = mem:[from __region_USB_PKG_RAM_start__ to __region_USB_PKG_RAM_end__];



define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };

initialize by copy { readwrite };
do not initialize  { section .noinit };
do not initialize  { section USB_PACKET_MEMORY };

place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in USB_PKG_RAM_region
                      { readwrite data section USB_PACKET_MEMORY  };
place in ROM_region   { readonly };
place in RAM_region   { readwrite,
                        block CSTACK, block HEAP };

__________________________________
B:

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x0800e000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x0800e000 ;
define symbol __ICFEDIT_region_ROM_end__   = 0x0800ffff;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__   = 0x20004FFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__   = 0x200;
/**** End of ICF editor section. ###ICF###*/


define memory mem with size = 4G;
define region ROM_region   = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
define region RAM_region   = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];

define symbol __region_USB_PKG_RAM_start__  = 0x40006000;
define symbol __region_USB_PKG_RAM_end__    = 0x400063FF;
define region USB_PKG_RAM_region = mem:[from __region_USB_PKG_RAM_start__ to __region_USB_PKG_RAM_end__];



define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };

initialize by copy { readwrite };
do not initialize  { section .noinit };
do not initialize  { section USB_PACKET_MEMORY };

place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in USB_PKG_RAM_region
                      { readwrite data section USB_PACKET_MEMORY  };
place in ROM_region   { readonly };
place in RAM_region   { readwrite,
                        block CSTACK, block HEAP };



至于如何调用,是A程序接收pc端指令后,进行跳转。。。
此帖出自stm32/stm8论坛
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

11
 
                                 跳转代码和连接文件没看出有什么问题。建议楼主先弄清楚是在什么地方死机的,怎么个死法?比如是进入fault了还是程序自己跑飞? A和B的ram区域虽然重叠,但B程序的启动代码会把RW和RO区域的内存进行初始化,所以ram重叠应该不是问题。重点检查一下寄存器,因为从A跳到B之后,寄存器的值可能不是上电后的默认值,有可能造成B程序的运行环境与用仿真器直接运行时不同。
此帖出自stm32/stm8论坛
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

12
 
A和B的flash区 是肯定分开的。。
至于如何调用,是A程序接收pc端指令后,进行跳转。。。
这个"A程序接收pc端指令后,进行跳转"是在中断里面吗?

简单的办法,你在执行Jump_To_Application();
之前看一下xPSR的值,如果在中断中某些位为当前中断号
此帖出自stm32/stm8论坛
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

13
 
对,B要充分认识到A之前做了什么东西……
要是我,A肯定做得很小而且用最少的资源,顶多开一个定时器和串口
做的时候充分阅读ST提供的串口IAP例程,打开它的option逐项阅读……我的做法就是直接在上面修改。Flash和Ram的设置可以在菜单里直接设的,尽量不要自己手工去修改文件。
此帖出自stm32/stm8论坛
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

14
 
                                 我也很少去手工修改里面的文件,很容易出问题
此帖出自stm32/stm8论坛
 
 
 

回复

89

帖子

0

TA的资源

一粒金砂(初级)

15
 
                                 嗯,除非你是高手
此帖出自stm32/stm8论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

16
 
多谢各位高手的指点。呵呵。。
可能是A用到的一些外设或资源没有被重新初始化,而直接运行B,导致了B的运行不正常。对吧。

比如A开启了一些外设、中断,之后只是关闭了所有的中断,我是用DisableAllNVIC()实现的,就直接运行B,会对B有影响吗?

B的内存用的小就可以,大就不可以,B能运行和不能运行仅仅就这点区别。对这点我比较疑惑,难道是内存冲突了?呵呵。

还有我保留一个观点:对于A使用的资源的多少应该没有限制吧,仅仅让A用很少的资源来保证程序的正常运行,是不是带有侥幸心理呢。


12楼:我不是在中断里跳转的。但是A的程序我是用ucos2的。谢谢~
此帖出自stm32/stm8论坛
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

17
 
16楼:
A程序用了ucos2,而且不是在中断里跳转到B,那应该是在某个任务里跳转的吧。ucos2的官方移植版本,任务里使用的堆栈指针是PSP,如果你的A程序是在使用PSP的任务里跳转到B程序的,那么函数void JumpBootloaderProgram(void)中的__set_MSP(*(volatile unsigned int*) ApplicationAddress)函数并没有使跳转到B后的堆栈指针初始化为主堆栈指针,即跳转到B后还是使用的程序A的PSP,问题可能会出在这里。
此帖出自stm32/stm8论坛
 
 
 

回复

54

帖子

0

TA的资源

一粒金砂(初级)

18
 
多谢ShakaLeo!!
我在把PSP和MSP都重新设置后,就没有问题了。呵呵。。
多谢各位高手的指点!
哎,主要还是对Cortex-M3不熟啊,好好看书,好好学习。
此帖出自stm32/stm8论坛
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

19
 


还得再啰嗦几句,楼主所说的“把PSP和MSP都重新设置”指的是在函数JumpBootloaderProgram中又加入了一句__set_PSP(*(volatile unsigned int*) ApplicationAddress)吗?如果是这样,貌似跳转到B之后还有隐患,因为由A跳到B后,主程序用的是PSP,而中断服务程序仍要使用MSP,因为CM3的中断服务是“处理模式”,只能使用MSP。如果在跳转到B之前把MSP和PSP设为同样值的话,那么B程序的中断服务程序在使用堆栈的同时,很可能也改写了主程序的堆栈中的内容。所以我觉得最好在由A跳转到B之前,在调用__set_MSP(*(volatile unsigned int*) ApplicationAddress)之前,把当前使用的堆栈指针由PSP改回MSP,然后再设置MSP,再跳转,这样比较好一些,跳转到B之后,无论主程序还是中断服务程序都只使用MSP,也就不会冲突了。
此帖出自stm32/stm8论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表