STM32F407单片机编程入门(十三) 单片机IAP(在应用编程)详解及实战源码

文章目录

    • 一.概要
    • 二.STM32F407VET6单片机IAP介绍
      • 1.STM32F407VET6单片机IAP基本原理
      • 2.STM32F407VET6单片机IAP基本流程
    • 三.配置一个BOOT工程
    • 四.配置一个APP工程
    • 五.工程源代码下载
    • 六.小结

一.概要

STM32单片机程序升级方法有很多种,主要有以下几种:

1.将编译生成的hex/bin文件使用ST-Link/J-Link工具直接下载进 Flash 即可,Keil中点击下载就能下载,下载后的代码会存放在Flash的起始地址0x08000000处。

2.ISP(In System Programing),这个是利用了STM32单片机自带的 Bootloader 升级程序。一般可通过USART串口对Flash重新编程,再通过电脑上的ISP下载软件导入程序。在用户参考手册中,可以看到下表,关于启动模式设置的,ISP就是BOOT1引脚为0,BOOT0引脚为1,单片机就进入ISP模式。
在这里插入图片描述
3. IAP(In Application Programing),即在应用编程,与之相对应的叫做ISP,两者的不同是ISP需要依靠烧写器在单片机复位离线的情况下编程,需要人工的干预,而IAP则是用户自己的程序在运行过程中对Flash 的部分区域进行烧写,目的是为了在产品发布后可以方便地通过预留的通信口对产品中的固件程序进行更新升级。

使用IAP技术能很好地降低现场工作量,实现IAP有两个很重要的前提
1.单片机程序能对自身的内部Flash 进行擦写。
2.单片机要有能够和外部进行通讯的方式,无论是网络还是别的方式,只要能传输数据就行。

二.STM32F407VET6单片机IAP介绍

1.STM32F407VET6单片机IAP基本原理

以STM32F407VET6单片机为例,每次程序复位是从0x08000000的位置开始执行主程序,如果不做IAP则这256KB(0x40000)空间都可以用来存放应用程序,但为了实现IAP,需要有划出一部分空间存放BOOT程序,BOOT程序跟应用程序是两个独立的工程,BOOT程序主要功能是来接收外部通讯(串口,485等)协议传输的应用程序代码文件(bin文件),并调用FLASH写入函数把bin文件分成N个32Bit数据,写入到应用程序地址空间,就实现对应用程序的升级。
在这里插入图片描述

2.STM32F407VET6单片机IAP基本流程

单片机先在BOOT工程的程序中跑,BOOT程序通过串口1(PA9,PA10引脚)接收上位机发来的.bin文件(应用程序工程),检查后将.bin文件写入到Flash特定位置(0x08004000开始的地址),bin文件写完后,单片机就从BOOT程序的空间跳转到应用程序的空间运行。
在这里插入图片描述
Bin文件是直接包含单片机的机器码,不包含调试信息或其他额外数据,这使得在传输过程中,无论是通过串口、网络还是其他接口,都能实现高效的二进制数据传输,所以一般IAP升级,就选用Bin文件下载到单片机指定的地址空间,就实现了程序升级目的。

三.配置一个BOOT工程

本实验配置一个包含跳转的程序工程,程序起始地址是0x0800000,大小是0x4000,包含FLASH写入以及Y-Modem协议。

打开STM32CubeMX软件,新建工程
在这里插入图片描述
Part Number处输入STM32F407VE,再双击就创建新的工程
在这里插入图片描述

配置下载口引脚
在这里插入图片描述

配置外部晶振引脚
在这里插入图片描述

配置系统主频168Mhz,使用外部晶振
在这里插入图片描述

配置PA9,PA10配置成串口1收发脚,波特率115200,8位数据,无校验,1位停止位。

在这里插入图片描述

串口1中断使能
在这里插入图片描述

配置工程文件名,保存路径,KEIL5工程输出方式
在这里插入图片描述
生成工程
在这里插入图片描述
用Keil5打开工程
在这里插入图片描述

添加代码
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

主要代码如下:

