STM32的bootloader IAP编程
STM32实现IAP“-STM32存储器 — STM32实现IAP

STM32 实现IAP“>STM32存储器—STM32 实现IAP
在对STM32 存储器结构及相关知识了解后,我们就可以进行IAP 的设计了。
在上一篇笔记中,进行了一个简单的IAP 程序结构,以及和User App 程序的相互联系的系统设计。
本篇对IAP 实现的细节进行了较为详细的论述,包括源码结构的设计;我们从上位机(PCC#)和下位机(MCUC)共同描述IAP 功能的实现过程。
1 STM32 的IAP 实现平台
IAP 功能的实现需要两个方面(上位机和STM32 上的IAP 程序)的密切合作。
因此,我们除了需要知道STM32 芯片上的IAP 程序结构,我们还需要了解上位机的程序结构,这样才能使上位机和STM32 很好的相互工作。
下位机(指的是STM32 构成的单片机系统):
本下位机系统使用C 语言进行编程,项目功能是实现IAP(In Application Programming);
下位机使用IAR Embedded Workbench for ARM 6.10 Kick start 开发环境;使用STM32F103C8-PKT 开发板进行调试和验证;
上位机(指的是PC 构成的PC 系统):
本上位机系统使用C#语言进行编程,项目功能是配合下位机实现IAP;
上位机使用Visual Studio 2008 开发环境;
使用一般的PC 机进行调试和验证;
上位机和下位机通讯(串口通讯):
上下位机之间通过串口进行通讯;。
STM32_USB _IAP 步骤

5.安装驱动,如果第二步默认安装的话,选择驱动C:\Program Files\STMicroelectronics\Software\DfuSe\Driver
6.打开应用程序工程,
6.1) 编译选项设置 在IROM1 start处设置0x8004000;
6.2) 修改中断向量表偏移量:( VECT_TAB_OFFSET 0x0---> 0x04000)
修改://#define ApplicationAddress 0x08003000为#define ApplicationAddress 0x08004000(因为要修改程序增加空间)
编译程序,用stlink/Jlink将程序下载到STM32中。
4.用usb线连接STM32板,PC端出现发现新硬件。
#ห้องสมุดไป่ตู้ndif
6.3) 编译选项设置output 钩上create HEX File ok 设置好编译。
7.打开C:\Program Files\STMicroelectronics\Software\DfuSe\BIN\DfuFileMgr.选择 I want to generate a dfu file from s19 ,hex or bin ok 选择s19 or hex 选择应用程序工程生成的STM3210E-EVAL.hex 点击generate 保存为20120131.dfu
STM32 USB IAP 步骤
1.下载STM32_USB-FS-Device_Lib_V3.2.1.rar
2.安装DfuSe_Demo_V3.0_Setup.exe。
3.打开...\STM32_USB-FS-Device_Lib_V3.2.1\Project\Device_Firmware_Upgrade\MDK-ARM\DFU.uvproj
STM32-bootloader流程解析

STM32 bootloader 流程解析stm32在内部有硬件bootloader,但那是在生产烧录时使用的。
stm32在flash开头的4K程序空间是可以设置成防擦除的,是天生的bootloader存放区。
我的思想是在开头的4K空间(0x8000000-0x8000FFF)放置一个独立程序,主程序编译地址放在0x8001000后端。
上电时,bootloader程序先判断是否满足升级条件(IO电平判断),然后选择是循环等待升级,或者直接跳转到主程序区。
现给出流程如下,大家可交流探讨。
BOOT流程.JPG (11.13 KB)boot程序流程程序流程详细.JPG (35.79 KB)程序详细流程说的太过简单笼统了,经过一个来星期的调试,总算完成了这个东西..调试中发现一个问题,在已经开始执行BOOT程序之后,再进行切换到应用程序时,有些中断会出问题.而在BOOT启动时(所有软硬件操作都没开始)马上切换到应用程序就不会出问题.一直没找到怎么解决.最后只好把IAP程序和应用程序合在一起使用,在上电后的短时间内执行IAP,无响应就进入应用程序,没有所谓的BOOT区了.stm32在flash开头的4K程序空间是可以设置成防擦除的,是天生的bootloader存放区。
我的思想是在开头的4K空间(0x8000000-0x8000FFF)放置一个独立程序,主程序编译地址放在0x8001000后端。
楼主所说的stm32在flash开头的4K程序空间是可以设置成防擦除的,如何设置?而且主程序编译地址放在0x8001000后端,如何实现啊,望指教!!!我最近也在做类似的事情,但是在跳转到功能程序出问题了。
功能程序应该如何设置?如果一个程序不从默认的Flash地址开始存储,需要设置哪些东西,在Keil 开发环境中。
谢谢!。
STM32串口IAP分享

IAP是In Application Programming的首字母缩写,IAP是用户自己的程序在运行过程中对User Flash的部分区域进行烧写,目的是为了在产品发布后可以方便地通过预留的通信口对产品中的固件程序进行更新升级。
在重新编程过程中可以使用任意类型的通信协议,如UART、I2S、SPI等。
这篇笔记分享的是使用UART方式IAP。
串口IAP实验先理一理流程(本实验是以STM32F103ZET6为例):1、实验说明做这个实验需要准备两个keil工程,一个工程用于编写IAP程序,另一个工程用于编写我们的应用程序(要实现某些功能的程序),这里我们以一个点灯程序为例。
最终,两份工程编译出来的可执行文件都需要烧写到芯片的FLASH 中。
只不过需要烧写到不同的地址,简单的示意图如下:这里,使用的STM32的型号为STM32F103ZET6,其FLASH大小是512KB,0x08000000为其FLASH被映射的地址,程序被烧写到的就是这个地址。
此处,我们的IAP程序烧写到这个地址,根据IAP程序的大小,我们在keil里可以设置合适的IAP结束地址。
注意:在没有IAP程序的情况下,0x08000000这个地址就是应用程序烧写的地址。
2、工程说明本实验用到的两个工程可按照文末的方式获取,其中IAP工程移植至ST官方例程。
下面对两个工程进行简单的说明IAP工程:(1)需要在target选项卡里设置我们IAP程序的起始地址与大小,如:这里我们的IAP程序起始地址设为0x08000000,大小设为0x3000,即IAP所能用的FLASH空间为12KB。
其中IAP所能占的占空间的大小可根据IAP的实际大小进行修改。
(2)需要修改程序中我们需要跳转到的应用程序的地址(即IAP程序的结束地址):LED工程:(1)需要在target选项卡里设置我们LED程序的起始地址与大小,如:这里我们的LED程序起地址设为0x08003000,大小设为0x10000,即LED所能用的FLASH空间为64KB。
STM32 合并BIN文件的两种方法

