久芯网

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

avatar 梦想27 提问时间: 2023-08-13 17:02:54 / 未解决

使用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个回答
  • avatar 废鱼
    回答时间: 2023-08-13 17:21:56

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

  • avatar 梦想27
    回答时间: 2023-08-13 17:45:00
    废鱼 发表于 2021-12-28 10:03
    楼主您好,请查看一下APP应用程序生成的HEX文件,里面有写实际的地址都是哪些。我怀疑是不是生成APP文 ...

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

  • avatar xmshao
    回答时间: 2023-08-13 18:14:18

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

  • avatar 废鱼
    回答时间: 2023-08-13 18:34:48

    if(((*(vu32*)appxaddr)&0x2FF00000)==0x20000000) //检查栈顶地址是否合法. 看一下这里,是不是读取出的地址不对所以没有跳转。加一下打印看看。最好是先刷好APP程序,然后再仿真bootloader进行仿真,看看代码执行到哪一步出错的。

  • avatar 梦想27
    回答时间: 2023-08-13 19:07:13
    废鱼 发表于 2021-12-28 10:21
    if(((*(vu32*)appxaddr)&0x2FF00000)==0x20000000) //检查栈顶地址是否合法.

    看一下这里,是不是 ...

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

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

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

  • avatar 废鱼
    回答时间: 2023-08-13 19:57:23

    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

  • avatar lee_479
    回答时间: 2023-08-13 20:15:30

    楼主搞定了吗?这个问题我也遇到了,说下我的解决你参考下: 1、我的芯片是stm32f207zgt6,iap参考的f407的代码写的; 2、iap中修改如下:(0x20000000改成0x20020000) if(((*(vu32*)appxaddr)&0x2FF00000)==0x20020000) //检查栈顶地址是否合法. 3、跳转前去初始化: // HAL_UART_DeInit(&huart1); / 不能打开注释,一开就不能正常跳转 / HAL_SuspendTick(); HAL_RCC_DeInit(); HAL_DeInit(); 我这一步老跑飞,最后把HAL_UART_DeInit 串口的注释掉,增加了HAL_RCC_DeInit();才正常跳转了

会员中心 微信客服
客服
回到顶部