GD32E230C8T6_OTA升级

GD32E230C8T6_OTA升级

  • 运行环境
    • 简介
    • 程序的起始地址
    • 进行分区
    • 总体流程图
    • Bootloader 程序
    • Bootloader 编译设置
    • APP 分区部分
    • APP 编译设置
    • 重点步骤

运行环境

1.Windows10
2. Keil5(MDK5) Version 5.27.0.0
3. MCU GD32E230C8T6

简介

本例程主要分析在线升级(OTA)的实现过程, 主要是针对IAP OTA从原理分析, 分区划分, 到代码编写和实验验证等过程阐述这一过程. 和大家以前理解OTA的原理.
作者也是通过已有的网上DEMO来理解编写,所以只是提供个人的理解思路。有需要优化的地方望大家指教。

程序的起始地址

正常情况下, 我们写的程序都是放在GD32片内Flash中(暂不考虑外扩Flash). 我们写的代码最终会变成二进制文件, 放进Flash中 。起始地址在0x08000000。

进行分区

64KBFlash MCU分区方案
Flash 空间划分出 4 个区域:Bootloader、FLAG、APP 分区、APPBAK 分区。
在这里插入图片描述

总体流程图

参考此流程图(可更具实际情况自己更改)
先执行BootLoader程序, 先去检查FLAG区有没有升级标志, 如果有就将APPBAK区(备份区)的程序拷贝到APP区, 然后再跳转去执行APP的程序.
然后执行APP程序, 因为BootLoader和APP这两个程序的向量表不一样, 所以跳转到APP之后第一步是先去更改程序的向量表. 然后再去执行其他的应用程序.
在应用程序里面会加入程序升级的部分, 这部分主要工作是拿到升级程序, 然后将他们放到APPBAK区(备份区), 以便下次启动的时候通过BootLoader更新APP的程序. 流程图如下图所示:
https://gitee.com/leafguo此图出自https://gitee.com/leafguo

Bootloader 程序

Bootloader 的主要职能是在有升级任务的时候将 APPBAK 分区里面的固件拷贝到 APP 区域。当然,这期间需要做很多的工作,比如升级失败的容错等等。具体的流程可以参考图示。需要注意的是,在校验 MD5 正确后开始搬运固件数据期间,MCU 出现故障(包括突然断电),MCU 应发生复位操作(FLAG 区域数据未破坏),复位后重新开始执行 Bootloader,从而避免 MCU 刷成板砖。(可以根据难度进行裁剪)
在这里插入图片描述

  • /* 程序跳转函数 */
void execute_user_code(void)
{uint32_t JumpAddress;JumpAddress = *(__IO uint32_t*) (APP_CODE_OFFSET+ 4);usart_disable(USART0);__set_MSP(*(__IO uint32_t*) APP_CODE_OFFSET);(*( void (*)( ) )JumpAddress) ();
}

在需要跳转的地方执行这个函数就可以了execute_user_code();

  • 所需要的宏定义
#define BOOTLOADER  					(0x08000000)   // 11KB  //BootLoader起始地址  #define UPDATE_FLAG     			(0x08002C00) 	  //升级标志地址 
#define UPDATE_FLAG_MAX_SIZE	(0x0400)			// 1KB#define APP_CODE_OFFSET 			(0x08003000)   	//APP起始地址 
#define APP_CODE_SIZE   			(0x6800)      // 26KB            #define UPDATE_CODE_OFFSET 		(0x08009800)   //APPBAK区(备份区)起始地址
#define UPDATE_CODE_SIZE   		(0x6800)      // 26KB  #define FLASH_SECTOR_SIZE 	 	(0x400)   		// 1KB

Bootloader 编译设置

BootLoader的代码默认是最开始的所以不需要特别设置代码的下载位置
按照下图, 修改擦除方式为Erase Sectors, 大小限制在0X2C00(11KB)
在这里插入图片描述
在这里插入图片描述

APP 分区部分