在单片机的开发过程中,经常需要将两个单独的BIN文件合并成一个文件,方便烧写和生产。
下面结合STM32的IAP Bootloader Code和Application Code的合并,介绍两种合并BIN文件的方法。
首先简单介绍一下STM32的IAP。
IAP(In-application-programming),即在应用中编程。
有了它,产品发布之后,仍然可以方便的升级固件,而不需要拆机并用JTAG等方式更新程序。
IAP系统的固件一般有两部分组成,IAP BootLoader Code和Application Code,如下图所示。
系统启动时,首先运行IAP BootLoader Code,并检测相应状态,判断是执行升级的流程还是直接运行本地的Application Code。
一般来说,BootLoader和Application是分别编译的,会生成两个二进制文件。
在工厂生产时,如果分别烧写这两个文件,显然有些麻烦。
这时,我们就可以将两个BIN文件合并成一个,直接烧写。
假设Application Code的偏移地址为0x1000,IAP固件在Flash中的分布如下图所示。
下面介绍第一种方法,使用二进制文件合并工具(UBIN.exe),这个小工具是以前在S3C2410上开发uCOS时做的,功能比较简单,满足一般的需求。
首先,添加第一个文件1.bin,其地址为0x0000,所以,偏移量设置为0x00000000,设置完偏移量后点击“添加”按钮。
然后添加第二个文件,偏移量根据需要设置为0x00001000,如下图所示。
设置目标文件为C:\dst.bin,然后点击“合并”按钮。
正常情况下,会成功生成目标文件,并有如下图所示的提示信息。
这种方法相对比较灵活,对合并文件的个数和偏移地址没有限制。
缺点是不支持配置文件,不能保存所设的配置,所以,每次合并都得手动做很多重复工作。
在调试阶段会比较浪费时间。
下面介绍一种通过命令行工具合并两个文件的方法。
单片机程序烧录的3种方式(ISP、ICP、IAP)是什么

单片机程序烧录的3种方式(ISP、ICP、IAP)是什么说起给单片机烧录程序,大家应该都不陌生吧,我最早接触单片机是从51单片机开始的,型号是STC89C52RC,当时烧录程序就是用的下面这种烧录软件——STC-ISP。
这种方式,通过串口连接单片机,选择一个合适的波特率就可以烧录了。
后来学习STM32,编程时使用KEIL软件自带的下载按钮就能下载程序,方便了不少,但需要额外使用J-Link等下载器。
再后来,接触到产品研发,给已经发布出的产品升级,都是要靠远程无线升级的(想想看,产品已经到客户那里了,当软件需要升级时,要是还使用有线的方式烧录程序,得有多麻烦)既然给单片机烧录程序的方式有多种,那烧录方式具体怎么分类呢?可以分为3种:ISP(In-System Programming)在系统编程,使用引导程序(Bootloader)加上外围UART/SPI等接口进行烧录。
ICP (In-circuit programmer)在电路编程,使用SWD/JTAG接口。
IAP(In-Application Programming)指MCU可以在系统中获取新代码并对自己重新编程,即用程序来改变程序。
这3种烧录方式的原理是什么呢?在分析原理之前,需要先了解一下单片机Flash的访问地址,看看程序是烧录到哪个位置了。
单片机Flash在地址映射表中位置下图是一张STM32F4xx的地址映射表,从0x0000 0000到0xFFFF FFFF,总计4Gbyte。
单片机的片上Flash、片上RAM、片上外设以及外部扩展接口的访问地址,都被映射到这4Gbyte的范围之内。
这张图中,我们需要先注意下半部分Main memory 主存储区通常,我们编写的代码,是放到主存储区的起始位置(0x0800 0000)开始运行的,烧录程序时,直接将程序烧录到这里即可(KEIL 软件给STM32烧录程序的默认烧写地址就是0x0800 0000开始)System memory系统存储区System memory(起始位置0x1FFF 000)是STM32在出厂时,由ST在这个区域内部预置了一段BootLoader,也就是我们常说的ISP程序,这是一块ROM,出厂后无法修改。
stm32f030 bootloader 例程

主题:STM32F030 Bootloader 例程一、简介STM32F030是STMicroelectronics公司推出的一款32位ARM Cortex-M0内核的微控制器。
它具有丰富的外设,如GPIO、UART、SPI、I2C等,适用于各种嵌入式系统应用。
在嵌入式系统开发中,Bootloader是一个重要的组成部分,它能够实现固件的更新和管理,提高系统的灵活性和可靠性。
本文将介绍如何使用STM32F030的Bootloader例程进行固件升级。
二、准备工作在使用STM32F030的Bootloader例程之前,我们需要准备好以下工具和材料:1. STM32F030开发板2. USB转TTL串口模块3. ST-Link下载器4. 针对STM32F030系列的Bootloader例程源码三、下载和安装Bootloader例程源码1. 在STMicroelectronics官全球信息站下载针对STM32F030的Bootloader例程源码2. 将下载的源码解压缩到本地3. 打开Keil MDK-ARM开发环境,导入源码并进行编译四、烧录Bootloader程序1. 使用ST-Link下载器将编译好的Bootloader程序烧录到STM32F030开发板上2. 确保烧录成功后,通过串口工具连接USB转TTL串口模块到STM32F030的串口引脚上五、固件升级测试1. 将需要升级的固件通过串口工具上传到开发板2. 在Bootloader程序中编写相关代码来实现固件的升级和校验3. 运行Bootloader程序,进行固件升级测试六、总结通过本文的介绍,我们了解了如何使用STM32F030的Bootloader 例程进行固件升级。
在实际的嵌入式系统开发中,Bootloader的作用不仅局限于固件升级,还可以实现固件的管理和安全验证。
掌握Bootloader的开发和使用对于提高系统的稳定性和可靠性是非常重要的。
IAR环境下STM32+IAP方案的实现

IAR环境下STM32+IAP方案的实现什么是IAP,为什么要IAPIAP即为In Application Programming(在应用中编程),一般情况下,以STM32F10x系列芯片为主控制器的设备在出厂时就已经使用J-Link仿真器将应用代码烧录了,如果在设备使用过程中需要进行应用代码的更换、升级等操作的话,则可能需要将设备返回原厂并拆解出来再使用J-Link重新烧录代码,这就增加了很多不必要的麻烦。
站在用户的角度来说,就是能让用户自己来更换设备里边的代码程序而厂家这边只需要提供给用户一个代码文件即可。
而IAP却能很好的解决掉这个难题,一片STM32芯片的Code(代码)区内一般只有一个用户程序。
而IAP方案则是将代码区划分为两部分,两部分区域各存放一个程序,一个叫bootloader(引导加载程序),另一个较user application(用户应用程序)。
bootloader在出厂时就固定下来了,在需要变更user application时只需要通过触发bootloader对userapplication的擦除和重新写入即可完成用户应用的更换。
如图1-1所示图 1-1在程序执行初始进入bootloader,在bootloader里面检测条件是否被触发(可通过按键是否被按下、串口是否接收到特定的数据、U盘是否插入等等),如果有则进行对user application进行擦除和重新写入操作,如果没有则直接跳转到user application执行应用;如果有则进行擦除用户代码并重新写入新的用户代码。
二、STM32F103ZET6硬件条件STM32F103ZET6的启动方式有三种:内置FLASH启动、内置SRAM 启动、系统存储器ROM启动,通过BOOT0和BOOT1引脚的设置可以选择从哪中方式启动,这里选择内置的FLASH启动。
其FLASH的地址为0x08000000—0x0807ffff,共512KB,这些都能从芯片数据手册中直接得到。
基于YModem的STM32串口IAP的设计

基于YModem的STM32串口IAP的设计摘要:针对STM32应用程序在线升级的问题,提出基于YModem的串口IAP方案,以实现简单、高效、可靠的MCU程序在线升级。
本文给出了基于YModem的串口IAP方案的原理解释及实现的技术细节。
方案成功应用在多个实际的项目中,缩短Bug修复时间,能实现远程升级,取得较大的经济和社会效益。
关键词:STM32串口BOOTLOADER YModem协议IAP随着集成电路技术的发展以及电子产品越来越智能化,MCU的应用越来越广泛。
而在MCU使用过程中,应用程序的升级是一个难点。
目前,对于程序升级主要存在两种技术:在系统编程ISP以及在应用编程IAP。
ISP在系统编程,指的是一种在系统中直接进行烧录的编程技术。
IAP在应用编程,指的是MCU可以在系统运行中获取新的代码并对自己重新编程的技术。
ISP一般需要少量的外部电路辅助实现,需要硬件事先留出相关接口且到现场升级;而IAP只需要依托系统现成的通信链路,无需额外的硬件,更为灵活,而且可以实现远程升级,因此IAP技术越来越受到欢迎和重视。
本文介绍一种基于YModem的STM32串口IAP的设计,从而实现简洁、高效、可靠地对MCU进行在应用编程。
一、STM32的IAP原理要实现STM32的在应用编程(IAP),需要把原来的一个程序拆分为两个程序,一个是负责对应用程序进行在应用编程的BOOTLOADER程序;另一个则是实现真正功能的应用程序APP。
因此,需要把Flash划分为BOOTLOADER区域和APP区域,如图1.1所示。
1.具体说来,BOOTLOADER程序需要实现两个功能:(1)在接收到升级命令时,与上位机进行通信,把新的APP程序接收并烧写到APP所在的Flash区域。
(2)在程序烧写完成后或无需升级时,自动跳转到APP程序来执行。
图1.1 IAP程序空间划分当系统复位时,中断向量表指向0x00000000,会从0x00000004处取出复位起始地址,并跳转到中断服务程序中执行,即执行BOOTLOADER中的复位中断程序。
STM32Bootloader基于ymodem传输协议串口IAP升级详解

