1、什么是IAP?

首先区分下两个概念:ISP和IAP:

ISP:In System Programming (在系统中编程),通过芯片专用的串行编程接口对其内部的程序存储器进行擦写。

IAP:In Application Programming( 在应用中编程),通过调用特定的bootloader程序,对程序存储器的指定段进行读/写操作,从而实现对目标板的程序的修改,目的是为了在产品发布后可以方便地通过预留的通信口对产品中的固件程序进行更新升级。

简单来说ISP就是平时我们用JLINK之类的下载器通过专门的SWD接口来下载程序,IAP就是通过调用bootloader来充当下载器的功能实现更新程序的作用。

2、IAP功能概述

通常实现 IAP 功能时,即用户程序运行中作自身的更新操作,需要在设计固件程序时编写两个项目代码,第一个项目程序不执行正常的功能操作,而只是通过某种通信方式(如 USB、USART)接收程序或数据,执行对第二部分代码的更新。这就是上面说的“bootloader程序”,这部分程序必须通过ISP的方式烧录;第二个项目代码才是真正的用户功能实现代码,这一部分代码可以和第一部分代码一起通过ISP的方式烧录,也可以通过第一部分代码使用IAP进行烧录。

这两部分项目代码都同时烧录在单片机的Flash 中,当芯片上电后,首先运行的是bootloader程序,它可以bootloader程序运行,可以是延时一段时间没检测到更新操作就跳转到第二个程序进行运行;也可以一直运行在等待更新的状态,直到受到触发才(如按键按下触发等)执行跳转到第二个程序的操作;

3、程序的执行流程

STM32H7 的内部闪存(FLASH)地址起始于0X08000000,一般情况下,程序文件就从此地址开始写入。此外STM32H743是基于Cortex-M7内核的微控制器,其内部通过一张“中断向量表”来响应中断。程序启动后,将首先从“中断向量表”取出复位中断向量执行复位中断程序完成启动,而这张“中断向量表”的起始地址是0x08000004,当中断来临,STM32H743的内部硬件机制亦会自动将PC指针定位到“中断向量表”处,并根据中断源取出对应的中断向量执行中断服务程序。

总结起来就是在正常情况下,当单片机复位后,首先从地址0x08000004读取复位中断向量执行复位中断程序完成启动。之后开始执行main函数,一般来说main函数都是在不断循环执行while(1)里面的内容,一旦收到中断请求(发生了中断),此时STM32H743强制将PC指针指回中断向量表处,根据中断源进入相应的中断服务程序,在执行完中断服务程序以后程序再次返回main函数继续执行。

这是正常情况下程序的运行逻辑,因为bootloader程序在FLASH的开头,所以bootloader程序的运行逻辑就和正常的逻辑一样,没有特别的地方,但用户程序就不太一样了。

上面提到过,用户程序和bootloader程序同时保存在FLASH内,并且bootloader程序在FLASH的最前面。由于用户程序的首地址并不是FLASH的首地址,但是“中断向量表”的地址还是没变,那应该怎们办呢?这里就涉及到一个新的知识点叫做“中断向量表的偏移”。

“中断向量表的偏移”的作用就是告诉单片机我现在的程序它的复位中断程序不是在默认的位置。在执行用户程序时,它最开始还是进入0x08000004读取复位中断向量,而不是进入复位以后的复位中断向量地址。为了解决这个问题,中断向量表偏移便应运而生了。通过中断向量表偏移将新的中断向量表的起始地址映射到旧的中断向量表起始地址上,之后再根据新的中断向量表找到复位中断向量执行复位中断程序完成启动。这个时候由于新的中断向量表地址已经映射过去了,所以现在系统的向量地址已经是第二个程序的中断地址,所以现在时候的程序执行过程完全和正常程序一样了。

这里便产生了一个问题,“中断向量表的偏移”该如何设置呢?在H7的HAL_库文件“system_stm32h7xx.c”里面有以下几行代码:

/* Configure the Vector Table location -------------------------------------*/#if defined(USER_VECT_TAB_ADDRESS)SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal D1 AXI-RAM or in Internal FLASH */#endif /* USER_VECT_TAB_ADDRESS */

这几行代码的意思就是如果定义了USER_VECT_TAB_ADDRESS,那就执行中断向量表偏移的语句。USER_VECT_TAB_ADDRESS是用户中断向量表偏移标志,VECT_TAB_BASE_ADDRESS是SRAM的偏移量,VECT_TAB_OFFSET是FLASH的偏移量。

对于我们的用户程序来说,要实现中断向量表偏移有2种方式,一种是使用HAL_库文件中上面说到的HAL库变量,直接对USER_VECT_TAB_ADDRESS标志和偏移量进行赋值,但这个会改变HAL库系统文件。第二种就是在main函数开始就执行中断向量表偏移语句,采用这种方法可以保证HAL库系统级别的文件不被更改,只修改用户程序,便于以后的移植。

4、bootloader程序运行过程

