代码改变世界

STM32 HAL开发完全指南

2023-05-25 19:07  dreamboy2000  阅读(92)  评论(0编辑  收藏  举报
关于STM32 IAP升级之为什么APP执行要&0x2FFE0000这个数值的原因

关于STM32 IAP升级之为什么APP执行要&0x2FFE0000这个数值的原因

 

如下图所示,这是我目前用的一款CPU:STM32F446RET6,大小是512KB

我的bootloader编译完以后占用了26KB的FLASH内存。 我的APP占用了363K的FLASH内存,主要是因为LCD显示,刷的图片很多,很占内存。 为了给以后的Bootloader扩展更多的功能需求,我给我的Bootloader栈顶占用FLASH 0x10000的大小,也就是64k。 所以,目前Bootloader占用了从Sector0-Sector3三个扇区,剩下的区域就分给APP吧。

APP从FLASH的0x8010000开始运行,也就是从扇区4Sector-4开始,STM32F446RET6的FLASH的大小是512KB,由于Bootloader占用了64KB,所以还剩余448KB,这一部分给我的APP用。我们可以将448KB * 1024 => 458752B =>再换算成十六进制>0x70000,所以上面这个0x70000是这么得出来的。 再来看看我的这款CPU的SRAM,先简单了解下SRAM:

然后打开Keil以及芯片数据手册查看。

从下面文档看出,我的这款CPU的SRAM是0x20000,也就是128KB

在写针对DFU固件更新程序时候,这里有一段跳转到APP的代码:

#define USBD_DFU_APP_DEFAULT_ADD     0x08010000U
static void JumpToApp(void)
{
	//如果按键没有按下,则启动APP
    if(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 1)
    {
        /* Test if user code is programmed starting from USBD_DFU_APP_DEFAULT_ADD * address */
		if(((*(__IO uint32_t*)USBD_DFU_APP_DEFAULT_ADD) & 0x2FFE0000 ) == 0x20000000)
        {
            /* Jump to user application */
            JumpAddress = *(__IO uint32_t *) (USBD_DFU_APP_DEFAULT_ADD + 4);
            JumpToApplication = (pFunction) JumpAddress;

            /* Initialize user application's Stack Pointer */
            __set_MSP((*(__IO uint32_t *) USBD_DFU_APP_DEFAULT_ADD));
            JumpToApplication();
        }
    }
}

我之前一直没搞明白为什么对APP的地址简引用,然后得出的数值 & 0x2FFE0000等于0x20000000就认为有APP,可以跳转到对应的地址去执行我的APP程序了,那我&上别的什么乱七八糟的数据它不香吗??为何呢??

原因如下:

程序在运行过程中,0x20000000是我们SRAM运行的起始地址,空间是128KB,也就是0x20000000-0X2001FFFF这个范围。 所以*(__IO uint32_t*)USBD_DFU_APP_DEFAULT_ADD) ,这句话的意思是取得用户地址空间存放的数据,这个空间就是0x08010000,当APP运行的程序栈顶指针落在SRAM区域时,也就是0x20000000到0X2001FFFF这个区间时候,这个时候即是有效的栈顶指针,由于开始的地址是0x20000000,而结束的地址是0X2001FFFF,我们只要判断它的高16位,即是确定这个地址范围在从0x2000开始。

转发:https://zhuanlan.zhihu.com/p/105109753