STM32Bootloader基于ymodem传输协议串⼝IAP升级详解硬件:stm32f103cbt6软件:STM32F10x_StdPeriph_Lib_V3.5.0⽂章⽬录1 预备知识基于标准外设库(STM32F10x_StdPeriph_Lib_V3.5.0)的IAP升级相关资料可以参考。
STM32升级的三种⽅式:IAP,ICP,ISP;具体有什么区别可以⾃⾏Google;本⽂需要实现STM32的Bootloader(后⾯Bootloader/IAP不加以区分),⽂件传输基于ymodem协议通过串⼝进⾏传输,这⾥参考了ST官⽅的DEMO —— ,在此基础上做了部分修改,增加了延时启动的功能,最终可以实现想要的效果。
整体架构分为两个部分;Bootloader和Application,具体如下图所⽰;由上图可知,STM32内置的Flash被分成了两个部分,分别⽤来保存Bootloader和Application程序,这⾥有两个有两个FLASH起始地址0x8000000和0x8003000;为什么是0x8000000这个地址呢?⽽不是其他地址呢?这是由M3内核硬件上的设计就已经这么做了,⼈为设计好了,可以参考M3内核权威指南;0x8003000这个地址则是由我们⾃⼰来规定的,这个地址的范围必须在0x8000000和0x8020000之间,所以⼀般根据Bootloader程序的最终⼤⼩,在这范围之间取⼀个⽐较合理的值即可。
如下图所⽰;注意:本⽂使⽤的stm32f103cb,属于中等⼤⼩Flash,128K = 0x20000,所以地址范围是0x8000000~0x8020000;2 Bootloader2.1 启动流程这⾥的Bootloader即为IAP程序,它具备以下⼏个功能;⽀持⽂件传输;本⽂基于ymodem协议通过串⼝通讯接收或发送的bin⽂件;当然也可以通过I2C,SPI,USB,WiFi,蓝⽛等等进⾏⽂件传输;对内置Flash进⾏读写,擦除和编程;启动Application程序;前⾯分析STM32启动⽂件的时候,我们可以知道,正常⼀个系统的启动流程,可以参考;由该图可以知道程序正常启动流程;以下表格⼀四个向量是必须的,从图中也可以了解到;地址异常编号值0x0800_0000-MSP 的初始值0x0800_00041复位向量(PC 初始值)0x0800_00082NMI 服务例程的⼊⼝地址0x0800_000C3硬 fault 服务例程的⼊⼝地址………2.2 校验跳转地址是否有效在主函数中可以看到如下程序;甚是不解和迷茫;沉思⼀会⼉才恍然⼤悟;/* Test if user code is programmed starting from address "ApplicationAddress" */if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000){/* Jump to user application */JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);Jump_To_Application = (pFunction) JumpAddress;/* Initialize user application's Stack Pointer */__set_MSP(*(__IO uint32_t*) ApplicationAddress);Jump_To_Application();}本⽂中ApplicationAddress = 0x8000000;那么*(__IO uint32_t*)ApplicationAddress)则是这个地址中所保存的值,由表格⼀可以知道,程序起始地址的第⼀个向量地址保存的栈顶的,因此,地址0x800_0000和0x800_3000中保存的值都是指向栈顶,如下图所⽰;栈是在RAM上分配,因此RAM的有效范围要做⼀个检测,栈顶地址和0x2FFE0000做与运算可以推算出,要校验的RAM范围是0x2000_0000—0x2001_FFFF,所以RAM⼤⼩是128K,官⽅DEMO默认使⽤HD⾼密度系列,所以是128K,本⽂是CBT6,20K的RAM,则需要改成0x2FFFB000:/* Test if user code is programmed starting from address "ApplicationAddress" */if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFFB000 ) == 0x20000000){/* Jump to user application */JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);Jump_To_Application = (pFunction) JumpAddress;/* Initialize user application's Stack Pointer */__set_MSP(*(__IO uint32_t*) ApplicationAddress);Jump_To_Application();}计算⽅式:20K = 20*1024= 0x5000,0x2FFF_FFFF - (0x5000 - 1) = 0x2FFF_B0002.3 Keil⼯程IAP的相关设置2.3.1 修改Flash地址设置程序起始地址0x800000和⼤⼩0x3000;设置Debug⼯具烧写时Flash的起始地址0x800000和⼤⼩0x3000;2.3.2 使⽤⾃⼰的链接脚本该项为选配,与上述配置⼆选⼀即可,如果仍然想使⽤⾃⼰的链接脚本,在Option-->Linker下将Use Memort Layout from Target Dialog选项勾选去掉,然后选择⾃⼰的链接脚本,如下图进⾏配置;参考ARMCC的链接脚本编写⽅法,可以⾃⼰编写的srt⽂件,参考ARM分散加载技术;; *************************************************************; *** Scatter-Loading Description File generated by uVision ***; *************************************************************LR_IROM1 0x08000000 0x00003000 { ; load region size_regionER_IROM1 0x08000000 0x00003000 { ; load address = execution address*.o (RESET, +First)*(InRoot$$Sections).ANY (+RO).ANY (+XO)}RW_IRAM1 0x20000000 0x00005000 { ; RW data.ANY (+RW +ZI)}}如果⽤的gcc⼯具链,则要编写gcc的链接脚本ld⽂件;2.3.3 下载固件配置完成之后进⾏Build,然后通过SWD的⽅式先下载固件,进⾏实验;3 Application3.1 启动流程⽤户的Application需要在IAP启动完成后,才能正常执⾏;具体启动过程,⽐正常应⽤的启动多了⼀个IAP启动的过程,并最终通过IAP引导进⼊Application;具体如下图所⽰;⽩⾊部分为IAP;灰⾊部分为Application;图中的0x8000004+N+M就等于0x8003004,所以Application的启动地址需要进⾏修改,另外还有其他需要修改的地⽅,下⾯会详细指出。
STM32学习:IAP简单的IAP例子

STM32学习:IAP简单的IAP例⼦章节概述:以⼀个最简单的例⼦⽰范IAP程序(没有⽂件通讯,没有跳转判断),需要借助IDE进⾏分区数据的划分以及下载。
准备IDE:keil-MDK 5MCU:STM32F103ZET6为例(Flash地址为0x08000000—0x0807ffff,共512KB)。
BSP:STM32-HAL启动⽅式:FLASH启动前32KB存放BootLoader程序(0x08000000 ~ 0x08007fff)剩余的空间存放APP程序(0x08008000 ~ 0x0807ffff)假定跳转的APP程序的实际物理地址为:0x08008000分别新建2个⼯程,名字可以为:bootLoader与app。
从Bootloader跳转到APPBootloader为了区分执⾏分区的不同,添加串⼝打印功能。
(略)例如:printf("Hello Bootloader\r\n");添加下⾯的代码以实现跳转功能:节选⾃CubeMX的例程:STM32Cube\Repository\xxx\Projects\Applications\IAP#define NVIC_VectTab_RAM ((u32)0x20000000)#define NVIC_VectTab_FLASH ((u32)0x08000000)#define PHYSICAL_ADDRESS_Flash (0x08000000) // 程序烧写的物理地址#define APPLICATION_POSADDR (0x0000C000) // APP 偏移量#define APPLICATION_ADDRESS ((PHYSICAL_ADDRESS_Flash) | (APPLICATION_POSADDR)) // 最终跳转的地址,实际上就是0x08008000typedef void (*pFunction)(void);pFunction JumpToApplication;uint32_t JumpAddress;void NVIC_SetVectorTable(uint32_t base, uint32_t offset){/* close interruption*/__set_FAULTMASK(1);/* set vector table*///NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0xffset);SCB->VTOR = base | offset;/* open interruption*/__set_FAULTMASK(0);}int main(void){// 在BootLoader程序的中断向量表指向设置中应有这么⼀句:NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); //设置中断向量表指向/* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000) //①{/* Jump to user application */JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);// ②JumpToApplication = (pFunction) JumpAddress;//③/* Initialize user application's Stack Pointer */__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS); // ④JumpToApplication(); // ⑤}while (1){}}解析:①因为⽤户程序开始位置(0x08008000处)的前4个字节存放的是堆栈的地址,堆栈地址必定是指向RAM空间的,⽽STM32的RAM空间起始地址为0x20000000,所以要进⾏判断。
STM32 IAP升级

