IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【嵌入式】关于IAP+Xmodem从外部接收bin文件对芯片进行升级学习记录 -> 正文阅读

[嵌入式]【嵌入式】关于IAP+Xmodem从外部接收bin文件对芯片进行升级学习记录

本文基于GD32F303CGT6芯片
使用软件:

  1. KEIL5
  2. Tera Term

什么是IAP

对于芯片的程序烧录,一共三种方式:

  • ICP
  • ISP
  • IAP

ICP(in-circuit-programmer在电路编程)

ICP就是在工厂生产产品时,先把芯片烧录好后再去贴片

ISP(in-system-programmer在系统编程)

ISP就是芯片先贴片后烧录代码,也就是我们最常用的利用J-Link、DAP进行烧录代码的方式

IAP(in-application-programmer在应用编程)

IAP最常应用于出厂芯片的外部升级,通过已有的bootloader引导系统将程序烧录到对应的存储块上

什么是Xmodem

对于Xmodem,百度百科上是这样说的:

XMODEM协议是一种使用拨号调制解调器的个人计算机通信中广泛使用的异步文件运输协议。这种协议以128字节块的形式传输数据,并且每个块都使用一个校验和过程来进行错误检测。

其实就是一种传输协议,对你要传输的文件进行分包,通过串口、SPI、I2C、USB、BLE(低功耗蓝牙协议)、WIFI等各种各样的方式进行传输文件。
经过多年的更新迭代,Xmodem衍生出了一下几种系列协议:

  • Xmodem-1k
  • Xmodem-CRC
  • Ymodem

Xmodem-1k

Xmodem-1k只是Xmodem的升级版,采用CRC校验,每个包的数据可达1k

Xmodem-CRC

Xmodem-CRC与普通Xmodem类似,采用CRC校验,每个包只有128字节

Ymodem

Ymodem与以上协议有一些区别,虽然都是Xmodem演变而来的,与Xmodem每一包都是文件的数据不同,Ymodem第一包发送的是文件名和文件大小,数据帧长度只有128字节,而它接下来的包有1k字节。(其余细小差别可百度)

Xmodem的帧格式

每个协议都会有各自定义帧格式的方式,Xmodem作为较早出现的数据传输协议(1978年),必然也有自己的一套帧格式

控制符

定义取值作用
SOH0x01128字节帧头标志
STX0x021k字节帧头标志
EOT0x04发送结束标志
ACK0x06应答标志
NCK0x15非应答标志
CAN0x18取消发送标志
CRC160x43CRC16校验帧

帧包格式(只说Xmodem)

BYTE1BYTE2BYTE3BYTE4-BYTE131BYTE132
SOH包序列~包序列数据checksum

传输流程

RECV SEND NCK 3S NCK |SOH|0x01|0xFE|DATA[0-127]|checksum| checksum is OK ACK |SOH|0x02|0xFD|DATA[0-127]|checksum| checksum is wrong NCK |SOH|0x02|0xFD|DATA[0-127]|checksum| checksum is OK ACK ... ... |EOT| ACK RECV SEND

以上为Xmodem传输流程,最开始的NCK为告知发送端接收端已经准备好,然后发送端开始按顺序发送数据,其中DATA[0-127]表示每一帧固定发送128字节数据,当剩余数据不够128字节时,一般用ctrlZ替代。 在发送过程中,如果某一帧数据传输错误,会导致checksum错误,这是接收端会发送NAK给发送端,发送接收到NAK后重新发送该帧数据。当所有数据发送完毕时,发送端发送一个EOT,接收端回复ACK表示整个发送过程技术。

GD32F30X的IAP使用方法

对于MCU,内部一般会有可擦除区域,这块区域可用于存储某些小块数据,亦或者可用于存储代码等,而IAP正是利用这块区域,或者说芯片的这一功能来对芯片内部代码进行修改的。
对于GD32F30X,其拥有一个叫做FMC(flash memory controller闪存控制器)的内部外设,该外设可对芯片内部flash进行擦写操作,参考芯片的用户手册以及数据手册之后可以对芯片的代码和数据分区,芯片擦写时间进行初步判断。
在这里插入图片描述
此图来源于GD32F30X用户手册,表明了GD32F30X各个系列内部flash的分区,对于IAP,我们主要操作的是图中的主存储闪存块
由图可知,主存储闪存块分为两部分,一部分是前256页,用户手册以及官方demo将其命名为bank0,另一部分为256-896页,用户手册以及官方demo将其命名为bank1
这两个bank的区别在于:

  1. 对于bank0,CPU指令操作零等待,此范围对于其他内存地址有操作延时小的优势
  2. bank0每一页的容量为2k,bank1每一页的容量为4k
  3. 对于主存储闪存块容量不大于512k的芯片,只有bank0

