datasheet

IAR环境下STM32F103ZET6+IAP方案的实现

2019-06-13来源: eefocus关键字:IAR环境  STM32F103ZET6  IAP方案

一、什么是IAP,为什么要IAP

      IAP即为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,这些都能从芯片数据手册中直接得到。而这里首要的一个问题是中断的问题。正常情况下发生中断的过程为:发生中断(中断请求)à到中断向量表查找中断函数入口地址à跳转到中断函数à执行中断函数à中断返回。也就是说在STM32的内置的Flash中有一个中断向量表来存放各个中断服务函数的入口地址,内置Flash的分配情况大致如下图2-1。

图2-1

 

在只有一个程序的情况下,程序执行的走向应该如图2-2所示(借用网友的原图)。

图2-2

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

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

图2-3

在内置的Flash里面添加一个BootLoader程序,BootLoader程序和user application各有一个中断向量表,假设BootLoader程序占用的空间为N+M字节,则程序的走向应该如图2-2所示(借用网友的原图并做改动,其中虚线部分为原图步骤④⑤的走向,本人改为指向灰色部分)。

图2-2

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

      对于步骤④⑤,网友认为是:“在main执行的过程中,如果CPU得到一个中断请求,PC指针仍强制跳转到地址0x08000004中断向量表处,而不是新的中断向量表,如图标号④所示,程序再根据我们设置的中断向量表偏移量,跳转到对应中断源新的中断服务程序中,如图标号⑤所示”。我对此的理解是:“当发生中断后,程序从0x08000004(旧)处的中断向量表中得到相应的中断服务函数入口地址,继而跳转到相应的中断服务程序”。但是旧的中断向量列表里边存放的是IAP程序中断函数的入口地址,它是如何得到user程序中断函数的入口地址呢?所以我觉得此种说法是错误的。“当发生中断时PC指针强制会跳转到0x08000004处”这种说法并没有错,只是忽略了后续的一些知识要点而导致这个说法出现矛盾。

      对于步骤④⑤我认为的是,在main函数的执行过程中,如果CPU得到一个中断请求,PC指针本来应该跳转到0x08000004处的中断向量表,由于我们设置了中断向量表偏移量为N+M,因此PC指针被强制跳转到0x08000004+N+M处的中断向量表中得到相应的中断函数地址(待求证),再跳转到相应新的中断服务函数,执行结束后返回到main函数中来。

 

三、实现过程

      STM32F103ZET6的Flash地址为0x08000000—0x0807ffff共512KB,把这512KB的空间分为两块,第一块大小为32KB存放BootLoader程序,剩余的空间存放用户程序(根据实际情况分配这两块空间的大小,BootLoader程序占用的空间越小越好,则BootLoader地址为0x08000000—0x08007fff,用户程序地址为0x08008000—0x0807ffff。BootLoader流程图大致应该如下:

1、初始化时钟。

2、初始化中断向量表地址。

3、初始化按键。      (使用按键触发方式,上电时如果按键被按下则进行用户程序更新操作)

4、初始化串口。

5、检测按键是否被按下,是则执行步骤6,否则执行步骤10。

6、擦除用户程序(擦除0x08008000—0x0807ffff地址空间Flash)。

7、从串口读取新的用户代码数据,把代码写入用户程序空间。

8、检测串口数据接收完毕?是则执行步骤9,否则跳回步骤7。

9、用户程序更新完毕,等待重新上电或硬件复位。

10、跳转到用户程序(强制将PC指针跳转到0x08008000+4处)。

     

到这里首先要解决的问题就有:

1、如何进行对STM32的Flash进行擦除和写入操作。

2、中断向量表偏移如何设置。

3、如何改变代码存放的地址空间(因为BootLoader要存放在0x08000000处,用户程序要存放在0x08008000处,而默认的代码存放的地址空间为0x08000000)。

4、怎么进行PC指针的强制跳转,跳转时需要做些什么。

5、串口接收的用户代码数据是什么样的代码数据,是一种什么样的文件。

 

问题的解决:

1、使用STM32的固件库函数,只需调用几个库函数即可轻松解决,使用的固件库为stm32f10x_flash.c文件,对Flash的操作过程简要为:Flash解锁àFlash擦除àFlash写入àFlash上锁。(对Flash编程的更详细操作参考STM32F10xxx闪存编程手册)

①解锁:

FLASH_Unlock();            //解锁Flash

FLASH_SetLatency(FLASH_Latency_2);            //因为系统时钟为72M所以要设置两个时钟周期的延时

②擦除:

for(i=0;i<240;i++)

{

  if(FLASH_ErasePage(FLASH_ADDR+i*2048) != FLASH_COMPLETE)      //一定要判断是否擦除成功

    return ERROR;

}

说明:FLASH_ErasePage(uint32_t Page_Address)即为Flash擦除操作,按页擦除,每页2KB,Page_Address为页的起始地址,如0x08000000是第一页起始地址,0x08000800为第二页起始地址,这里的操作擦除了0x08008000—0x0807ffff地址空间的Flash。

③写入:

unsigned char buf[1024];            //假设待写入的代码数据

unsigned short temp;            //临时数据

for(i=0;i<512;i++)

{

      temp = (buf[2*i+1]<<8) | buf[2*i];            //2个字节整合为1个半字

      if(FLASH_ProgramHalfWord(ADDR,temp) != FLASH_COMPLETE)      //判断是否写入成功

      {

            Return ERROR;

      }

ADDR +=2;      //地址要加2,因为每次写入的是2个字节(1个半字)

}

说明:因为STM32的Flash写入为双字节(1个半字)写入,FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)函数即为对地址为Address写入1个半字的Data,每次写入完成后地址要加2。

