【STM32】IAP升级01 bootloader实现以及APP配置(主要) | 您所在的位置:网站首页 › 应用升级是不是更占内存 › 【STM32】IAP升级01 bootloader实现以及APP配置(主要) |
APP程序以及中断向量表的偏移设置
前言
通过之前的了解 之前的了解,我们知道实现IAP升级需要两个条件: 1.APP程序必须在 IAP 程序之后的某个偏移量为 x 的地址开始; 2.APP程序的中断向量表相应的移动,移动的偏移量为 x; 1.APP 程序起始地址设置 默认条件下的起始地址默认的条件下,图中 IROM1 的起始地址(Start)一般为 0x08000000,大小(Size)为 0x100000,即从 0x08000000 开始的 1024K 空间为我们的程序存储区。 设置起始地址(Start)为 0x08010000,偏移量为 0x10000(64K 字节,即留给 BootLoader 的空间),因而,留给 APP 用的 FLASH 空间(Size)为 0x80000-0x10000=0x70000(448KB)。设置好 Start 和 Size,就完成 APP 程序的起始地址设置。IRAM 是内存的地址,APP 可以独占这些内存,我们不需要修改。 需要确保 APP 起始地址在 Bootloader 程序结束位置之后,并且偏移量为 0x200 的倍数即可 将 IROM1 的起始地址(Start)定义为:0x20001000,大小为 0x19000(100K 字节),即从地址 0x20000000 偏移0x1000 开始,存放 SRAM APP 代码。 STM32F407ZGT6 只有一个 128K(不算 CCM)的片内 SRAM,存放程序的位置与变量的加载位置不能重复,所以我们需要设置 IRAM1 中的地址(SRAM)的起始地址变为 0x2001A000,分配大小只有 0x6000(24K 字节)。整个 STM32F407ZGT6 的 SRAM(不含 CCM)分配情况为:最开始的 4K 给 Bootloader 程序使用,随后的 100K 存放 APP 程序,最后 24K,用作 APP 程序的内存。 SCB->VTOR寄存器存放的是中断向量表的起始地址。默认的情况它由 BOOT 的启动模式决定。重定向这个位置,这样就可以从 Flash 区域的任意位置启动代码。 就是你跳转到app程序后,你后续得跑app的中断向量表。要实现这个就必须在刚进入app的时候重定向中断向量表 /* 设置 NVIC 的向量表偏移寄存器,VTOR 低 9 位保留,即[8:0]保留 */ SCB->VTOR = baseaddr | (offset & (uint32_t)0xFFFFFE00);baseaddr 为基地址(即 APP 程序首地址),Offset 为偏移量 比如 FLASH APP 设置中断向量表偏移量为 0x10000 SCB->VTOR = FLASH_BASE | ( 0x10000 & (uint32_t)0xFFFFFE00);SRAM APP 的情况可以参考正点原子探索者开发指南V1.1。 3.设置keil生成bin文件MDK 默认生成的文件是.hex 文件,并不方便用作 IAP更新,我们希望生成的文件是.bin 文件. hex和bin文件的区别简单来说:HEX文档是ascii码的文档。 是不能直接烧到单片机中的。 中间要有转换程序。 但是现在很多编程器都设计成直接可以导入hex文件烧录的,其实这是做了设计的。 bin文件是二进制文件,是可以直接烧到芯片中,中间不用转换的。 设置keil生成bin文件在 MDK 点击 Options for Target→User 选项卡,在 After Build/Rebuild一栏中,勾选 Run #1,我们推荐使用相对地址,在勾选的同一行后的输入框并写入命令行:fromelf --bin -o …\[email protected] …\Output%L 通过这一步设置,我们就可以在 MDK 编译成功之后,调用 fromelf.exe, ..\..\Output\%L 表示当前编译的链接文件(…\是相对路径,表示上级目录,编译器默认从工程文件*.uvprojx 开始查找,根据我的工程文件 Output 的位置就能明白路径的含义) 指令–bin –o …\[email protected]表示在 Output 目录下生成一个.bin 文件, @L 在 Keil 的下表示 Output 选项卡下的 Name of Executable 后面的字符串,即在 Output 文件夹下生成一个 atk_f407.bin 文件。 在得到.bin 文件之后,我们只需要将这个 bin 文件传送给单片机,即可执行 IAP 升级。 Bootloader程序的实现1、APP文件的编写与通常编写一致,只需要设定好偏移地址 2、新的中断向量表的偏移设置好 这两点在前文已经写过,接下来就是bootloader的实现了。 Bootloader 和 app 属于两个独立的工程,不是一个工程!!! 相关资料: 1.写 STM32 内部 Flash 的功能用到 STM32 的 Flash操作。STM32片上Flash操作 2.设置bootloader的起始地址为复位之后第一个启动的工程。 这个例子中,bootloader从0x800 0000开始,APP从0x800 8000开始,执行完bootloader之后再执行APP。 BootLoader 的编译器设置 是我们专门用来搬运APP程序的工具,所以也和是和普通程序一样的执行流程。 IAP升级程序(bootloader)启动流程 例如,使用串口升级,那么步骤就是 bootloader的main之前1.单片机复位,从0x800 0000开始执行。 2.执行0x0800 0004处的Rest_Handler复位中断向量函数 3. 复位中断向量函数执行 _main 标号表示 C/C++标准实时库函数里的一个初始化子程序 _main的入口地址。该程序的一个主要作用是初始化堆栈(跳转_user_initial_stackheap标号进行初始化堆栈),并初始化映像文件,最后跳转到C程序中的main函数。这也正解释了为什么所有的C程序必须有一个main函数作为程序的起点,因为这是由C/C++标准实时库所规定的。 4.跳转到IAP升级程序(bootloader)的main函数。 bootloader的main之后 1.初始化初始化和正常没有bootloader 的程序一下,该咋样就咋样,为了避免无效功耗损失,一般是需要什么就初始化什么。时钟初始化,串口初始化,定时器初始化等(如果有用到定时轮询或者定时器延时等可以初始化) 2.检查APP 程序是否完整若出现某些情况导致APP程序不全,有可能导致程序跑飞,进入硬件错误。 初始化完成后,首先检测 APP 分区中最后地址的标志位是否符合(如是否等于0x5a5a,一般APP程序的末尾加入特殊字符,以检测完整性),如果符合,启动倒计时(时间大约几百毫秒就行,根据实际情况决定),等待进入 APP 程序,在此期间,也会等待接收升级的指令;否则,则一直等待接收升级的指令。 check收到的估计bin的最后四个字节是否为0x5A5A int CheckIfAPPCanJump(void) { uint32_t *pFlag = (uint32_t *)(APP_FLASH_CODE_BASE + APP_FLASH_CODE_SIZE - 4); if (*pFlag == 0x5A5A) { return 1; } return 0; } 3.升级接收到升级指令后,则启动升级流程,升级期间不允许进入 APP 程序。 4.跳转APP程序(IAP 如何实现跳转到用户程序)升级完成后,需要跳转到 APP 程序(可以自动跳转,也可以增加跳转指令手动跳转),跳转前的准备: 1.检测 APP 程序是否存在,若存在,则继续往下执行APP升级 2.关闭全局中断(可选,放置升级中被打断) 3.清除所有中断标志位(可选,放置升级中被打断) void Disable_irq(void) { uint8_t i; __disable_irq(); // 关闭总中断 //__enable_irq(); /* 清除所有中断标志 */ for(i= 0; i |
CopyRight 2018-2019 实验室设备网 版权所有 |