int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */Main_Menu();//实现程序升级并跳转,Ymodem协议}/* USER CODE END 3 */
}void Main_Menu(void)
{SerialPutString("\r\n  STM32F407 In-Application Programming Application  \r\n");while (1){SerialDownload();}
}
void SerialDownload(void)
{int32_t Size = 0;Size = Ymodem_Receive(&tab_1024[0]);if (Size > 0){SerialPutString("\r\n Programming Completed Successfully!\r\n ");HAL_Delay(10);SerialPutString("----------Jump To App-------------\r\n");CLI();RCC_DeInit();NVIC_DeInit();JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);//定义跳转地址是0x08004000JumpToApplication = (pFunction) JumpAddress;/* Initialize user application's Stack Pointer */__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);JumpToApplication();//跳转到应用程序}else if (Size == -1){SerialPutString("\n\n\rThe image size is higher than the allowed space memory!\n\r");}else if (Size == -2){SerialPutString("\n\n\rVerification failed!\n\r");}else if (Size == -3){SerialPutString("\r\n\nAborted by user.\n\r");}else{SerialPutString("\n\rFailed to receive the file!\n\r");}
}int32_t Ymodem_Receive (uint8_t *buf)
{uint8_t*file_ptr, *buf_ptr;int32_t i, packet_length, session_done, file_done, packets_received, errors, session_begin, size = 0;uint32_t flashdestination, ramsource;/* Initialize flashdestination variable */flashdestination = APPLICATION_ADDRESS;for (session_done = 0, errors = 0, session_begin = 0; ;){for (packets_received = 0, file_done = 0, buf_ptr = buf; ;){switch (Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT)){case 0:errors = 0;switch (packet_length){/* Abort by sender */case - 1:Send_Byte(ACK);return 0;/* End of transmission */case 0:Send_Byte(ACK);file_done = 1;break;/* Normal packet */default:if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff)){Send_Byte(NAK);}else{if (packets_received == 0){/* Filename packet */if (packet_data[PACKET_HEADER] != 0){/* Filename packet has valid data */for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);){FileName[i++] = *file_ptr++;}FileName[i++] = '\0';for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < (FILE_SIZE_LENGTH - 1));){file_size[i++] = *file_ptr++;}file_size[i++] = '\0';Str2Int(file_size, &size);/* Test the size of the image to be sent *//* Image size is greater than Flash size */if (size > (USER_FLASH_SIZE + 1)){/* End session */Send_Byte(CA);Send_Byte(CA);return -1;}/* erase user application area *///FLASH_If_Erase(APPLICATION_ADDRESS);fmc_erase_pages();Send_Byte(ACK);Send_Byte(CRC16);}/* Filename packet is empty, end session */else{Send_Byte(ACK);file_done = 1;session_done = 1;break;}}/* Data packet */else{memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length);ramsource = (uint32_t)buf;TimeOutCounter=0;/* Write received data in Flash */if (FLASH_If_Write(&flashdestination,ramsource, (uint16_t) packet_length/4)  == 0){Send_Byte(ACK);}else /* An error occurred while writing to Flash memory */{/* End session */Send_Byte(CA);Send_Byte(CA);return -2;}}packets_received ++;session_begin = 1;}}break;case 1:Send_Byte(CA);Send_Byte(CA);return -3;default:if (session_begin > 0){errors ++;}TimeOutCounter++;if(TimeOutCounter>=50){SerialPutString("----------Jump To App-------------\r\n");CLI();RCC_DeInit();NVIC_DeInit();JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);//定义跳转地址是0x08004000JumpToApplication = (pFunction) JumpAddress;/* Initialize user application's Stack Pointer */__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);JumpToApplication();//跳转到应用程序}if (errors > MAX_ERRORS){Send_Byte(CA);Send_Byte(CA);return 0;}Send_Byte(CRC16);break;}if (file_done != 0){break;}}if (session_done != 0){break;}}return (int32_t)size;
}

四.配置一个APP工程

本实验需要配置一个LED闪烁的程序工程,并改变程序起始地址到0x08004000

打开STM32CubeMX软件,新建工程
在这里插入图片描述
Part Number处输入STM32F407VE,再双击就创建新的工程
在这里插入图片描述

配置下载口引脚
在这里插入图片描述

配置外部晶振引脚
在这里插入图片描述

可以查看STM32F407VET6开发板原理图,PB4连接LED灯,所以配置PB4为GPIO输出

在这里插入图片描述

配置系统主频168Mhz,使用外部晶振
在这里插入图片描述

配置工程文件名,保存路径,KEIL5工程输出方式
在这里插入图片描述

生成工程
在这里插入图片描述

用Keil5打开工程
在这里插入图片描述

配置应用程序起始地址
在这里插入图片描述

输出.bin文件配置,配置完,编译的时候就会生成.bin文件
在这里插入图片描述

中断向量表偏移配置
在这里插入图片描述

主要代码如下:

