0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

STM32的IAP方案实现设计

痞子衡嵌入式 来源:果果小师弟 2023-06-05 14:23 次阅读

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

IAP即为In Application Programming(在应用中编程),一般情况下,以STM32F10x系列芯片为主控制器的设备在出厂时就已经使用J-Link仿真器将应用代码烧录了,如果在设备使用过程中需要进行应用代码的更换、升级等操作的话,则可能需要将设备返回原厂并拆解出来再使用J-Link重新烧录代码,这就增加了很多不必要的麻烦。站在用户的角度来说,就是能让用户自己来更换设备里边的代码程序而厂家这边只需要提供给用户一个代码文件即可。

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

2f350acc-0359-11ee-90ce-dac502259ad0.png

在程序执行初始进入bootloader,在bootloader里面检测条件是否被触发(可通过按键是否被按下、串口是否接收到特定的数据、U盘是否插入等等),如果有则进行对user application进行擦除和重新写入操作,如果没有则直接跳转到user application执行应用;如果有则进行擦除用户代码并重新写入新的用户代码。

二、STM32F103ZET6硬件条件

STM32F103ZET6的启动方式有三种:内置FLASH启动、内置SRAM启动、系统存储器ROM启动,通过BOOT0和BOOT1引脚的设置可以选择从哪中方式启动,这里选择内置的FLASH启动。其FLASH的地址为0x08000000—0x0807 FFFF,共512KB,这些都能从芯片数据手册中直接得到。而这里首要的一个问题是中断的问题。

正常情况下发生中断的过程为:发生中断(中断请求)到中断向量表查找中断函数入口地址跳转到中断函数执行中断函数中断返回。也就是说在STM32的内置的Flash中有一个中断向量表来存放各个中断服务函数的入口地址,内置Flash的分配情况大致如下图。

2f561e92-0359-11ee-90ce-dac502259ad0.png

在只有一个程序的情况下,程序执行的走向应该如图所示。

2f6c17d8-0359-11ee-90ce-dac502259ad0.png

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

在执行main函数的过程中发生中断,则STM32强制将PC指针指回中断向量表处(标号③所示),从中断向量表中找到相应的中断函数入口地址,跳转到相应的中断服务函数(标号④所示),执行完中断函数后再返回到main函数中来(标号⑤所示)。

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

2f90259c-0359-11ee-90ce-dac502259ad0.png

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

2fa21400-0359-11ee-90ce-dac502259ad0.png

上电初始程序依然从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—0x0807 FFFF共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_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。

③写入:

unsignedcharbuf[1024];//假设待写入的代码数据
unsignedshorttemp;//临时数据
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处即可。

①在BootLoader程序的中断向量表指向设置中应有这么一句:

NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);//设置中断向量表指向

其中NVIC_VectTab_FLASH是个宏定义,的值为0x08000000。

②在用户程序的中断向量表指向设置用应有这么一句:

NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x8000);//设置中断向量表指向

四、结束语

总的来说STM32的IAP方案实现需要在进行用户程序之前加一段Bootloader程序,BootLoader程序的作用就是:

1、什么都不做,直接跳转到用户程序。

2、删除原有的用户程序,读取*.bin文件数据并将数据重新写入新的用户程序。对于用户程序相比普通的编程只需要做三步改动即可

3、改变中断向量表。

4、改变代码存放的地址空间

5、修改生成*.bin文件

使用通过UART的IAP方案并不是很好的选择,这只是IAP方案的一个机制,因为能使用PC机通过串口升级程序,同样能通过Jlink烧写程序,并且自定义的串口通讯协议在没有校CRC校验的情况下不能及时发现数据传输过程发生的错误。这里推荐使用SD卡(或U盘)进行用户程序更新,将*.bin文件复制到SD卡(或U盘)中,STM32再通过读取SD卡(或U盘)的*.bin文件进行用户程序更新,这也避免了STM32与PC笨重的通讯,只需插一个SD卡(或U盘)更显得人性化一些,但需要去弄懂STM32如何与SD卡(或U盘)的通讯。




审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 控制器
    +关注

    关注

    112

    文章

    16299

    浏览量

    177783
  • 存储器
    +关注

    关注

    38

    文章

    7481

    浏览量

    163750
  • STM32F103ZET6
    +关注

    关注

    9

    文章

    67

    浏览量

    21121
  • STM32芯片
    +关注

    关注

    0

    文章

    38

    浏览量

    4374

原文标题:给你的代码升个级?—IAP