bootloader程序在上电后首先将各项外设进行初始化,尤其是用于传输升级文件的通讯外设。在外设初始化结束后一般都在while(1)循环中等待接收需要用于升级的数据。一旦数据接收完成则调用“iap_write_appbin”函数将接收的信息写入到用户程序对应的内存地址中,在写入完成后再通过“iap_load_app”函数跳转到用户程序进行执行。亦或者在等待一定时间后如果还没接收到需要升级的文件就跳转到用户程序进行执行。

“iap_write_appbin”函数需要调用FLASH读写函数将接收的信息写入到FLASH的指定区域。函数如下:

//appxaddr:应用程序的起始地址//appbuf:应用程序CODE.//appsize:应用程序大小(字节).void iap_write_appbin(u32 appxaddr,u8 *appbuf,u32 appsize){u32 t;u16 i=0;u32 temp;u32 fwaddr=appxaddr;//当前写入的地址u8 *dfu=appbuf;for(t=0;t<appsize;t+=4){ temp=(u32)dfu[3]<<24;   temp|=(u32)dfu[2]<<16;    temp|=(u32)dfu[1]<<8;temp|=(u32)dfu[0];   dfu+=4;//偏移4个字节iapbuf[i++]=temp;     if(i==512){i=0;STMFLASH_Write(fwaddr,iapbuf,512);fwaddr+=2048; //偏移2048  512*4=2048}}if(i)STMFLASH_Write(fwaddr,iapbuf,i);   //将最后的一些内容字节写进去.  }

STM32单片机中不同内核的芯片其内存管理方式不太一样。

STM32H7系列单片机采用的是存储区(BANK)和扇区(SECTOR)的结构。STM32H7的FLASH分为两个独立的存储区(即BANK1和BANK2),每个存储区再由多个128K大小的扇区组成。由于STM32H7的FLASH最小1M,最大2M,所以每一个存储区就被分成了4或8个扇区,分别对应(SECTOR_0至SECTOR_7)。由于扇区是结构中最小的单位,这就决定了FLASH的最小单位就扇区(即128K大小),所以在设置内存地址时需要注意,不要在擦除时不小心擦除了需要使用的区域。

STM32F1系列单片机采用的是页面(Page)的结构,FLASH被分割成了多个Page。根据FLASH的大小不同,Page的大小有2K或者1K的不同。由于F1系列最大FLASH为512K,所以Page最大为256个(Page0至Page255)。这就决定了FLASH每次擦除最小都要擦除一个页面的大小。

“iap_load_app”函数先判断栈顶地址是否合法,在得到合法的栈顶地址后,通过MSR_MSP 函数设置栈顶地址,最后通过一个虚拟的函数(jump2app)跳转到 APP 程序执行代码,实现 IAP→APP 的跳转。函数如下:

//跳转到应用程序段//appxaddr:用户代码起始地址.void iap_load_app(u32 appxaddr){if(((*(vu32*)appxaddr)&0x2FF00000)==0x24000000)//检查栈顶地址是合法性.{printf("跳转到APP\r\n");jump2app=(iapfun)*(vu32*)(appxaddr+4); //第二个字为复位地址)MSR_MSP(*(vu32*)appxaddr);      //初始化APP堆栈指针jump2app();  //跳转到APP.}}

5、如何设置程序的起始地址

在MDK5编译器中,点击Options for Target→Target选项卡,其中的IROM便是用来设置程序存储区的大小。其后面2个框框分别填写程序存储区的起始地址和大小。比如我要将FLASH的前256K字节大小区域用于bootloader程序,由于FLASH的首地址为0X8000000,所以第一个框框就应该填0X8000000。由于只允许bootloader程序使用前256K字节大小的内存,所以总的大小为256*1024=262144字节,转换成16进制为0X40000,所以第二个框框就应该填0X40000。如下图所示:

6、bin文件的生成

在使用IAP进行升级时,使用bin文件会更加方便,所以在编写完APP文件以后需要将MDK5默认生成的hex文件转换成bin文件。

在MDK中自带有一个hex文件到bin文件的转换工具,它就是“fromelf.exe”,它的位置为“D:\Keil5\ARM\ARMCC\bin|”(D:\Keil5是自己MDK5的安装目录)。它的基本语法为{“fromelf.exe软件地址” --bin -o “bin文件地址”  “axf文件地址”}(上述地址需要包含本文件的完整名称,地址可以是相对地址,例如:"fromelf.exe" --bin -o .\WAM-USART-IAP\App.bin .\WAM-USART-IAP\App.axf)。z

如果要在MDK中使用该工具,只需点击Options for Target→User选项卡,找到下面的“After Build/Bebuild”选项。勾选“选Run #1”并在后面的框框中填入fromelf.exe软件的语法语句,最后点击OK即可。操作如下图:

