网站开发端,兰山区网站建设推广,购买服务器后如何做网站,成都旅游网站建设规划0 工具准备 Keil uVision5 Cortex M3权威指南#xff08;中文#xff09; STM32参考手册 1 在线升级#xff08;IAP#xff09;设计思路
为了实现STM32的在线升级#xff08;IAP#xff09;功能#xff0c;通常会将STM32的FLASH划分为BOOT和APP两个部分#xff0c;BOO…0 工具准备 Keil uVision5 Cortex M3权威指南中文 STM32参考手册 1 在线升级IAP设计思路
为了实现STM32的在线升级IAP功能通常会将STM32的FLASH划分为BOOT和APP两个部分BOOT就是引导APP的引导程序当我们需要在线升级时就可以通过BOOT来实现。BOOT和APP在FLASH中的分布如下
原理分析 1当STM32复位后会跳转到FLASH首地址也就是0x08000000的位置读取1-4Byte获取主堆栈指针初始值栈顶值并设置然后读取5-8Byte获取复位中断服务函数入口地址并执行进入BOOT程序 2BOOT程序根据用户选择升级APP或者跳转到APP 2.1如果用户选择升级APP则擦除APP所在扇区按照一定协议将APP程序复制到FLASH的APP扇区 2.2如果用户选择跳转到APP首先关闭全局中断及清除中断挂起标志设置主堆栈指针跳转到APP的复位中断服务函数**相当于做了1中内核干的事情**
2 BOOT设计
这里介绍一下BOOT跳转到APP函数的设计思路
void Jump_to_APP(void)
{uint32_t i0;void (*SysMemBootJump)(void);/* 关闭全局中断 */__disable_irq();/* 关闭滴答定时器复位到默认值 */SysTick-CTRL 0;SysTick-LOAD 0;SysTick-VAL 0;/* 设置所有时钟到默认状态使用HSI时钟 */RCC_DeInit();/* 关闭所有中断清除所有中断挂起标志 */for (i 0; i 8; i){NVIC-ICER[i]0xFFFFFFFF;NVIC-ICPR[i]0xFFFFFFFF;}/* 使能全局中断 */__enable_irq();/* 跳转到系统BootLoader首地址是MSP地址4是复位中断服务程序地址 */SysMemBootJump (void (*)(void)) (*((uint32_t *) (FLASH_APP_ADDR 4)));/* 设置主堆栈指针 */__set_MSP(*(uint32_t *)FLASH_APP_ADDR);/* 跳转到APP */SysMemBootJump();/* 跳转成功的话不会执行到这里用户可以在这里添加代码 */while (1){}
}相关知识 1涉及到的NVIC寄存器 1.1NVIC-ICER中断失能寄存器写入1失能中断 1.2NVIC-ICPR中断挂起清除寄存器写入1清除中断挂起 2APP二进制文件含义 bin文件 Byte1-40x20014168 Byte5-80x080101A1 Byte9-120x08012D75 Byte13-160x08012851 map文件 __initial_sp 0x20014168 Data 0 startup_stm32f40xx.o(STACK) Reset_Handler 0x080101a1 Thumb Code 8 startup_stm32f40xx.o(.text) NMI_Handler 0x08012d75 Thumb Code 2 stm32f4xx_it.o(i.NMI_Handler) HardFault_Handler 0x08012851 Thumb Code 8 stm32f4xx_it.o(i.HardFault_Handler) 可以看到APP工程的bin文件含义如下 Byte1-40x20014168 主堆栈指针初始值栈顶值 Byte5-80x080101A1 复位中断服务函数地址 Byte9-120x08012D75 NMI中断服务函数地址 Byte13-160x08012851 HardFault中断服务函数地址 该部分的定义在STM32的参考手册上也可以看到 其实我们只需要关注主堆栈指针初始值栈顶值和复位中断服务函数地址即可。如果想要了解APP前几个byte的全部内容可以参看STM32参考手册的“STM32F405xx/07xx 和 STM32F415xx/17xx 的向量表”。 弄清楚了上述的寄存器使用方法和APP的bin文件内容后接下来BOOT中跳转到APP的操作原理就一目了然了 1关闭全局中断避免被打断 2关闭滴答定时器复位到默认值为后面的APP营造一个纯净的环境 3设置所有时钟到默认状态为后面APP营造一个纯净的环境 4关闭所有中断同时清除所有中断挂起标志避免APP使能中断后异常触发等情况 5使能全局中断避免APP部分没有打开全局中断 6函数指针指向APP的复位中断服务函数也就是APP的第5-8Byte 7设置主堆栈指针也就是APP的前4Byte 8跳转到APP 以上有2个地方需要特别注意 1APP的复位中断服务函数地址是APP的第5-8Byte 2APP的主堆栈指针初始值栈顶值是APP的前4Byte
3 APP设计
APP设计时只需要修改工程的flash起始地址以及中断向量偏移地址寄存器即可。 1修改FLASH起始地址 如果我们的APP存放在FLASH的0x8010000开始的位置则将FLASHA的起始地址修改为0x8010000即可。 2修改中断向量偏移地址 BOOT下我们的中断向量偏移地址为0x08000000和默认值一样无须特别设置APP下由于FLASH起始地址被修改到0x8010000因此需要将中断向量偏移地址设置为0x1000
#define VECT_TAB_OFFSET 0x10000相关寄存器如下 当STM32发生了中断需要响应时内核会根据向量表偏移量寄存器的值在相应的FLASH空间找到异常服务函数入口地址中断服务函数入口地址保存工作由编译器完成。上电后的向量表如下 假设我们设置的VTOR的值为0x8010000在发生了硬错误时会跳转到0x80100000x0000000C的位置找到硬错误中断服务函数地址并执行。这也是我们为什么需要在APP中设置VTOR的原因BOOT里已经默认设置为0x0x8000000保证我们的中断能够正确执行。
4 总结
1APP程序需要修改FLASH起始地址和向量表偏移量寄存器以便内核能够在中断发生时进入正确的中断服务函数 2BOOT程序跳转到APP的过程实际上就是模拟内核的操作 3BOOT跳转到APP之前一定要失能所有中断、清除所有中断挂起标志营造一个纯净的环境