做好 Bootloader 工作后,我们开始写 APP 分区的代码。APP 分区固件的编写要注意硬件版本号和软件版本号,软件版号作为升级迭代很重要的标志。APP 分区代码我们只需要增加从网络接口接收到新固件到APPBAK区(备份区)功能,并给更新标志区写入相应数据。需要注意的是,中断向量地址偏移的定义,我们 APP 分区实际的偏移是 0x3000。如果不修改,APP 分区也可以正常加载运行,但是不会相应中断。所以,我们需要根据实际 APP 分区下载的起始地址,对中断向量地址偏移做定义。按照协议规定,具体如下:
在这里插入图片描述

  1. 修改中断向量表
nvic_vector_table_set (BOOTLOADER,0x3000);

APP 编译设置

因为硬件 FLASH 空间限定,我们需要对 APP 分区的固件大小做严格的限制。本例程可允许的最大固件为 26KB。需要升级的新固件同样最大可支持 26KB。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

重点步骤

  1. 程序的跳转
  2. APP中的修改中断向量表
  3. Flash内存的操作(重点)
int main(void)
{systick_config();usart_gpio();usart_init();uint32_t temp;while(1){printf("current version:"BOOTLOAD_VERSION"\n");//读取升级标志temp=option_byte_value_get(UPDATE_FLAG);//判断升级标志并把APPBAK区固件拷贝到APP区if(43690 == temp){printf("Enter the firmware upgrade process\n");copy_updata();//先Flash解锁 清除标志 再擦除 进行拷贝//完成拷贝后清除标志上锁 fmc_unlock();fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR);fmc_page_erase(UPDATE_FLAG);fmc_lock();usart_disable(USART0); //程序跳转前失能中断execute_user_code();}else{printf("Firmware upgrade failed, jump to app\n");execute_user_code();}}
}

中间的Flash操作各MCU大体相同 故参考相关例程
此文章仅个人的思路及理解,如有需要优化的地方大家提出,共同优化。
更新代码参考

#include "gd32e23x.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFF_SIZE 1024
uint32_t flash_address = 0x08002000;   // Flash起始地址
uint8_t recv_buff[BUFF_SIZE];          // 接收缓冲区
uint32_t recv_len = 0;                 // 已接收数据长度
uint32_t recv_total_len = 0;           // 接收数据总长度
uint16_t crc = 0;                      // 接收数据的校验和
uint32_t timeout = 0;                  // 超时计数器
// USART初始化函数
void usart_init(void)
{rcu_periph_clock_enable(RCU_USART0);                 // 使能USART0时钟rcu_periph_clock_enable(RCU_GPIOA);                  // 使能GPIOA时钟gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);    // PA9作为USART0_TX引脚输出gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);   // PA10作为USART0_RX引脚输入usart_deinit(USART0);               // 复位USART0usart_baudrate_set(USART0, 115200); // 设置波特率为115200usart_word_length_set(USART0, USART_WL_8BIT);       // 设置数据位为8位usart_stop_bit_set(USART0, USART_STB_1BIT);         // 设置停止位为1位usart_parity_config(USART0, USART_PM_NONE);         // 设置无奇偶校验usart_receive_config(USART0, USART_RECEIVE_ENABLE); // 使能接收usart_enable(USART0);               // 使能USART0
}
// USART发送数据函数
void usart_send_data(uint8_t *data, uint32_t len)
{uint32_t i;for (i = 0; i < len; i++) {usart_data_transmit(USART0, data[i]);  // 发送数据while (usart_flag_get(USART0, USART_FLAG_TBE) == RESET); // 等待发送完成}
}
// 接收数据回调函数
void usart_receive_data(uint8_t ch)
{static uint8_t prev_ch = 0;static uint8_t state = 0;switch (state) {case 0:if (ch == 0x7E && prev_ch == 0x7E) {state = 1;crc = 0xFFFF;recv_len = 0;recv_total_len = 0;timeout = 0;}break;case 1:if (ch == 0x7E) {state = 2;} else {recv_buff[recv_len++] = ch;recv_total_len++;crc = crc16_update(crc, ch);}break;case 2:if (ch == 0x7E) {state = 1;if (crc == 0) {// 接收到一帧完整的OTA数据包flash_write_data(flash_address, recv_buff, recv_len); // 将数据写入Flashflash_address += recv_len;usart_send_data("OK", 2); // 发送确认回复} else {usart_send_data("ERR", 3); // 发送错误回复}} else {state = 0;}break;}prev_ch = ch;
}
int main(void)
{usart_init(); // 初始化USARTwhile (1) {if (recv_total_len == 0) {timeout++;if (timeout > 1000000) {    // 超时处理timeout = 0;state = 0;}} else {timeout = 0;}}return 0;
}

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

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

相关文章

个人配置电脑清单 (windows+黑苹果)

自配第一套,3A游戏入门套 AMD锐龙 R5 3500X盒装微星B450 迫击炮 Max主板套装 1218元 酷兽DDR4 8G 3200MHz内存条 2条 301元 耕升1660 super 6g 炫光 1487元 爱国者极光风扇 4个 110元 航嘉 金牌500W WD500K电源 265元 先马&#xff08;SAMA&#xff09;鲁班1 机箱 179元 …

耕升 GeForce RTX 4070 星极皓月 OC给玩家带来DLSS3+2K光追百帧游戏体验

在2023年4月12日晚上21:00,耕升 GeForce RTX 4070 系列全系显卡正式解禁。作为NVIDIA 核心AIC合作伙伴之一的耕升&#xff0c;也紧跟步伐推出全新耕升 GeForce RTX 4070 星极皓月 OC 和 耕升 GeForce RTX 4070 星极幻姬 OC。其建议零售价为人民币5199元。耕升 GeForce RTX 4070…

耕升 GeForce RTX 4060 Ti 系列,为玩家带来DLSS3+1080P光追游戏体验!

NVIDIA 于2023年5月18日&#xff0c;正式发布GeForce RTX 4060 Ti系列&#xff0c;作为核心AIC厂商的一员&#xff0c;耕升此次也为玩家带来了多款耕升 GeForce RTX 40系列全新家族成员。其中囊括耕升 GeForce RTX 4060 Ti 追风 EX3和耕升 GeForce RTX 4060 Ti 追风&#xff0c…

shell脚本耕升(一)

文章目录 文件描述符自定义文件描述符数组和关联数组定义关联数组 别名获取终端信息获取&#xff0c;设置日期与延时延时 调试脚本函数与参数递归函数导出函数 读取命令序列输出不按回车键的方式读取字符“n”字段分隔符与迭代器for循环命令使用cat 查看script&#xff0c;scri…

高精度地图定位在高速公路自动驾驶系统中的应用

近年来随着汽车保有量不断增加&#xff0c;随之而来的是: ( 1) 严重的交通拥堵&#xff0c;通行效率低下&#xff0c;用在通行上的时间不断增加; ( 2) 交通事故频发&#xff0c;交通事故导致的伤亡人数和费用不断增加&#xff0c;而且绝大多数事故是由人为因素导致的; ( 3) 大气…

Kubernetes对象深入学习之五:TypeMeta无效之谜

欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码)&#xff1a;https://github.com/zq2599/blog_demos 本篇概览 本文是《Kubernetes对象深入学习之五》系列的第五篇&#xff0c;从前文的分析也能看出&#xff0c;代表对象类型的schema.ObjectKind&#xff0c;于…

WindowBuilder的安装

偶然间发现利用Eclipse原来也可以通过Java Swing像VB一样以拖拽的形式布局控件。 那就是在Eclipse中安装Window Builder插件。 1、在Eclipse中Help——Install New Software——在Work with中输入WindowBuilder的链接 WindowBuilder的链接&#xff1a;WindowBuilder | Downlo…

android获取当前windows,Android 中的 Window

一台 Android 手机屏幕上显示的内容就是由一个个 Window 组合而成的。顶部的状态栏是一个 Window,底部的导航栏也是一个 Window,中间自己的应用显示区域也是一块大 Window,Toast、Dialog 也都对应一个自己的 Window。而 Android 中对这些 Window 的管理是通过 一个框架的服务…

Flink Window机制详解

Flink 认为 Batch 是 Streaming 的一个特例&#xff0c;所以 Flink 底层引擎是一个流式引擎&#xff0c;在上面实现了流处理和批处理。而窗口&#xff08;window&#xff09;就是从 Streaming 到 Batch 的一个桥梁。Flink 提供了非常完善的窗口机制&#xff0c;这是我认为的 Fl…

window7下利用DockerToolbox安装Docker

这几天终于放假&#xff0c;有空在家深造下后端的知识。在通过某位大神的博客中深入学习redis时&#xff0c;知道了redis在window中的版本其实是阉割版&#xff08;既非官方版&#xff09;的&#xff0c;也就意味着很多功能没有&#xff0c;这对于以后的开发中可能造成隐患。当…

Window.innerHeight

Window.innerHeight 接口的只读innerHeight属性 Window返回窗口的内部高度&#xff08;以像素为单位&#xff09;&#xff0c;包括水平滚动条的高度&#xff08;如果存在&#xff09;。值innerHeight取自窗口 布局视口的高度。可以使用该 innerWidth属性获得宽度。一个整数值&a…

window7 正式中文零售版(10.22版) 32位已提供下载,64位待更新

window7ULTIMATE 正式中文零售版&#xff08;10.22版&#xff09; 32&#xff08;上传时间&#xff1a;2009-10-21 04:18:54&#xff09; fs2you://Y2FjaGVmaWxlMzQucmF5ZmlsZS5jb20vemgtY24vZG93bmxvYWQvM2JlNzVkZjUzZTBjZmIzOTA1YWYwYjRmNDQ3MWM5ZjMvY25fd2luZG93c183X3VsdGl…

计算机Windows7③

一、操作系统 1.1操作系统的概念 操作系统可以控制和管理计算机的硬件和软件资源、控制程序执行、改善人机界面、合理组织计算机工作流程并为用户提供计算机运行环境的系统软件。 操作系统是人机接口&#xff0c;如果没有操作系统&#xff0c;则不能使用计算机&#xff0c;是裸…

STM32 Cubemx 同名外设中断及回调

文章目录 前言示例工程个人理解 前言 最近在学习STM32&#xff0c;采用HAL库开发方式。记录一下同名外设中断及回调。 这里提及的同名外设指USART1/2之类的相同外设&#xff0c;但不是同一个instance。 示例工程 以使用cubemx配置两个同名外设EXTI0/EXT4为例。 在NVIC配置…

Java语言程序设计 例题5.4(英里和公里的转化)

5.4 (Conversion from miles to kilometers) Write a program that displays the following table (note that 1 mile is 1.609 kilometers): Miles Kilometers 1 1.609 2 3.218 ... 9 14.481 10 16.090 5.4&#xff08;英里和公里的转化&#xff09;写一个程序显示下表&#x…

图片换脸-->>视频换脸-->>直播换脸

资源网站&#xff1a;https://tianfeng.space/ 个人娱乐&#xff0c;切勿作恶 下载 ​ 网盘&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1DHMY1mCXpT0OtpmlvIoMKA 提取码&#xff1a;nf57 使用 下载解压后&#xff0c;打开 第一个就是你要替换的人脸&#xff0c;…

跟我学Springboot开发后端管理系统1:概述

前言 Matrxi-Web是一个前后端分离的管理系统&#xff0c;前端采用vue开发框架&#xff0c;后端使用springboot开发框架&#xff0c;具体快速开发、简单可复用的特点。只要把整体框架搭建起来了&#xff0c;后面就只用写CRUD了。 Matrxi-Web具备基本的管理系统的基本功能&…

跟我学SpringBoot之配置常见用法

只需低头努力&#xff0c;剩下的交给时光&#xff0c;时间会公平地帮你处理一切 配置基本用法 application.yml book:name: "Java"Value注解可以直接取配置的值 RestController EnableAutoConfiguration public class ConfigurationDemo {Value("${book.name…

《图解HTTP》——上野 宣

图解HTTP 看完这本书并在此博客下摘录书中的部分知识以便回顾。 第一章 了解Web及网络基础 1.1 使用HTTP协议访问Web Web使用一种名为HTTP(HyperText Transfer Protocol&#xff0c;超文本传输协议)的协议作为规范&#xff0c;完成从客户端到服务器端等一系列运作流程。而协…

山西电力市场日前价格预测【2023-08-28】

日前价格预测 预测明日&#xff08;2023-08-28&#xff09;山西电力市场全天平均日前电价为319.70元/MWh。其中&#xff0c;最高日前电价为371.80元/MWh&#xff0c;预计出现在19: 15。最低日前电价为278.59元/MWh&#xff0c;预计出现在13: 00。 价差方向预测 1&#xff1a; …