STM32单片机IAP介绍相关推荐

  1. 关于STM32单片机IAP升级中if(((*(__IO uint32_t*)ulAddr_App) 0x2FFE0000) == 0x20000000)语句的理解

    没有标题 初见if(((*(__IO uint32_t*)ulAddr_App) & 0x2FFE0000) == 0x20000000) 语句理解 语句功能 为什么ulAddr_App里存的 ...

  2. 9、★♥★基于STM32单片机的颜色检测仪设计♥☆

    9.★♥★基于STM32单片机的颜色检测仪设计♥☆ 文章目录 9.★♥★基于STM32单片机的颜色检测仪设计♥☆ 引言 1.系统概述 1.1.设计任务 1.2.设计要求 2.方案设计与论证 2.1.芯 ...

  3. 电源学习(1):stm32单片机buck电路可调电源设计介绍

    最近,搞了一块stm32单片机的降压电路板,效果还不错分享分享给大家. 首先上图看效果! 下图 输入电压在20v不变,效果如图所示. 然后我又测了几组数据供大家参考一下,具体电路后续在写了 可见负载调 ...

  4. 【STM32单片机学习】第三课:开发板介绍和Keil环境搭建

    [朱老师课程总结 侵删] 第一部分.章节目录 3.3.1.STM32开发板详细介绍 3.3.2.STM32开发板ISP下载原理分析 3.3.3.STM32F4的浮点运算单元 3.3.4.MDK5的开发 ...

  5. STM32实现IAP功能之一

    最近因项目需求要实现STM32的在线升级即IAP功能,先将这几天的学习体会和IAP的具体实现总结出来,分享给大家,希望对同样实现IAP的童鞋有所帮助,文中最后会上传名为STM32_Update.zip ...

  6. 基于STM32单片机的差分升级(增量升级)算法

    DiffIAP – STM32单片机可用的差分升级(增量升级),适用于物联网车联网IAP升级OTA升级 应用背景 随着目前物联网,车联网,智能设备的增多,需要远程升级设备程序的场景增多,以往的IAP升 ...

  7. STM32应用IAP进行程序更新详解及实例

      这是以前就想写的一个小专题关于IAP,以及IAP在STM32编程的应用,专题分三小节,主要介绍常见的单片机烧录方式,IAP的实际应用,以及Ymodem协议在IAP编程中应用,在笔记吃灰很久了,终于 ...

  8. 基于STM32单片机的差分升级(增量升级)算法移植手册V.3 STM32+BSDiff+LZ77

    基于STM32单片机的差分升级算法移植手册V.3 STM32+BSDiff+LZ77 更新时间:2022-03-10 版本V1.3 同步更新如下: 基于STM32单片机的差分升级(增量升级)算法V1. ...

  9. stm32怎么加载字库_收藏 | STM32单片机超详细学习汇总资料(二)

    点击"蓝字"关注我们 3110月 收藏 | STM32单片机超详细学习汇总资料(一) ◆41.DMA仲裁器分为软件和硬件两种.软件部分分为4个等级,分别是很高优先级.高优先级.中等 ...

最新文章

  1. PostgreSQL第一步:安装
  2. 科大星云诗社动态20210208
  3. 英文单词 hard
  4. 小白自学深度学习——目录
  5. AtCoder Regular Contest 110 E.Shorten ABC——坑
  6. IntelliJ IDEA普通的Java项目如何转成Maven Web项目
  7. VBoxManage: error: Nonexistent host networking interface, name 'vboxnet0' (VERR_INTERNAL_ERROR)
  8. uart怎么判断帧错误_UART通讯总线工作原理的理解--龚玉山
  9. Java Web中相对路径与绝对路径的分析
  10. Unique Binary Search Trees ll -深度优先遍历DFS
  11. 通用模块(4)——EEPROM(AT24C08)
  12. onenote打开闪退平板_ipad pro 11英寸。onenote闪退 无法使用
  13. 背包问题(简单回溯)
  14. 不会 Python 没关系,手把手教你用 web scraper 抓取豆瓣电影 top 250 和 b 站排行榜
  15. python求斐波那契数列,阶层
  16. 解决验证码显示不了的方案
  17. 使用git将代码提交到github
  18. 《淮南师范学院学报》(双月刊)投稿须知
  19. 上网看视频国家版八段锦,很好的预防和治疗久坐办公室带来的肩周颈椎疾病...
  20. win10:应用程序无法正常启动(0xc0000142),请单击“确认”关闭程序

热门文章

  1. C70600白铜棒/90-10铜镍合金管Cu90Ni10铁白铜
  2. 【毕业设计/Matlab系列】基于PCA和BP神经网络的人脸识别系统(附matlab代码)
  3. Nginx--secure_link和geoip_module
  4. 创新与赛道定义 ——产品定义和建立赛道是个技术活
  5. 高校计算机教师个人总结,大学教师个人总结与自我评价
  6. Exp10 Final 类CTF(Webug3.0漏洞靶场—渗透基础)
  7. Ext4 超级块详解
  8. a标签 rel属性
  9. mysql 统计SQL
  10. ios html特殊字符转义字符,iOS URL 字符转义问题