我有一个项目:单个二进制文件可在多种不同类型的 PCB 板上运行,这些板卡都用STM32F303RCT6,但外接的外设不同,如,有电机板、电磁线圈板、电源板、传感器板等。所有这些板卡均运行同一二进制文件,通过 Flash 中特定区域的一个标志位,来决定应执行哪些 HAL/MSP 初始化函数。
该项目名为 f3_application,文件大小约 112KB。为支持通过 UART 端口烧录固件,我还预留了 112KB 空间,用于存储待更新的新固件。
另外还有一个 f3_bootloader 项目:设备启动时, Bootloader 会先检查是否需要将新固件复制到应用程序区域;之后通过重写向量表偏移量、设置应用程序栈指针,并跳转到对应地址运行应用程序。
以上方案在 Eclipse 2019 AC6 System Workbench中一直运行正常。
现在我需要为该代码库新增一款 MCU,但仍希望沿用现有库等资源,因此我开始将这个项目迁移至 CubeIDE 中,在此过程中遇到了一些问题
Bootloader 链接脚本如下:
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x2000A000; /* end of "RAM" Ram type memory */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Memories definition */
MEMORY
{
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 8K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 40K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 24K
DATA (rx) : ORIGIN = 0x08006000, LENGTH = 8K
}
int main(void)
{
[..]
pFunction appEntry;
uint32_t appStack;
// APPLICATION_ADDRESS 0x08008000
/* Get the application stack pointer (First entry in the application vector table) */
appStack = (uint32_t) *((__IO uint32_t*) APPLICATION_ADDRESS);
/* Get the application entry point (Second entry in the application vector table) */
appEntry = (pFunction) *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
/* Reconfigure vector table offset register to match the application location */
SCB->VTOR = APPLICATION_ADDRESS;
/* Set the application stack pointer */
__set_MSP(appStack);
/* Start the application */
appEntry();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_Delay(100);
HAL_GPIO_TogglePin(OutputBoard_State_DataBus_GPIO_Port, OutputBoard_State_DataBus_Pin);
}
/* USER CODE END 3 */
}
程序卡在第14行
如果我注释掉所有这些代码,让程序进入 while 循环,就能正常运行。
所以知道问题肯定和内存地址有关,但不确定接下来该如何排查。
|
|