while (1) { File_Receive(); } } ARM 通知 MCU 升级时, APP 往 EEPROM 写入升级标志, APP 跳转到 IAP 后, 则优先判断 EEPROM 中是否存在升级标志。若不存在升级标志则直接跳转到用户应用程序。 void EEPROM_Read(void) { u8 read2byte[2]; u16 timeout; timeout = 200; do { EEPROMReadReg(0x00,&read2byte[0]); //读取 EEPROM 数据 if (read2byte[0] == 0x3C) //判断数据是否为 0x3C { printf("\r\nUPDATA data,%d\r\n",read2byte[0]); HaveFile_Flag=1; break; } Else { SysDelay10us(50); } }while(Байду номын сангаасimeout--); if(HaveFile_Flag==1) return; //如果存在升级标志,则返回 //设置升级标志
//关闭总中断
IAPJumpAddress = *(__IO uint32_t*) (IAP_ADDRESS + 4); Jump_To_Iap = (pFunction) IAPJumpAddress; __set_MSP(*(__IO u32*) IAP_ADDRESS); Jump_To_Iap(); //跳转到 IAP } //初始化 IAP 堆栈指针
APP 工
中断向量表的映射及相关外设的初始化。 int main(void) { SCB->VTOR= FLASH_BASE | (uint32_t)0X4004; HAL_Init(); SystemClock_Config(); __enable_irq(); MX_GPIO_Init(); MX_TIM6_Init(); MX_USART1_UART_Init(); Uart2Init(); I2C1_Init(); Timer6_Start(); printf("\r\nThis is App Code~\r\n"); while (1) { ProcessUart2(); //串口数据解析 //中断向量表的映射 //时钟配置 //打开总中断 //GPIO 口初始化 //定时器初始化 //Debug 串口初始化 //MCU 与 ARM 通信串口初始化 //I2C 初始化 //打开定时器
在STM32L011上通过I2C接口实现IAP

在STM32L011上通过I2C接口实现IAP前言客户计划使用STM32L011xx开发一款光模块产品,需要MCU支持I2C接口下载代码。
但STM32L011xx内部Bootloader没有支持I2C接口,所以需要我们使用IAP的方式来帮助客户实现该功能。
问题分析IAP代码大小STM32L011xx只有8K-16K 字节的Flash容量,所以这个IAP的代码不能过大,否则就会将用户的应用程序空间压缩的过小。
经过和客户沟通,最大IAP代码可以占用的空间为2K字节。
开发模式选用因为代码空间的限制(最多2K字节),所以我们只能使用直接写寄存器的开发方式。
硬件结构代码结构基本流程参考了我们的Bootloader by UART的结构。
在上电的时候检查外部使能管脚的状态,如果是有效电平的话就进入到Bootloader模式,开启Bootloader程序的运行。
在Bootloader程序中进行Flash内容的改写。
最后,进入到烧写好的用户代码中运行。
注意事项在使用寄存器开发中,需要注意几个地方。
1/在地址匹配中断中需要检查DIR的值以判断当前的状态是发送还是接收;2/主要的任务是下载Code到Flash中,所以,I2C主要做的就是接收一个完整的数据包,这里以主机发送STOP事件为接收完成标志。
3/I2C的接收缓冲开的越大越好,但是由于代码的限制,以最小的数据量为准。
4/STM32L011xx系列的Flash最小单元都是相等的(128Byte),所以在擦写的时候可以直接一个页一个页的写,降低了IAP代码的大小。
总结:此IAP程序架构可以在整个STM32L011系列产品中直接应用,节省了客户下载应用代码的程序开发时间。
占用的代码空间小于2K字节。
重要通知 - 请仔细阅读意法半导体公司及其子公司(“ST”)保留随时对ST 产品和/ 或本文档进行变更、更正、增强、修改和改进的权利,恕不另行通知。
买方在订货之前应获取关于ST 产品的最新信息。
一种单片机IAP方案-STM32F

一种单片机固件IAP方案导言基于FLASH存储器的微处理器,一个重要的需求是安装到产品中后,仍具有升级固件(firmware)的能力。
这种能力称为“在应用中编程”(In-application-programming,IAP)。
这篇应用笔记以STM32F 32位cortex-M3为例,阐述了构建IAP系统的一些通用概念。
并提出了一种新的技术,有助于单片机开发人员更好的构建IAP系统。
STM32系列微处理器基于FLASH存储器。
在FLASH中运行的固件可以擦写FLASH 本身。
FLASH的头4KB具有写保护,适合存储IAP固件(IAP BootLoader)。
1IAP 概览:1.1 IAP(In-application-programming)、ICP(In-circuit-programming)、ISP(In-system-programming):ICP 是在电路板编程,IAP 是在应用编程。
ISP 大部分时候指ICP ,但少数MCU 厂家将IAP 称为ISP 。
1.2IAP 系统的硬件组成:1.3IAP 系统的固件组成:1.4IAP BootLoader 的流程:1.4.1BootLoader的激活条件,通常在复位后,首先进入BootLoader,并检查某些条件,以选择激活BootLoader还是跳转到Application。
一般有以下几类条件:1.4.1.1检测IAP Port上某个GPIO的状态。
1.4.1.2检测IAP Port上某条输入线的信号序列。
1.4.1.3检测Application Code的有效性、标志。
1.4.2本地存储器的使用:1.4.2.1在远程IAP系统中,经常使用本地存储器来存储升级代码。
便于升级代码的分包传输、完整性校验。
1.5IAP系统的要求:1.5.1Safety(安全性):升级代码需要完整的、正确的写到Application Area。
另外需要考虑到升级过程中断电、强干扰等意外事件。
STM32实现IAP功能的学习笔记--转载

STM32实现IAP功能的学习笔记--转载STM32实现IAP功能的学习笔记最近因项⽬需求要实现STM32的在线升级即IAP功能,先将这⼏天的学习体会和IAP的具体实现总结出来,分享给⼤家,希望对同样实现IAP 的童鞋有所帮助,⽂中最后会上传名为STM32_Update.zip的压缩⽂件⾥⾯包含了STM32_App、STM32_MyBoot_V1.0和升级软件STM32_UpdateSoftware的源码⽂件供⼤家参考。
所有程序都经过测试,可以直接在原⼦哥的上跑,上位机的升级软件⼤家可以直接打开STM32_Update\STM32_UpdateSoftware\Release\STM32_UpdateSoftware.exe来升级,如果需要查看源码请⽤VS2010打开⼯程⽂件。
最终要实现的是:单⽚机每次上电会先运⾏Boot程序,检查标志位如果标志位为FLAG_TO_APP则直接跳转到App程序运⾏,如果标志位为FLAG_TO_BOOT,则运⾏Boot程序准备升级。
在运⾏App程序时,当接收到升级的指令后会在FLASH中的某处空间写下升级的标志位FLAG_TO_BOOT,并且加载Boot程序,Boot程序会接受新的程序⽂件并且存储在相应的FLASH空间⾥,完成升级后会在标志位的空间写下FLAG_TO_APP,并且运⾏新的程序。
帖⼦包含如下⼏个⽅⾯:1. 什么是IAP?2. STM32的启动模式?3. STM32的FLASH分布?4. STM32程序的运⾏过程?5. BootLoader程序的编写(如何实现程序的动态加载)?6. App程序的编写?7. bin⽂件的转换?8. 上位机串⼝升级软件的简介-------------------------------------------------------------------------------------------------1. 什么是IAP?IAP的知识⽹上的各种资料也说的⽐较明⽩,在此简单介绍⼀下。
STM32三种启动模式以及IAP在线升级

一.Duanxx的STM32学习:启动模式,BOOT0和BOOT1详解Reference from:/daunxx/article/details/40148945在画STM32的电路图的时候,关于STM32的启动方式纠结了一下,现有的参考设计都是在STM32的启动选择引脚BOOT0和BOOT1上使用了跳帽,用以人工选择STM32的启动方式,但是在实际应用中这种设计就显得冗余,所以这里顺带研究了一下STM32的启动方式。
STM32一共有三种启动模式,在ST官网上下载的RM0008中,我找到了启动相关的配置说明:对应的中文翻译如下:所谓启动,一般来说就是指我们下好程序后,重启芯片时,SYSCLK 的第4个上升沿,BOOT引脚的值将被锁存。
用户可以通过设置BOOT1和BOOT0引脚的状态,来选择在复位后的启动模式。
∙Main Flash memory是STM32内置的Flash,一般我们使用JTAG或者SWD模式下载程序时,就是下载到这个里面,重启后也直接从这启动程序。
∙System memory从系统存储器启动,这种模式启动的程序功能是由厂家设置的。
一般来说,这种启动方式用的比较少。
系统存储器是芯片内部一块特定的区域,STM32在出厂时,由ST在这个区域内部预置了一段BootLoader,也就是我们常说的ISP程序,这是一块ROM,出厂后无法修改。
一般来说,我们选用这种启动模式时,是为了从串口下载程序,因为在厂家提供的BootLoader中,提供了串口下载程序的固件,可以通过这个BootLoader将程序下载到系统的Flash中。
但是这个下载方式需要以下步骤:Step1:将BOOT0设置为1,BOOT1设置为0,然后按下复位键,这样才能从系统存储器启动BootLoaderStep2:最后在BootLoader的帮助下,通过串口下载程序到Flash中Step3:程序下载完成后,又有需要将BOOT0设置为GND,手动复位,这样,STM32才可以从Flash中启动可以看到,利用串口下载程序还是比较的麻烦,需要跳帽跳来跳去的,非常的不注重用户体验。
手把手教你写STM32的bootloader(SDIO读取TF更新Bootloader)

手把手教你写STM32的bootloader(SDIO读取TF卡更新固件)作者:谭建裕1、bootloader的简介及作用什么是bootloader?本人不知道该怎么说,反正会来看这篇都是知道自己要干嘛的。
不过bootloader的作用还是要提提的,bootloader最直观的作用就方便,比如你用单片机给人家做了一款产品,后期你的产品固件需要更新的时候,你总不能带着电脑直接去客户那里拆开产品给单片机下程序吧?也不能教客户怎么给单片机下程序吧?用户体验感太差。
其实本质上bootloader的也是一个完整的程序,也有main函数,有自己的中断向量表,栈顶指针,它可以检查有没有新的固件,如果有,则将新的固件的数据写入到我们指定的flash地址中,之后跳到新的程序中去就OK了。
此时bootloader的优势就来了,bootloade 更新固件有很多种方式,本人在这里只详细讲解一种,搞懂一种之后,其它的都好办,因为它们的思路都是一样的。
Bootloader的主体原理是:首先将bin文件的数据复制到特定的地址。
然后设置中断向量表,设置MSP主堆栈指针(具体请看CM3权威指南),设置复位向量。
然后就没有然后了。
2、bootloader涉及的知识本人在此讲解的是STM32通过读取TF内的bin文件数据来更新固件。
这里牵扯到STM32的SDIO外设,FATFS文件系统,STM32的flash读写操作。
2.1 SDIOSDIO是STM32的外设,需要注意的是只有100引脚及以上的才有。
电路原理图如图2-1-1所示。
图2-1-1注意:在使用TF之前必须保证TF卡格式为FAT32,单元大小为2048。
如图2-1-2所示。
图2-1-2记得在stm32f10x_it.c文件中添加中断函数。
如图2-1-3所示。
图2-1-32.2 FATFS文件系统移植和使用文件系统使用的是FATFS9,源码在压缩包的ff9文件夹,如图2-2-1所示。
stm32 bootloader例程

stm32 bootloader例程STM32 bootloader是一种用于更新芯片固件的程序,它具有一些特殊的功能和特点。
在本文中,我们将探讨STM32 bootloader的例程,并详细介绍其工作原理和使用方法。
让我们对STM32 bootloader的概念进行简要说明。
STM32 bootloader是一种特殊的程序,它允许用户通过串口或其他通信接口将新的固件程序加载到STM32微控制器中。
这种功能对于在运行中的设备上更新固件非常有用,因为它允许用户无需使用专用的编程器或调试器就可以完成固件更新。
STM32 bootloader的工作原理是通过检测特定的引脚状态来确定是否需要进入bootloader模式。
当芯片复位时,它会读取引脚的状态并决定是否进入bootloader模式。
如果芯片进入bootloader模式,它将等待来自主机的命令,并根据命令执行相应的操作,例如擦除芯片、写入新的固件等。
在使用STM32 bootloader时,我们需要在主机上运行一个特定的应用程序,该应用程序可以通过串口或其他通信接口与bootloader通信。
通过这个应用程序,我们可以发送命令并接收来自bootloader 的响应,从而实现固件更新的目的。
要使用STM32 bootloader,我们需要在芯片中预留一部分内存空间来存放bootloader程序。
这一部分内存通常称为bootloader区域。
在编译和烧录固件时,我们需要确保bootloader区域不会被覆盖,以确保我们能够随时进入bootloader模式。
除了更新固件之外,STM32 bootloader还具有其他一些功能。
例如,它可以用于读取芯片的唯一ID和版本号,以及执行其他一些与固件相关的任务。
这些功能使得STM32 bootloader成为一个非常强大和灵活的工具。
在实际应用中,我们可以根据需要自定义STM32 bootloader的行为。
例如,我们可以添加一些额外的命令或功能,以满足特定的需求。
STM32F030之IAP代码编写

STM32F030之IAP代码编写
程序收尾总想着以后更新的方便性,采用在应用编程(In ApplicaTIon Programming),通过Bootload引导单片机自己往程序存储器里写数据或修改程序。
下面简介STM32F030的IAP方法。
不同于STM32F1系列,F0没有中断向量偏移寄存器。
所以在APP程序的开头要添加以下代码。
为什么这样做??
可以看到函数用了for循环将矢量表拷贝到0 x20000000 SRAM的基地址,即将矢量表由Flash映射到了SRAM。
所以在MDK里面设置Flash偏移地址的时候,同时要设置SRAM 偏移地址。
如下截图
//APP程序开头加入IAP_Set(void)函数
有Target对话框可以看出APP程序有Flash地址0x8001400开始执行。
Sram数据则有0x20000c0出开始存储。
说完APP代码要处理事项,下面说一下IAP代码编写
程序更新完以后执行以上跳转函数即可执行更新的APP代码。
关于如何通过IAP将代码将APP代码(bin文件)传到单片机Flash,可以通过串口分包传输。
因为F0Flash是1K 为一页所以这里我用的是1K缓存,即接收串口1K的数据量就执行一次Flash写操作,传输到最后不满1K,填写0XFF按照1K数据写。
写Flash代码如下
关于IAP如何接收串口的数据,我用的是正点原子的XCOM V2.0串口调试助手通过协议传输每次传输128字节数据,执行的IAP串口数据接收。
STM32 合并BIN文件的两种方法

在单片机的开发过程中,经常需要将两个单独的BIN文件合并成一个文件,方便烧写和生产。
下面结合STM32的IAP Bootloader Code和Application Code的合并,介绍两种合并BIN文件的方法。
首先简单介绍一下STM32的IAP。
IAP(In-application-programming),即在应用中编程。
有了它,产品发布之后,仍然可以方便的升级固件,而不需要拆机并用JTAG等方式更新程序。
IAP系统的固件一般有两部分组成,IAP BootLoader Code和Application Code,如下图所示。
系统启动时,首先运行IAP BootLoader Code,并检测相应状态,判断是执行升级的流程还是直接运行本地的Application Code。
一般来说,BootLoader和Application是分别编译的,会生成两个二进制文件。
在工厂生产时,如果分别烧写这两个文件,显然有些麻烦。
这时,我们就可以将两个BIN文件合并成一个,直接烧写。
假设Application Code的偏移地址为0x1000,IAP固件在Flash中的分布如下图所示。
下面介绍第一种方法,使用二进制文件合并工具(UBIN.exe),这个小工具是以前在S3C2410上开发uCOS时做的,功能比较简单,满足一般的需求。
首先,添加第一个文件1.bin,其地址为0x0000,所以,偏移量设置为0x00000000,设置完偏移量后点击“添加”按钮。
然后添加第二个文件,偏移量根据需要设置为0x00001000,如下图所示。
设置目标文件为C:\dst.bin,然后点击“合并”按钮。
正常情况下,会成功生成目标文件,并有如下图所示的提示信息。
这种方法相对比较灵活,对合并文件的个数和偏移地址没有限制。
缺点是不支持配置文件,不能保存所设的配置,所以,每次合并都得手动做很多重复工作。
在调试阶段会比较浪费时间。
下面介绍一种通过命令行工具合并两个文件的方法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
不需要拆机就能对产品进行固件升级是很多人想要的效果,不仅方便而且节省精力和成本。
那么如何完成这项工作呢?接下来所介绍的Bootloader就可以完成这项工作,通过Bootloader引导程序完成固件的升级。
下面来浅析STM32 Bootloader设计。
首先谈谈stm32的ISP和IAP区别和联系。
ISP(In-System Programming)在系统可编程,指电路板上的空白器件可以编程写入最终
用户代码,而不需要从电路板上取下器件,已经编程的器件也可以用ISP方式擦除或再编程。
IAP(In-Application Programming)指MCU可以在系统中获取新代码并对自己重新
编程,即可用程序来改变程序。
ISP和IAP技术是未来仪器仪表的发展方向。
1 ISP和IAP的工作原理
ISP的实现相对要简单一些,一般通用做法是内部的存储器可以由上位机的软件通过串口来进行改写。
对于单片机来讲可以通过SPI或其它的串行接口接收上位机传来的数据并写
入存储器中。
所以即使我们将芯片焊接在电路板上,只要留出和上位机接口的这个串口,
就可以实现芯片内部存储器的改写,而无须再取下芯片。
IAP的实现相对要复杂一些,在实现IAP功能时,单片机内部一定要有两块存储区,一
般一块被称为BOOT区,另外一块被称为存储区。
单片机上电运行在BOOT区,如果有外
部改写程序的条件满足,则对存储区的程序进行改写操作。
如果外部改写程序的条件不满足,程序指针跳到存储区,开始执行放在存储区的程序,这样便实现了IAP功能。
2 ISP和IAP的优点
ISP技术的优势是不需要编程器就可以进行单片机的实验和开发,单片机芯片可以直接焊接到电路板上,调试结束即成成品,免去了调试时由于频繁地插入取出芯片对芯片和电路
板带来的不便。
IAP技术是从结构上将Flash存储器映射为两个存储体,当运行一个存储体上的用户程序时,可对另一个存储体重新编程,之后将程序从一个存储体转向另一个。
ISP的实现一般需要很少的外部电路辅助实现,而IAP的实现更加灵活,通常可利用单
片机的串行口接到计算机的RS232口,通过专门设计的固件程序来编程内部存储器,可以
通过现有的INTERNET或其它通讯方式很方便地实现远程升级和维护。
IAP的编写流程
设计思想
由Bootloader负责检测SD卡中是否有固件更新所需的BIN文件。
如果检测到所需要的BIN文件,则开始复制文件更新固件。
更新结束后跳转到指定的地址开始执行最新的程序。
知识要点
STM32内部FLASH的起始地址为0X08000000,Bootloader程序文件就从此地址开始
写入,存放APP程序的首地址设置在紧跟Bootloader之后。
当程序开始执行时,首先运行的是Bootloader程序,此时Bootloader检测SD卡中的BIN文件并将其复制到APP区域使固件得以更新,固件更新结束后还需要跳转到APP程序开始执行新的程序,完成这最后这一
步要了解Cortex-M3的中断向量表:
程序启动后,将首先从“中断向量表”取出复位中断向量执行复位中断程序完成启动,
当复位中断程序运行完成后才跳转到main函数。
由此可见,在最后一步的设计中需要根
据存放APP程序的起始地址以及中断向量表来设置栈顶地址,并获取复位中断地址跳转到
复位中断程序。
接下来开始分析程序设计步骤。
Bootloader程序设计
1.确定存放APP程序的首地址
#define FLASH_APP_ADDR 0x08010000 //应用程序起始地址(存放在FLASH)上一句
代码中是0X08010000可以看出,留给Bootloader程序的存储空间大小为64K。
存放APP
程序的起始地址为0X08010000。
2.Bootloader检测是否有BIN文件
gCheckFat = f_open(&FP_Struct,"/APP/LIKLON.BIN",FA_READ);//判读gCheckFat确
定上面的代码是检测是否存在liklon.bin这个文件存在,其中liklon.bin文件就是固件升级
所需要的BIN文件。
3.复制文件到指定地址
上一步中如果gCheckFat为0则表示存在所需BIN文件,则可以执行这一步。
f_read (&FP_Struct,ReadAppBuffer,512,(UINT *)&ReadNum); //读取512个字节将512个字节转换为256个16位的数据存放在ChangeBuffer数组中,准备写入FLASH。
FlashWrite(FLASH_APP_ADDR + i * 512,ChangeBuffer,256); //向指定地址写入读出数据向APP程序区写入512个字节的数据。
按照这样读取写入,就可以完成对APP程序区的更新。
4.跳转到新程序运行
更新完程序后就需要跳转到新程序开始运行,具体实现看下面代码:
typedef void (*iapfun)(void); //定义一个函数类型的参数
iapfun jump2app;
__asm void MSR_MSP(u32 addr) //设置堆栈指针
{
MSR MSP, r0
BX r14
}
//跳转到应用程序段
//appxaddr:用户代码起始地址.
void iap_load_app(u32 appxaddr)
{
if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法.
{
jump2app = (iapfun)*(vu32*)(appxaddr+4);//用户代码区第二个字为程序开始地址(复位地址),此处查看中断向量表可知
MSR_MSP(*(vu32*)appxaddr);//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
jump2app(); //跳转到APP,执行复位中断程序
}
}
APP程序设计注意
1.编译软件需要做出设置:
在Bootloader程序中已经指定了APP程序存储的起始地址为0x08010000,所以在APP 程序设计时需要将编译软件这里做出设置,修改起始地址和大小。
2.修改system_stm32f10x.c文件
同样是针对于APP的起始地址改变而修改这里的偏移量,如上图所示。
文中只是简单的介绍了关于Bootloader程序的设计,作为抛砖引玉,大家可以继续深入,添加数据校验和程序加密等。
///////////////////////////////////////////////////////////////////////////////////跳转函数具体说明
1、函数原型:
void Jump_Address(void)
{
if (((*(volatile u32*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
{
test = (*(volatile u32*)ApplicationAddress);
JumpAddress = *(volatile u32*) (ApplicationAddress + 4);
Jump_To_Application = (pFunction) JumpAddress;
__set_MSP(*(volatile u32*) ApplicationAddress);
Jump_To_Application();
}
}
2、if (((*(volatile u32*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)分析:ApplicationAddress存放的是用户程序Flash的首地址,(*(volatile
u32*)ApplicationAddress)的意思是取用户程序首地址里面的数据,这个数据就是用户代码的堆栈地址,堆栈地址指向RAM,而RAM的起始地址是0x20000000,因此上面的判断语句执行:判断用户代码的堆栈地址是否落在:0x20000000~0x2001ffff区间中,这个区间的大小为128K,笔者查阅STM32各型号的RAM大小,目前RAM最大的容量可以做到
192K+4K,时钟频率为168MHZ。
一般情况下,我们使用的芯片较多的落在<128K RAM的区间,因此上面的判断语句是没有太大问题的。
3、经过2的分析,test保存的就是堆栈地址(并且是应用程序堆栈的栈顶地址),查看STM32的向量表,可以知道:栈顶地址 + 4 存放的是复位地址,因此JumpAddress存放的是复位地址。
4、调用__set_MSP函数后,将把用户代码的栈顶地址设为栈顶指针
5、Jump_To_Application();的意思就是设置PC指针为复位地址。
CORTEX-M3上电后后检测BOOT引脚的电平来决定PC的位置。
例:BOOT设置为FLASH 启动,启动后CPU会先取两个地址:一个是栈顶地址,另一个是复位地址。
因此才有了第4、第5点的写法。