void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset)
{ /* Check the parameters */assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));assert_param(IS_NVIC_OFFSET(Offset));  SCB->VTOR = NVIC_VectTab | Offset;
}
#define CLI() __set_PRIMASK(1)//关闭总中断  
#define SEI() __set_PRIMASK(0)//打开总中断
int main(void)
{/* USER CODE BEGIN 1 */SEI();						//打开全局中断,因为在IAP中关闭了全局中断NVIC_SetVectorTable(FLASH_BASE, 0x4000);	//定位中断向量表/* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();//初始化1毫秒 Tick/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();//外部8M晶振,系统168M主频/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_4);//PB4引脚翻转输出HAL_Delay(100);//等待100ms}/* USER CODE END 3 */
}

实验效果:
BOOT程序:主要实现YMODEM协议以及内部FLASH编程,程序烧录完之后,由APP程序生成的APP.Bin文件烧录到APP程序的FLASH地址空间,再实现程序跳转。

1.Keil5打开BOOT工程,编译,并烧录BOOT程序。
2. Keil5打开APP程序,编译,生成APP.bin文件,文件在工程Objects目录下。
3.插上USB转TTL,接上TX<—>板子PA10,RX<—>板子PA9,GND<—>板子GND。打开超级终端,配置115200波特率,无校验,无数据流控制。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
4. 复位板子,超级终端会显示下图所示,会有C字符显示。

在这里插入图片描述
5. 在C字符显示的过程中,选择传送,发送文件,选择407.bin文件,在APP\MDK-ARM\407路径下,协议选择YMODEM,点击发送。

在这里插入图片描述
在这里插入图片描述
6. 会有进度条发送显示,并显示发送成功,并跳转到APP,如果超时没有发送,也会在超时几秒后自动跳转到APP。
在这里插入图片描述

五.工程源代码下载

通过网盘分享的文件:14.IAP升级实验.zip
链接: https://pan.baidu.com/s/16gM7B6-xoq9d4KBajG3qBg 提取码: 9nd2

如果链接失效,可以联系博主给最新链接
程序下载下来之后解压就行

CSDN资源

六.小结

在单片机应用中,在线升级功能是必不可少的,它可以让我们在不破坏硬件的情况下对程序进行升级和修正,提高了开发效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1542400.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【LeetCode】146. LRU缓存

1.题目 2.思想 3.代码 3.1 代码1 下面这是一版错误的代码。错误的原因在于逻辑不正确导致最后的代码也是不正确的。 class LRUCache:def __init__(self, capacity: int):self.time 0 # 用于全局记录访问的时间self.num2time {} # 数字到时间的映射self.key2val {} # 数字…

如何理解MVCC

MVCC是什么&#xff1f; MVCC&#xff0c;是MultiVersion Concurrency Control的缩写&#xff0c;翻译成中文就是多版本并发控制&#xff0c;多个事务同时访问同一数据时&#xff0c;调控每一个事务获取到数据的具体版本。和数据库锁一样&#xff0c;它也是一种并发控制的解决…

实时同步 解决存储问题 sersync

目录 1.sersync服务 2.sersync同步整体架构 ​编辑 3.rsync服务准备 4.sersync部署使用 5.修改配置文件 6.启动sersync 7.接入nfs服务 8.联调测试 1.sersync服务 sersync服务其实就是由两个服务组成一个是inotify服务和rsync服务组成 inotify服务用来监控那个…

Infineon——TC397 Multicore简介

文章目录 前言一、TC397简介二、命名规则三、多核开发建议 前言 AURIX™ TC3xx微控制器架构具有多达6个独立的处理器内核CPU0…CPU5, 可在一个统一平台上无缝托管多个应用程序和操作系统. 由于实现了具有独立读取接口的多个程序Flash模块, 该架构支持进一步的实时处理. AURIX™…

自学笔记之TVM编译器框架 ,核心特性,模型优化概述,AI应用落地

最近在学习一些和芯片 AI相关的知识&#xff0c;重点了解了一下TVM&#xff0c;我自己认为TVM在AI应用落地类似的项目中&#xff0c;用途还是非常广泛的&#xff0c;现在把一些重要的笔记贴在下面&#xff0c;有两篇原帖链接也附上&#xff0c;感兴趣的同学可以学习一下。 TVM…

小球轻重的测量

设有12个小球。其中11个小球的重量相同&#xff0c;称为好球&#xff1b;有一个小球的重量与11个好球的重量不同&#xff08;或轻或重&#xff09;&#xff0c;称这个小球为坏球。试编写一个算法&#xff0c;用一个无砝码的天平称三次找出这个坏球&#xff0c;并确定其比好球轻…

SpringCloud入门(五)Nacos注册中心(上)

国内公司一般都推崇阿里巴巴的技术&#xff0c;比如注册中心&#xff0c;SpringCloudAlibaba也推出了一个名为Nacos的注册中心。Dynami Naming and Configuration Service。是阿里巴巴2018年7月开源的项目。 Nacos是阿里巴巴的产品&#xff0c;现在是SpringCloud中的一个组件。…

智谱清影 - CogVideoX-2b-部署与使用

&#x1f351;个人主页&#xff1a;Jupiter. &#x1f680; 所属专栏&#xff1a;Linux从入门到进阶 欢迎大家点赞收藏评论&#x1f60a; 目录 体验地址&#xff1a;[丹摩DAMODEL官网](https://www.damodel.com/console/overview) CogVideoX 简介本篇将详细介绍使用丹摩服务器部…

网络通信——OSI七层模型和TCP/IP模型

OSI模型 一.OSI七层模型 OSI&#xff08;Open System Interconnect&#xff09;七层模型是一种将计算机网络通信协议划分为七个不同层次的标准化框架。每一层都负责不同的功能&#xff0c;从物理连接到应用程序的处理。这种模型有助于不同的系统之间进行通信时&#xff0c;更…

KamaCoder 103. 水流问题

题目要求 N*M的矩阵&#xff0c;数值代表位置的相对高度。矩阵模拟了一个地形&#xff0c;当雨水落上时&#xff0c;会根据地形倾斜向低处流动。但是只能从较高或等高的地点流向较低或等高并且相邻的地点&#xff0c;我们的目标是确定那些单元格&#xff0c;从这些单元格出发的…

Vue(14)——组合式API①

setup 特点&#xff1a;执行实际比beforeCreate还要早&#xff0c;并且获取不到this <script> export default{setup(){console.log(setup函数);},beforeCreate(){console.log(beforeCreate函数);} } </script> 在setup函数中提供的数据和方法&#xff0c;想要在…

101. 对称二叉树(共含三道leetcode题)

文章目录 101. 对称二叉树递归法迭代法 小结100.相同的树572.另一个树的子树 101. 对称二叉树 101. 对称二叉树 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true示例 2&#…

Administration Console后台弱⼝令登录

1.环境搭建 cd vulhub-master/iboss/CVE-2017-12149 docker-compose up-d 2.访问登录页面 JBoss AS 6 Admin Consolehttp://47.121.211.205:8080/admin-console/login.seam?conversationId4用户名admin 密码vulhub 3.上传war文件 4.访问上传文件并进行连接 访问上传文件 使…

kubectl 执行一条命令之后发生了什么?

kubectl 是与 Kubernetes 集群交互的命令行工具&#xff0c;用户通过它可以对集群资源进行操作和管理。你有没有想过&#xff0c;当我们执行一条 kubectl 命令之后&#xff0c;背后都发生了什么&#xff1f; 详细过程 kubectl -> kube-api-server 根据通信类型&#xff0…

算法题之宝石与石头

宝石与石头 给你一个字符串 jewels 代表石头中宝石的类型&#xff0c;另有一个字符串 stones 代表你拥有的石头。 stones 中每个字符代表了一种你拥有的石头的类型&#xff0c;你想知道你拥有的石头中有多少是宝石。 字母区分大小写&#xff0c;因此 "a" 和 "…

EECS498 Deep Learning for Computer Vision (一)软件使用指南

#最近开始学习深度学习的相关基础知识&#xff0c;记录一下相关笔记及学习成果# learning&#xff1a;building artificial systems that learn from data and experience deep learning(a set of machine learning): hierarchical learning algorithms with many "laye…

制作一个rabbitmq-sdk以及rabbitmq消费者实现定时上下线功能

目录结构 pom.xml <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">&l…

低版本JMX Console未授权

1.环境搭建 cd vulhub-master/jboss/CVE-2017-7504 docker-compose up -d 2.访问漏洞网站 http://47.121.211.205:8080/jmx-console/http://47.121.211.205:8080/jmx-console/ 3.然后找到jboss.deployment (jboss ⾃带得部署功能) 中的flavorURL,typeDeploymentScanner点进 …

比 Kimi 更强!用 Claude 仿写头条文章,轻松过原创(附完整指令)

最近&#xff0c;我有个做头条号的朋友跟我吐槽&#xff0c;说每天都要更新内容&#xff0c;经常写文章写到半夜&#xff0c;他已经快撑不住了。我听完实在有点不忍心&#xff0c;就告诉他&#xff0c;其实可以用 AI 来帮忙写头条文章。 朋友一脸怀疑&#xff0c;说“怎么可能&…

UML图之类图关系例题

答案&#xff1a;B C 知识点 依赖关系 一个事物发生变化影响另个一个事物 泛化关系 特殊/一般关系 关联关系 描述了一组链&#xff0c;链是对象之间的连接 实现关系 接口与类之间的关系