④上锁:

FLASH_Lock();      //Flash 上锁,一个固件库函数即可实现。

 

2、关于中断向量表的偏移设置,对于BootLoader程序只需设置中断向量表的指向在0x08000000处,对于用户程序需要设置中断向量表的指向在0x08008000处即可。

[1] [2]

关键字:IAR环境  STM32F103ZET6  IAP方案

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/ic464493.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32:SPI驱动ADXL345
下一篇:STM32如何使用内部时钟源当系统时钟

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM8 IAR环境生成hex文件

发表于 2018-06-02

STM8中断的设置(ST Visual Develop和IAR环境下)

以下以stm8s103为例介绍在ST Visual Develop和IAR环境下的中断设置;这两种只是环境不同其实中断向量是不会变的,先看一下数据手册,再结合芯片手册中中断向量映像表,如下图所示结合起来的话我们就能够理解的。在用ST Visual Develop环境时新建一个新的Stm8工程它会自动生成一个main.c和一个stm8_interrupt_vector.c文件。空白的main.c文件时如下所示的:[cpp] view plaincopy/* MAIN.C file  *   * 
发表于 2018-06-01

IAR环境下STM32+IAP方案的实现

;而IAP却能很好的解决掉这个难题,一片STM32芯片的Code(代码)区内一般只有一个用户程序。而IAP方案则是将代码区划分为两部分,两部分区域各存放一个程序,一个叫bootloader(引导加载程序),另一个较user application(用户应用程序)。bootloader在出厂时就固定下来了,在需要变更user application时只需要通过触发bootloader对userapplication的擦除和重新写入即可完成用户应用的更换。如图1-1所示 图 1-1       在程序执行初始
发表于 2016-07-27
IAR环境下STM32+IAP方案的实现

在IAR环境下LPC2129平台上脉冲捕捉导致死机问题

在项目进行过程中,设置了脉冲捕捉,然后产生中断,我的做法是,设置了个全局变量环形数组,将捕获的脉冲计数值与前一次作差后放入环形数组里,然后由相关任务去处理。然是奇怪的是,捕捉中断进行几次之后就不再响应了,而且还会导致死机,代码如下: #define LCD_LED_SW  1<<24 //extern OS_EVENT *pMbox_App_CapISR_Flowmeter; INT8U capCnt = 0; INT32U rcvLast = 0; extern INT32U rcvBuf[]; extern BOOLEAN flag_capISR; void  BSP_Tmr_Cap
发表于 2016-04-20

stm32 IAR环境printf函数调用

在串口都配置好的情况下,在main.c文件中加入 #include <stdio.h> #ifdef __GNUC__     #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else   #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif   PUTCHAR_PROTOTYPE {       USART_SendData(EVAL_COM1, (uint8_t) ch);
发表于 2015-10-14

STM32F103ZET6 — WWDG

简介与 STM32 的 IWDG 一样,窗口看门狗的作用也是从不可预知的情况下,进行恢复的一种手段,只不过窗口看门狗的用法和 IWDG 有一定的差异,主要体现在“窗口”二字。那么什么是窗口看门狗呢?顾名思义,窗口看门狗就是在指定的时间窗口进行喂狗,才有效,在窗口外进行喂狗,都视为无效。具体的内容,请看下面分析时钟与独立看门狗 IWDG 不同,WWDG 窗口看门狗由 APB1 提供时钟输入:工作原理WWDG 的基本组成为:可编程的自由运行递减计数器。条件复位        ---- 当递减计数器的值小于0x40,(若看门狗被启动)则产生复位。       
发表于 2019-04-09
STM32F103ZET6 — WWDG

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved