ST意法半导体
直播中

zhongnian

9年用户 1453经验值
擅长:MEMS/传感技术
私信 关注
[问答]

使用cubeide生成APP程序的bin文件写入Flash之后,无法跳转到APP程序中,怎么解决?

实现IAP功能,使用cubeide生成APP程序的bin文件写入Flash之后,无法跳转到APP程序中。
但是使用KEIL编译生成的bin文件写入FLASH之后,可以正常执行。

在检查栈顶地址是否合法的那一步不通过。APP程序还需要修改哪些地方

Boot Loader部分代码:
/*****************************************************************************************/
VTOR = APP_Address;
        __enable_irq();




        uint16_t i = 0;
        uint8_t updata_cmd[7] = {0xF5, 0x00, 0xeb, 0x00, 0x00, 0xe0, 0xfa};
        uint8_t temp_buf[7] = {0};
  /* 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();
  MX_DMA_Init();
  MX_USB_DEVICE_Init();
  MX_TIM14_Init();
  MX_USART6_UART_Init();
  /* USER CODE BEGIN 2 */


  /* USER CODE END 2 */


  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
          if(USB_RxIndex > 0)
          {
                  memcpy(temp_buf, USB_RxBuf, 7);
                  /* F5 00 eb 00 00 e0 fa */
                  if(strcmp((char *)updata_cmd, (char *)temp_buf) == 0)
                  {
                          for (i = 0; i < 8; i++)
                          {
                                  NVIC->ICER=0xFFFFFFFF;
                                  NVIC->ICPR=0xFFFFFFFF;
                          }
                          NVIC_SystemReset(); // 复位单片机
                  }


                  printf("nrx:");
                  for(i = 0; i < USB_RxIndex; i++)
                  {
                          if(temp_buf > 0x0F)
                                  printf("%x ", temp_buf);
                          else
                                  printf("0%x ", temp_buf);
                  }
                  printf("n");


                  USB_RxIndex = 0;
          }
    /* USER CODE END WHILE */


    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}



/*****************************************************************************************/


STM32F407ZGTX_FLASH.ld中修改
/*****************************************************************************************/
/* Memories definition */
MEMORY
{
  CCMRAM    (xrw)    : ORIGIN = 0x10000000,   LENGTH = 64K
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 128K
  FLASH    (rx)    : ORIGIN = 0x08020000,   LENGTH = 896K
}




/*****************************************************************************************/
看网上的历程好像也只是添加了
SCB->VTOR = APP_Address;
和修改了STM32F407ZGTX_FLASH.ld中的FLASH。


回帖(1)

幽默

2025-6-16 17:44:52

要解决使用CubeIDE生成的APP程序bin文件无法跳转的问题,需确保以下关键配置正确。以下是逐步解决方案:




1. 修改APP程序的链接脚本(.ld文件)



  • 在CubeIDE中打开APP工程的链接脚本(如STM32XXXX_FLASH.ld)。

  • 修改Flash的起始地址为APP存储地址(如0x08008000),并调整长度:
     MEMORY {
       FLASH (rx)  : ORIGIN = 0x08008000, LENGTH = 256K   /* 示例地址 */
       RAM (xrw)   : ORIGIN = 0x20000000, LENGTH = 64K
    }

  • 确认栈顶地址_estack在RAM范围内:
     _estack = ORIGIN(RAM) + LENGTH(RAM); /* 确保不越界 */




2. 设置中断向量表偏移(VTOR)



  • 方法1:在main.cmain()函数开头添加:
     SCB->VTOR = FLASH_BASE | 0x8000; // 示例:偏移0x8000字节

  • 方法2:修改SystemInit函数(在system_stm32xx.c中):
    定义宏VECT_TAB_OFFSET=0x8000(通过IDE配置或在文件中设置):
     // system_stm32xx.c
    #define VECT_TAB_OFFSET 0x8000
    void SystemInit(void) {
       SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;
    }




3. 优化Boot Loader跳转逻辑



  • 关闭所有中断:跳转前确保中断已禁用。
     __disable_irq(); // 关闭总中断

  • 精确栈顶地址检查
     uint32_t sp = *(__IO uint32_t*)APP_ADDRESS;
    uint32_t valid_ram_end = 0x20000000 + RAM_SIZE; // RAM_SIZE = 如0x20000 (128KB)
    if (sp >= 0x20000000 && sp <= valid_ram_end) { // 精确范围检查
       __set_MSP(sp); // 设置主堆栈指针
       uint32_t reset_vector = *(__IO uint32_t*)(APP_ADDRESS + 4);
       ((void(*)(void))reset_vector)(); // 跳转到APP
    }

  • 清除中断标志:跳转前清除所有挂起中断:
     for (int i = 0; i < 8; i++) {
       NVIC->ICER[i] = 0xFFFFFFFF; // 禁用中断
       NVIC->ICPR[i] = 0xFFFFFFFF; // 清除挂起标志
    }




4. 检查APP程序初始化



  • 确保APP工程配置:

    • No Bootloader:在Project Properties > C/C++ Build > Settings > MCU Settings中取消勾选"Use Float with nano"等选项。


  • 生成.bin文件:在工程属性中配置Post-build步骤:
     arm-none-eabi-objcopy -O binary "${BuildArtifactFileName}" "${BuildArtifactFileBaseName}.bin"




5. 验证调试配置



  • 复位向量正确性:用ST-Link Utility或CubeProgrammer查看Flash内容:

    • 地址0x08008000:应存放_estack值(栈顶地址)。

    • 地址0x08008004:应存放Reset_Handler地址。


  • 地址对齐:确保APP地址是0x200的倍数(某些芯片要求)。




6. 其他常见问题



  • 编译器优化差异:检查Keil与CubeIDE的优化级别是否一致(如-O0)。

  • FPU配置:若使用浮点运算,确保Boot Loader和APP的FPU初始化一致。

  • 时钟配置:APP不应重新初始化时钟(除非Boot Loader未初始化)。




最终步骤总结



  1. 修改APP链接脚本地址和栈顶范围。

  2. 在APP中设置SCB->VTOR

  3. 增强Boot Loader的栈检查和中断清理逻辑。

  4. 确保生成.bin文件的命令正确。

  5. 验证Flash内容与向量表地址。


按以上步骤操作后,应能解决跳转问题。若仍有异常,可结合调试器检查硬故障(HardFault)原因,或进一步核对Keil与CubeIDE的生成文件差异。

举报

更多回帖

×
20
完善资料,
赚取积分