本篇是关于根据正点原子IAP程序的学习记录,以及自己理解。
一、IAP运行流程图
STM32 的内部闪存(FLASH)地址起始于 0x08000000,一般情况下,程序文件就从此地址开始写入。程序启动后,将首先从“中断向量表”取出复位中断向量执行复位中断程序完成
启动,“中断向量表”的起始地址是 0x08000004。
二、生成APP
1 ) 设置 APP 程序的起始地址和存储空间大小
因此留给APP用的flash空间为0x30000,起始地址为0x8010000。设置好 Start 和 Szie,就完成APP 程序的起始地址设置。
2 ) 设置中断向量表偏移量
systemInit函数中的定义如下:
VTOR寄存器存放的是中断向量表的起始地址,在main函数开头重新设置了中断向量
SCB->VTOR = FLASH_BASE | 0x10000;
3 ) 生成.bin 文件
三、生成bootloader
bootloader的起始地址为0x8000000,FLASH_APP1_ADDR设置为app1启动的地址,即0x08010000
3.1、程序下载
正点原子从flash升级例程中,先使用iap_write_appbin将串口接收buff中的app1程序下载到flash中。
3.2、程序跳转(对应流程③)
通过iap_load_app函数,跳转到 APP1 程序运行
先介绍“==”号的左侧,结合app1的hex文件会更好理解,这里判断FLASH_APP1_ADDR+4,由于FLASH_APP1_ADDR为0x08010000,偏移四个后取值,在hex文件找到地址0x08010004对应的值为0x080164F1,结合运行流程图,这个就是APP复位中断向量的值,这里0x20000780即是栈顶指针的值。
“==”右侧判断是否为0x08000000的原因是stm32f10xx的闪存地址都是从该地址开始的,只要判断最高8位是0x08,等价于你烧录的就是stm32的固件。
接下来看一下iap_load_app的实现
appxaddr=0x08010000,按位与后就是0x20000000,这条If语句的目的是通过判断顶地址值是否正确(是否在0x20000000-0x20010000之间) 来判断APP程序是否已经正确加载,因为APP程序的启动文件刚开始就去初始化化栈空间,若栈顶值对了,说应用程已经下载了启动文件的初始化也执行了。 如果没有这一句话,即使没有下载程序也会进入而导致程序跑飞。
本文参考:https://www.freesion.com/article/217536578/
((*(vu32*)(0X20001000+4))&0xFF000000)==0x08000000这句话应该怎样理解呢?麻烦详细解释一下。。。-OpenEdv-开源电子网