你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

使用CUBE IDE无法通过IAP跳转APP进行软件升级

[复制链接]
梦想27 提问时间:2021-12-28 09:48 / 未解决

使用CUBE IDE无法通过IAP跳转APP进行软件升级

本人使用的是cubeide 1.7.0版本,单片机是STM32F407VET6.在这个IDE工具下,成功实现STM32F103RCT6单片机的升级,却无法实现F407这款芯片的升级,我不确定问题出现在哪,我尝试使用KEIL进行软件编译,下载,在这个工具下F407也能实现IAP升级。

以下是我的IAP具体代码

int main(void)

{

HAL_Init(); //初始化HAL库

Stm32_Clock_Init(336,8,2,7); //设置时钟,168Mhz

delay_init(168); //初始化延时函数

LED_Init(); //初始化LED

while(1)

{

    HAL_GPIO_WritePin(GPIOE,GPIO_PIN_3,GPIO_PIN_RESET);    //PF9置1,默认初始化后灯灭



    delay_ms(1000);

    HAL_GPIO_WritePin(GPIOE,GPIO_PIN_4,GPIO_PIN_RESET);    //PF10置1,默认初始化后灯灭

    delay_ms(1000);

    iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码  

}

}

上面的引导代码使用两个一秒的闪灯进行识别,

我也尝试过直接跳转,代码如下,依然无效,无效说的是无法跳转到IDE生成的APP程序,可以成功跳转KEIL的APP程序。

int main(void)

{

while(1)

{



    iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码  

}

}

上面的代码中跳转的地址定义的是 :#define FLASH_APP1_ADDR 0x08020000 //第一个应用程序起始地址(存放在FLASH)。代码源码来自正点原子开发板的IAP例程。其中我也尝试过在跳转前关闭全局中断,开启全局中断,或者关闭时钟等各种办法,均无法实现跳转。

//跳转到应用程序段

//appxaddr:用户代码起始地址.

void iap_load_app(u32 appxaddr)

{

if(((*(vu32*)appxaddr)&0x2FF00000)==0x20000000)    //检查栈顶地址是否合法.

{ 



    SysTick->CTRL = 0;                                //关键代码

    HAL_DeInit();                                     //可选

    HAL_NVIC_DisableIRQ(SysTick_IRQn);                //可选

    HAL_NVIC_ClearPendingIRQ(SysTick_IRQn);           //可选



    /* Jump to user application */

    __disable_irq();

    jump2app=(iapfun)*(vu32*)(appxaddr+4);        //用户代码区第二个字为程序开始地址(复位地址)      

    MSR_MSP(*(vu32*)appxaddr);                    //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)

    jump2app();                                    //跳转到APP.

}

}

以下是我的APP具体代码

int main(void)

{

/ USER CODE BEGIN 1 /

__enable_irq();

/ USER CODE END 1 /

/ MCU Configuration--------------------------------------------------------/

/ Reset of all peripherals, Initializes the Flash interface and the Systick. /

HAL_Init();

/ USER CODE BEGIN Init /

/ USER CODE END Init /

/ Configure the system clock /

SystemClock_Config();

/ USER CODE BEGIN SysInit /

/ USER CODE END SysInit /

/ Initialize all configured peripherals /

MX_GPIO_Init();

/ USER CODE BEGIN 2 /

/ USER CODE END 2 /

/ Infinite loop /

/ USER CODE BEGIN WHILE /

while (1)

{

/* USER CODE END WHILE */



/* USER CODE BEGIN 3 */

    HAL_GPIO_WritePin(GPIOE,GPIO_PIN_3,GPIO_PIN_RESET);    //PF9�???1,默认初始化后灯�???

    HAL_GPIO_WritePin(GPIOE,GPIO_PIN_4,GPIO_PIN_SET);    //PF10�???1,默认初始化后灯�???

    HAL_Delay(500);

    HAL_GPIO_WritePin(GPIOE,GPIO_PIN_3,GPIO_PIN_SET);    //PF9�???1,默认初始化后灯�???

    HAL_GPIO_WritePin(GPIOE,GPIO_PIN_4,GPIO_PIN_RESET);    //PF10�???1,默认初始化后灯�???

    HAL_Delay(500);

}

/ USER CODE END 3 /

}

APP程序中只开启了两个闪灯,未使用FREERTOS系统,即使不开启SystemClock_Config();依然无法跳转。

相比直接生成的代码,我修改了以下三个地方:

第一,在main函数添加__enable_irq();,尝试开启或不使用,没有作用;

第二,在STM32F407VETX_FLASH.ld文件下修改起始地址和长度,原本是

MEMORY