文章出处:【微信号:pzh_mcu,微信公众号:痞子衡嵌入式】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    STM32IAP方案

    源取出对应的中断向量执行中断服务程序。最后还需要知道关键的一点,通过修改STM32工程的链接脚本可以修改程序文件写入闪存的起始地址。在STM32微控制器上实现IAP
    发表于 03-13 16:38

    STM32IAP方案

    情况,而且若使用远距离或无线的数据传输方案,甚至可以实现远程编程和无线编程。这绝对是ICP或ISP技术无法做到的。某种微控制器支持IAP技术的首要前提是其必须是基于可重复编程闪存的微控制器。S
    发表于 07-19 16:04

    STM32IAP方案

    STM32IAP方案几乎所有的同类书籍都介绍综合性的应用示例如“万年历 + 温度显示 + 闹钟响铃 + 计时表”这样的一个实时时钟范例或“STM32 + 音频解码 + 大容量存储
    发表于 08-25 09:44

    STM32IAP方案

    STM32微控制器的时钟系统、GPIO、定时器、中断系统、异步串口以及内置可编程flash等设备的应用,作为一个综合性实验的同时还具有很强的“实用”意义。这个示例就是STM32IAP方案
    发表于 09-13 16:15

    STM32IAP方案

    STM32微控制器的时钟系统、GPIO、定时器、中断系统、异步串口以及内置可编程flash等设备的应用,作为一个综合性实验的同时还具有很强的“实用”意义。这个示例就是STM32IAP方案
    发表于 09-18 15:52

    STM32IAP方案

    STM32微控制器的时钟系统、GPIO、定时器、中断系统、异步串口以及内置可编程flash等设备的应用,作为一个综合性实验的同时还具有很强的“实用”意义。这个示例就是STM32IAP方案
    发表于 04-13 15:16

    STM32IAP方案

    STM32IAP方案几乎所有的同类书籍都介绍综合性的应用示例如“万年历 + 温度显示 + 闹钟响铃 + 计时表”这样的一个实时时钟范例或“STM32 + 音频解码 + 大容量存储
    发表于 10-14 14:57

    STM32IAP方案分享

    用远距离或无线的数据传输方案,甚至可以实现远程编程和无线编程。这绝对是ICP或ISP技术无法做到的。某种微控制器支持IAP技术的首要前提是其必须是基于可重复编程闪存的微控制器。STM32
    发表于 07-06 04:07

    STM32是如何实现IAP功能的

    STM32实现IAP功能的学习笔记最近因项目需求要实现STM32的在线升级即IAP功能,先将这几
    发表于 08-11 08:07

    使用 USART 实现 STM32F40x/STM32F41x 的 IAP

    使用 USART 实现 STM32F40x/STM32F41x 的 IAP
    发表于 01-25 16:07 16次下载

    使用STM32单片机实现IAP的详细资料说明

    本文档的主要内容详细介绍的是使用STM32单片机实现IAP的详细资料说明。先说一下实现的功能 IAP程序的功能
    发表于 05-17 18:04 28次下载
    使用<b class='flag-5'>STM32</b>单片机<b class='flag-5'>实现</b><b class='flag-5'>IAP</b>的详细资料说明

    STM32--STM32F051 IAP实现

    一、IAP原理及过程《正点原子--STM32F10x串口IAP实验》《stm32f030 IAP》《ST
    发表于 11-29 15:06 32次下载
    <b class='flag-5'>STM32--STM32</b>F051 <b class='flag-5'>IAP</b>的<b class='flag-5'>实现</b>

    STM32通过IAP实现固件升级的分析与示例

    大部分MCU都可以通过IAP对片内flash进行读写来实现固件升级。这里主要是STM32如何实现IAP升级。不同内核的
    发表于 12-14 18:50 11次下载
    <b class='flag-5'>STM32</b>通过<b class='flag-5'>IAP</b><b class='flag-5'>实现</b>固件升级的分析与示例

    STM32实现IAP功能的学习笔记

    最近因项目需求要实现STM32的在线升级即IAP功能,先将这几天的学习体会和IAP的具体实现总结出来,分享给大家,希望对同样
    发表于 12-27 18:41 11次下载
    <b class='flag-5'>STM32</b><b class='flag-5'>实现</b><b class='flag-5'>IAP</b>功能的学习笔记

    关于STM32单片机的IAP实现

    基于STM32F103单片机的IAP实现(虽然该篇文章不会详细写出实现细节,但是会从一个全局的角度讲述,实际的实现细节只需根据datashe
    发表于 02-09 10:29 5次下载
    关于<b class='flag-5'>STM32</b>单片机的<b class='flag-5'>IAP</b><b class='flag-5'>实现</b>