STM32F10x IAP技术

2023-11-04 23:18
文章标签 技术 iap stm32f10x

本文主要是介绍STM32F10x IAP技术,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

STM32F10x IAP技术

(BOOTLOADER)

第一部分

一 计算固件占用FLASH大小

每次生成固件时,Keil 会有一个固件信息显示,如下列图

图1

固件占用FLASH大小 = Code + RO + RW + ZI,上图中的固件大小为:11,016字节,16进制为:0x2B08。

二 固件数据结构

http://www.51hei.com/UpFiles/up/0/491511221618834.jpg

图2

STM32F10x有一个中断向量表,这个中断向量表存放在代码开始部分的后4个字节处(即0x08000004),代码开始的4个字节存放的是堆栈栈顶的地址,当发生中断后程序通过查找该表得到相应的中断服务程序入口地址,然后再跳到相应的中断服务程序中执行。上电后从0x08000004处取出复位中断向量的地址,然后跳转到复位中断程序的入口(标号①所示),执行结束后跳转到main函数中(标号②所示)。在执行main函数的过程中发生中断,则STM32强制将PC指针指回中断向量表处(标号③所示),从中断向量表中找到相应的中断函数入口地址,跳转到相应的中断服务函数(标号④所示),执行完中断函数后再返回到main函数中来(标号⑤所示)

:Stm32源代码中有说明。堆栈栈顶地址需为0x200的整数倍,原文为” Vector Table base offset field. This value must be a multiple of 0x200” 。即:”向量表基本偏移量字段。此值必须是0x200的倍数”。 因此,图1中,如该固件在FLASH中的起始地址为0x8000000。若想在该固件后继续放置其它固件,则最近的可用地址为 0x2C00

 

三 固件程序间的跳转说明

若在STM32F103x中使用IAP方案,则内置的Flash分配情况大致如下图:

http://www.51hei.com/UpFiles/up/0/491511231663247.jpg

图3

在内置的Flash里面添加一个BootLoader程序,BootLoader程序和 用户程序 各有一个中断向量表,假设BootLoader程序占用的空间为N+M字节,则程序的走向应该如下图所示

http://www.51hei.com/UpFiles/up/0/491511231667910.jpg

图4

上电初始程序依然从0x08000004处取出复位中断向量地址,执行复位中断函数后跳转到IAP的main(标号①所示),在IAP的main函数执行完成后强制跳转到0x08000004+N+M处(标号②所示),最后跳转到新的main函数中来(标号③所示),当发生中断请求后,程序跳转到新的中断向量表中取出新的中断函数入口地址,再跳转到新的中断服务函数中执行(标号④⑤所示),执行完中断函数后再返回到main函数中来(标号⑥所示)。

以上 参考链接:https://blog.csdn.net/wzy15965343032/article/details/88545225

对于步骤④⑤,是跳转到0x8000004 还是跳转到 0x8000004+N+M,由②③来协同决定。

若想跳转到0x8000004+N+M,则:② 在跳转前要关闭所有中断外设,清除所有中断向量的使用。若是从RTOS固件跳转到其它固件,除放弃一切中断和中断服务外,还要修改CPU的模式为特权模式、关闭SysTick、激活MSP等操作;③的main中重定中断向量表地址为0x8000004+N+M。否则固件程序在④⑤的时候会跑到0x8000004的向量表中,运行结果不可预知。通常会进入 XXXX_Handler ,如 :HardFault_Handler、SysTick_Handler等。

四 不同固件在FLASH中的地址参数

         前面已经提到了固件在FLASH中占用空间的算法;堆栈栈顶地址需为0x200的整数倍。下面举例说明,想将多个固件放在同一个MCU FLASH中的地址参数配置方法如下。

         现有BootLoader ,APP1, APP2 三个程序要放入一片 STM32F103C8T6中。三个程序在FLASH中的存储安排如下:

BOOTLOADER

APP1

APP2

 

         BOOTLOADER 程序编译后的固件信息,算下来,约占0x2C00空间,(下一个APP的堆栈栈顶地址需为0x200的整数倍,因此取了一个你好我好大家好的占用空间0x2C00)如下图:

因此BOOTLOADER 使用的是默认地址设置,如下图:

         重点是 Start : 0x8000000。(有人说Size也要设置为固件占用大小,我没有改,验证过程中也没有发现有问题)

         APP1程序编译后的固件信息,算下来,约占0x2C00空间 (实际上APP1只是把BOOTLOADER的程序改了几行代码),如下图:

         算上BOOTLOADER占用的空间,APP1的地址设置如下图:

         重点是,Start : 0x8002C00

         APP2 使用的是CMSIS RTOS2框架,实现的功能不多,占用的空间不小,约0x5C00的空间,如下图:

         算上BOOTLOAD、APP1所占用的空间,APP2的起始地址要从 0x5800开始,设置如下:

         为了使APP1、APP2初始化时,同步指定中断向量表,APP1要将中断向量偏移到程序所在地址(固件在FLASH中存储的起始地址),在system_stm32f10x.c中:

         

         同理 APP2中的也要修改:

        

         如果使用JLINK 直接烧写固件,3个固件,分3次独立烧写。无需额外设置。有朋友说也要设置地址,我验证过,没必要。但要注意不能每次烧写时把所有的FLASH清除,这样每次烧写都会把前面烧写的内容都清除掉了,这样是没有办法验证的。Jlink 烧写配置如下:

 

第二部分 程序跳转代码

说那么多都是云,代码才是重点,有多少朋友跨过千山万水,历经各种摩擦,总是不能正常跳转,就是跳不过去。以下代码专治各种跳转不服,从非RTOS固件到RTOS固件,再跳回非RTOS固件,随便跳!妥妥地!

/*程序中转:app_addr 程序在FLASH中的地址。不能在中断中调用*/
void Run_App(u32 app_addr)
{u32 spinitval;u32 jumpaddress;App_Function app = NULL;//确定中转的地址是否在正确的范围内if(((*(__IO u32 *)app_addr) & 0x2FFF0000) == 0x20000000)   //64K  的FLASH RAM
//    if(((*(__IO u32 *)app_addr) 0x2FFE0000) == 0x20000000)   //128K  的FLASH RAM
//    if(((*(__IO u32 *)app_addr) & 0x2FF80000) == 0x20000000)   //512K  的FLASH RAM{//为了不给要跳转的程序初始化造成麻烦,初始化所有端口GPIO_DeInit(GPIOA);GPIO_DeInit(GPIOB);GPIO_DeInit(GPIOC);GPIO_DeInit(GPIOD);GPIO_DeInit(GPIOE);GPIO_DeInit(GPIOF);GPIO_DeInit(GPIOG);if(CONTROL_nPRIV_Msk & __get_CONTROL())		//RTOS{__asm("SVC #0");	//确保CPU处于特权模式}//常规RCC_DeInit();	//关闭所有外设时钟NVIC_DeInit();	//禁用NVIC中的所有已启用中断和请求 ,高版本固件库中好像没有这个函数了,可以自己写一个//RTOSSysTick->CTRL = 0 ;	//关闭 RTOS 的心跳时钟SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;	//清除其异常挂起位//如果引导加载程序使用它们,则禁用各个故障处理程序SCB->SHCSR &= ~( SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk | SCB_SHCSR_MEMFAULTENA_Msk ) ;//常规spinitval = *(__IO u32 *)app_addr;	//	取得栈顶地址jumpaddress = *(__IO u32 *)(app_addr + 4);	//取得复位中断向量app = (App_Function)jumpaddress;//如果发现核心当前与PSP一起运行(在RTOS的线程中运行时使用的是PSP),则激活MSPif( CONTROL_SPSEL_Msk & __get_CONTROL( ) ){  /* MSP 未激活 */__set_CONTROL( __get_CONTROL( ) & ~CONTROL_SPSEL_Msk ) ;	//激活MSP}//将MSP设置为用户应用程序向量表中的值__set_MSP(spinitval); //如果未在中断或没有使用系统的时候,那么这个生效  //将用户应用程序的向量表地址加载到SCB-> VTOR寄存器中。确保地址符合对齐要求 0x200的倍数(这一句可能没有意义)SCB->VTOR = ( uint32_t )app_addr; // 将用户应用程序的向量表地址加载到SCB-> VTOR寄存器中app(); //中转到指定程序地址}

以上代码参考连接:https://www.keil.com/support/docs/3913.htm

第三部分 固件HEX合并烧写说明

         产品出厂前,通常是两个固件要同时写入到MCU中,每一片要写两次,没效率。因此需要将多个HEX文件合并为一个文件,再一次性烧写,注:HEX文件是文本格式,可以用文本编辑器打开。操作方法如下:

  1. bootloader的最后一行(文件结束记录行)删除;
  2. APP1HEX文件内容直接COPYbootloader的后面,不能有空行;
  3. 同样把合并后的最后一行(原APP1 固件Hex文件的最后一行)删除;
  4. 把APP2的HEX文件内容直接COPY在合并文件的后面,不能有空行;
  5. 保存合并文件成为新的HEX文件,即可使用Jlink或Hex烧写工具直接烧写

以上合并文件烧写结果,验证通过。

特别说明:本说明是以STM32F103C8T6为列说明的,该MCU的FLASH扇区大小为1024。程序地址参数是否受MCU的FLASH扇区大小制约,目前并未验证。

验证工程下载地fh址:https://download.csdn.net/download/SCY820114/12915364

这篇关于STM32F10x IAP技术的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/345838

相关文章

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

金融业开源技术 术语

金融业开源技术  术语 1  范围 本文件界定了金融业开源技术的常用术语。 本文件适用于金融业中涉及开源技术的相关标准及规范性文件制定和信息沟通等活动。

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出 在数字化时代,文本到语音(Text-to-Speech, TTS)技术已成为人机交互的关键桥梁,无论是为视障人士提供辅助阅读,还是为智能助手注入声音的灵魂,TTS 技术都扮演着至关重要的角色。从最初的拼接式方法到参数化技术,再到现今的深度学习解决方案,TTS 技术经历了一段长足的进步。这篇文章将带您穿越时

系统架构设计师: 信息安全技术

简简单单 Online zuozuo: 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo : 文章目录 系统架构设计师: 信息安全技术前言信息安全的基本要素:信息安全的范围:安全措施的目标:访问控制技术要素:访问控制包括:等保

前端技术(七)——less 教程

一、less简介 1. less是什么? less是一种动态样式语言,属于css预处理器的范畴,它扩展了CSS语言,增加了变量、Mixin、函数等特性,使CSS 更易维护和扩展LESS 既可以在 客户端 上运行 ,也可以借助Node.js在服务端运行。 less的中文官网:https://lesscss.cn/ 2. less编译工具 koala 官网 http://koala-app.

STM32内部闪存FLASH(内部ROM)、IAP

1 FLASH简介  1 利用程序存储器的剩余空间来保存掉电不丢失的用户数据 2 通过在程序中编程(IAP)实现程序的自我更新 (OTA) 3在线编程(ICP把整个程序都更新掉) 1 系统的Bootloader写死了,只能用串口下载到指定的位置,启动方式也不方便需要配置BOOT引脚触发启动  4 IAP(自己写的Bootloader,实现程序升级) 1 比如蓝牙转串口,

Spring的设计⽬标——《Spring技术内幕》

读《Spring技术内幕》第二版,计文柯著。 如果我们要简要地描述Spring的设计⽬标,可以这么说,Spring为开发者提供的是⼀个⼀站式的轻量级应⽤开发框架(平台)。 作为平台,Spring抽象了我们在 许多应⽤开发中遇到的共性问题;同时,作为⼀个轻量级的应⽤开发框架,Spring和传统的J2EE开发相⽐,有其⾃⾝的特点。 通过这些⾃⾝的特点,Spring充分体现了它的设计理念:在

java线程深度解析(六)——线程池技术

http://blog.csdn.net/Daybreak1209/article/details/51382604 一种最为简单的线程创建和回收的方法: [html]  view plain copy new Thread(new Runnable(){                @Override               public voi

java线程深度解析(二)——线程互斥技术与线程间通信

http://blog.csdn.net/daybreak1209/article/details/51307679      在java多线程——线程同步问题中,对于多线程下程序启动时出现的线程安全问题的背景和初步解决方案已经有了详细的介绍。本文将再度深入解析对线程代码块和方法的同步控制和多线程间通信的实例。 一、再现多线程下安全问题 先看开启两条线程,分别按序打印字符串的

SSM项目使用AOP技术进行日志记录

本步骤只记录完成切面所需的必要代码 本人开发中遇到的问题: 切面一直切不进去,最后发现需要在springMVC的核心配置文件中中开启注解驱动才可以,只在spring的核心配置文件中开启是不会在web项目中生效的。 之后按照下面的代码进行配置,然后前端在访问controller层中的路径时即可观察到日志已经被正常记录到数据库,代码中有部分注释,看不懂的可以参照注释。接下来进入正题 1、导入m