最近遇到一个非常邪门的问题:用"MDK做的BOOTLOADER程序"引导"STM32CubeIDE做的APP"会导致启动不了不能成功进入APP的问题。但是同样的APP源码用MDK来编译却是可以成功进入APP。大家可能会怀疑是STM32CubeIDE生成的APP机器码有问题,为了验证这个问题我去掉BOOTLOADER将APP的起始地址设为0x00再次用STM32CubeIDE编译生成机器码并烧录进芯片发现APP又可以正常运行。更加奇怪的是:如果保留BOOTLOADER让STM32CubeIDE进入debug模式也能正常启动APP,但是一旦芯片复位后就又不能进入APP了。
通过以上操作应该可以确定STM32CubeIDE生成的APP是没有问题的,因为在没有BOOTLOADER的情况下APP是可以正常运行的。问题应该是出在BOOTLOADER上。我记得BOOTLOADER在跳转APP前会将APP的起始位置4个字节的内容做个判断,如果这个值合法则跳转不合法则不跳转:
/* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */
if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
{
/* Jump to user application */
JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
Jump_To_Application = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
Jump_To_Application();
}
我怀疑问题应该就出在这里,于是将问题程序烧录后读出FLASH数据找到APP起始位置的数据:
QQæªå¾20191206175542.png (56.5 KB, 下载次数: 19)
下载附件
保存到相册
APPèµ·å§ä½ç½®æ°æ®
2019-12-6 17:56 上传
可以发现这个值是0x20030000明显不合法,难怪跳转APP不成功。
我现在有个疑问:将堆栈首地址设为0x20030000为什么不会越界,因为我用的芯片内存地址最大值应该是0x2002FFFFF?