{

CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K

RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K

FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K

}

修改为

MEMORY

{

CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K

RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K

FLASH (rx) : ORIGIN = 0x8020000, LENGTH = 384K

}

第三,在system_stm32f4xx.c文件下修改偏移地址,修改后如下:

{

........

define USER_VECT_TAB_ADDRESS

if defined(USER_VECT_TAB_ADDRESS)

/*!

收藏 评论8 发布时间:2021-12-28 09:48

举报

8个回答
废鱼 回答时间:2021-12-28 10:03:28

楼主您好,请查看一下APP应用程序生成的HEX文件,里面有写实际的地址都是哪些。我怀疑是不是生成APP文件的使用地址是不对的,所以跳转不过去。

梦想27 回答时间:2021-12-28 10:15:04

废鱼 发表于 2021-12-28 10:03
楼主您好,请查看一下APP应用程序生成的HEX文件,里面有写实际的地址都是哪些。我怀疑是不是生成APP文 ...

[md]###### 感谢关注,这个疑问我也是怀疑过的,我查看过hex文件,地址确实是08020000起始开始,使用的查看工具是segger j-flash软件

xmshao 回答时间:2021-12-28 10:15:26
可以肯定,不论是F1还是F4系列,做IAP设计时的基本操作是一样的。你注意下跳转前是否将所有中断使能都关闭了,包括SYSTICK的。再就是确认下中断矢量表地址给对了没有,跳转地址是否给对了。即使基于STM32CubeIDE也有相关例程,可以参考下基本步骤。\STM32Cube\Repository\STM32Cube_FW_F4_V1.26.2\Projects\STM324xG_EVAL\Applications\IAP
废鱼 回答时间:2021-12-28 10:21:37

if(((*(vu32*)appxaddr)&0x2FF00000)==0x20000000) //检查栈顶地址是否合法.

看一下这里,是不是读取出的地址不对所以没有跳转。加一下打印看看。最好是先刷好APP程序,然后再仿真bootloader进行仿真,看看代码执行到哪一步出错的。

梦想27 回答时间:2021-12-28 10:45:31

废鱼 发表于 2021-12-28 10:21
<code>if(((*(vu32*)appxaddr)&amp;amp;0x2FF00000)==0x20000000)    //检查栈顶地址是否合法.</code></p>
<p>看一下这里,是不是 ...

[md]栈顶地址判断是合法的 ,就是最后一步无法跳转,立马进入硬件异常中断。所以我真的怀疑是IDE有bug

梦想27 回答时间:2021-12-28 10:49:09

xmshao 发表于 2021-12-28 10:15
可以肯定,不论是F1还是F4系列,做IAP设计时的基本操作是一样的。你注意下跳转前是否将所有中断使能都关闭 ...

这些已经试过了,我的代码上也写了。至于你说的生成的是一样,确实正常的情况下是没问题的,出现问题的可能是,1,我误操作了哪个部分导致的,2,ide本身存在bug,这也不是不可能,毕竟软件一直更新。最好的解决方法是有一个同型号的ide例程参考。如果是参考官方例程,没有意义,他那个也是用keil的,我这边用keil是可以实现功能的

废鱼 回答时间:2021-12-28 11:37:55

CUBE IDE 用的是GCC的编译方式,可能是最后一句gcc和keil的用法有点出入。找一下gcc的使用方法来替换。

if defined ( __CC_ARM ) /------------------RealView Compiler -----------------/

__asm void MSR_MSP(uint32_t addr) { MSR MSP, r0 //set Main Stack value BX r14 }

elif (defined (GNUC)) /------------------ GNU Compiler ---------------------/

void MSR_MSP(uint32_t addr) attribute( ( naked ) ); void MSR_MSP(uint32_t addr) { __ASM volatile ("MSR MSP, r0\n\t" "BX r14\n\t" ); }

endif

lee_479 回答时间:2022-3-11 10:36:42

楼主搞定了吗?这个问题我也遇到了,说下我的解决你参考下:

1、我的芯片是stm32f207zgt6,iap参考的f407的代码写的;

2、iap中修改如下:(0x20000000改成0x20020000)

if(((*(vu32*)appxaddr)&amp;0x2FF00000)==0x20020000) //检查栈顶地址是否合法.

3、跳转前去初始化:

// HAL_UART_DeInit(&huart1); / 不能打开注释,一开就不能正常跳转 / HAL_SuspendTick(); HAL_RCC_DeInit();
HAL_DeInit();

我这一步老跑飞,最后把HAL_UART_DeInit 串口的注释掉,增加了HAL_RCC_DeInit();才正常跳转了

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版