图中信息块为Boot loader区与我们自己写的bootloader不同,此为芯片内部引导芯片烧录方式以及执行方式的区域,芯片出厂时就已经定下来,用户不可擦写,可以理解为电脑的BIOS

芯片IAP方式

正如上文所述,芯片的IAP方式可通过串口、SPI、I2C、BLE、WIFI等各种各样的方式。我选用了最简单的串口+Xmodem的方式进行入门学习。

IAP流程

IAP的流程可以细分为很多中,在不管哪一种都离不开一个接收到数据后将数据写入芯片,并在写完之后将PC指针跳转到它该去的地方这个基本框架。
而为了芯片在烧录过程的安全性,避免因为一些非可抗力因素导致芯片升级失败后成为一块死芯片,这是在产品发布后,比如手机在用户手里进行系统升级时,决不可发生的事情。因此,为了保证升级过程绝对安全,一般会有各种各样的方式:

  1. 在芯片某一个闪存区写一个FLAG,当芯片开始升级时和升级成功后对FLAG进行相应的操作。
  2. 对芯片的烧录位置和bootloader代码进行严格的区分,保证他们井水不犯河水。

这里我两者都使用了,即在芯片需要进行升级时,先选择一块固定的闪存区,写一个FLAG进去,之后跳转到bootloader区,进行接收bin文件,在这个过程中即使中途因为断电停止接收了,芯片上电时,判断到FLAG区为正在升级时,也仍然会留在bootloader区重新开始升级。当芯片升级成功后,会跳转到APP区,并把FLAG擦除掉。这时即使重新上电,芯片也能成功跳转到APP区。

shut down and on
FLAG==UPGRADE
FLAG==UNPUGRADE
upgrade operation
recv
APP/bootloader
bootloader
APP
Tera Term

IAP时需要注意的点

  1. 对于Xmodem,在发送端发送数据前,一定要收到发送端的NAK,否则不会开始发送数据。
  2. 选定APP写入的地址,该地址应该是与bootloader井水不犯河水,所以我们在写完bootloader之后,需要计算bootloader一共占用芯片多少内存,之后APP生成bin文件前,要进行对应的地址偏移操作,以及FLASH-VTOR偏移(这个操作是告诉芯片应该去哪里找中断向量表,比如你把APP写在偏离主存储闪存区0x2000的地方,你的中断向量就应该偏移2000)。
  3. 第二点引申出最重要的这一点为,芯片在跳转时应该跳转到写入的地址+4,为什么要加4呢?这是因为写入的地址并非复位中断服务函数地址,而是中断向量表地址,我们在芯片复位时,PC指针应该是跳转到复位中断服务函数地址进行芯片复位,这样才能正常运行。

IAP学习过程中遇到的bug

  1. 在写芯片擦写过程的代码时,由于串口是以一个字节的形式发送数据的,而FMC在写数据的时候是以四个字节的形式写进去的,这个时候需要注意接收到的数据量与接收地址的数量关系,而我在写代码的时候,因为考虑到APP大代码量的情况,想到如果APP超过一页甚至超过bank1的时候怎么办?在判断数据时加了接收数据量这一判断操作,导致后续在判断是否超过一页时,使其跟写入地址混乱了。数据在写到四分之一的时候即跳到下一页开始擦写。
    这个情况也让我学习到,在不知道数据是否写入正确时,可以利用J-FLASH查看写入的数据

跳转代码

if(*(uint32_t *)UPGRADE_ADDR == UPGRADE_FLAG)
	{
		/* jump to APP */
		// 恢复指针
		if(((*(__IO uint32_t *)0x08002000) & 0x2FFE0000) == 0x20000000)  //判断跳转的地址是否为可用地址
		{
			LED_deinit(LED1);
			usart_disable(USART0);
			timer_disable(BASE_TIMER);  // 关闭升级时使用到的一些外设
			jUMP_ADDR = *(__IO uint32_t *)(0x08002000 + 4);  // +4为复位中断复位函数
			jump2App = (pfunction) jUMP_ADDR;
			__set_MSP(*(__IO uint32_t *)0x08002000);  // 设置栈顶指针
			// 清除flag
			fmc_sector_erase(0x082FF000);
			// jump to app
			nvic_vector_table_set(NVIC_VECTTAB_FLASH, 0x2000);  // 中断向量表偏移
			jump2App();
		}
		/***************/
	}
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-04-22 18:52:42  更:2022-04-22 18:54:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 4:24:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码