【开源】串⼝YMODEM 实现IAP 程序升级(附⼯程源码)
1、什么是IAP ?
IAP是In Application Programming的缩写,即在应⽤编程,IAP是⽤户⾃⼰的程序在运⾏过程中对User Flash的部分区域进⾏烧写,⽬的是为了在产品发布后可以⽅便地通过预留的通信⼝对产品中的固件程序进⾏更新升级。 可以通过串⼝、USB、⽹络、⽆线等⽅式进⾏升级数据的传输。
2、IAP 要点
(1)程序分两部分,BOOT和APP分别编写;
(2)flash空间划分(flash空间⾜够⼤的情况下,可以分成APP1和APP2进⾏备份升级)
本⽂Boot使⽤0x08000000-0x08003000空间,共12k存放Boot代码(可以根据Boot程序的⼤⼩,调整空间),剩下空间存放App代码。
(3)flash可编程(读、写、擦除),本⽂使⽤GD32f303,使⽤以下三个函数完成flash的编程操作。void  FlashWrite (uint16_t len ,uint8_t  *data ,uint32_t addr_start ){
uint16_t i ; uint16_t temp ;
fmc_state_enum  fmc_state =FMC_READY ;
fmc_unlock ();
fmc_flag_clear (FMC_FLAG_BANK0_END ); fmc_flag_clear (FMC_FLAG_BANK0_WPERR ); fmc_flag_clear (FMC_FLAG_BANK0_PGERR ); for (i =0;i <len /2;i ++)  {
fmc_state =fmc_halfword_program (addr_start , *(uint16_t *)data );
if (fmc_state !=FMC_READY )  {  return ;  }
fmc_flag_clear (FMC_FLAG_BANK0_END );  fmc_flag_clear (FMC_FLAG_BANK0_WPERR );  fmc_flag_clear (FMC_FLAG_BANK0_PGERR );
data += 2;  addr_start += 2;
12345678910111213141516171819202122232425262728
(4)从BOOT跳转到APP的时候需要,关闭中断,判断栈顶地址、设置栈指针。
addr_start += 2; }
if (len % 2) {
temp = *data | 0xff00;
fmc_state =fmc_halfword_program (addr_start ,temp ); }
fmc_lock ();}
void  FlashRead (uint16_t len ,uint8_t *outdata ,uint32_t addr_start ){
uint32_t addr ; uint16_t i ;
addr = addr_start ;
for (i =0;i <len ;i ++)  {
*outdata = *(uint8_t *) addr ;  addr = addr + 1;  outdata ++; }}
void  FlashErase (uint32_t start , uint32_t end ){
uint32_t EraseCounter ;
fmc_state_enum fmc_state =FMC_READY ; /* unlock the flash program/erase controller */    fmc_unlock ();
/* clear all pending flags */
fmc_flag_clear (FMC_FLAG_BANK0_END );    fmc_flag_clear (FMC_FLAG_BANK0_WPERR );    fmc_flag_clear (FMC_FLAG_BANK0_PGERR );
/* erase the flash pages */    while (start < end ) {
EraseCounter = start /FLASH_PAGE_SIZE ;
fmc_state =fmc_page_erase (EraseCounter *FLASH_PAGE_SIZE );  if (fmc_state !=FMC_READY ) 
{  return ;  }
fmc_flag_clear (FMC_FLAG_BANK0_END );        fmc_flag_clear (FMC_FLAG_BANK0_WPERR );        fmc_flag_clear (FMC_FLAG_BANK0_PGERR );
start += FLASH_PAGE_SIZE ;    }
/* lock the main FMC after the erase operation */    fmc_lock ();}
2829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
ApplicationAddress 为跳转后App的flash⾸地址,前⾯4字节存放的正是栈顶地址。⼀般arm cortex m内核的cpu,ram起始地址为
0x20000000,本⽂使⽤的GD32F303VC,ram为48k,范围为0x20000000-0x2000C000,所以要跳转到app之前先检查,确保栈顶地址在0x20000000-0x2000C000范围内。(5)APP程序编译设置
在编译器⾥⾯设置,App程序的flash起始地址,flash空间⼤⼩。(6)App程序设置(中断开和中断向量位置设置)
本⽂在Boot中没有关闭全局中断,所以不需要开全局中断。session和application的区别
3、YMODEM 协议
3.1、YMODEM 帧格式
Ymodem 有两种帧格式,主要区别是信息块长度不⼀样。
帧头包序号包序号 取反
信息块校验SOH/STX PN XPN DATA CRC 1byte
1byte
1byte
128/1024byte
2byte
3.1.1、帧头
帧头表⽰两种数据帧长度,主要是信息块长度不同。当帧头为SOH(0x01)时,信息块为128字节;当帧头为STX(0x02)时,信息块为1024字节。
if  (((*(__IO uint32_t *)ApplicationAddress ) & 0x2FF30000 ) == 0x20000000)  /*判断栈顶地址是否在合法范围内,*/ {
JumpAddress = *(__IO uint32_t *) (ApplicationAddress + 4);  /* Jump to user application */
Jump_To_Application = (pFunction ) JumpAddress ;    /* Initialize user application's Stack Pointer */
__set_MSP (*(__IO uint32_t *) ApplicationAddress );//设置栈指针  Jump_To_Application (); }
12345678910
nvic_vector_table_set (NVIC_VECTTAB_FLASH ,0x8003000); //设置向量表起始位置
1
3.1.2、包序号
数据包序号只有1字节,因此计算范围是0~255;对于数据包⼤于255的,序号归零重复计算。
3.1.3、帧长度
以SOH(0x01)开始的数据包,信息块是128字节,该类型帧总长度为133字节;
以STX(0x02)开始的数据包,信息块是1024字节,该类型帧总长度为1029字节。
3.1.4、校验
Ymodem采⽤的是CRC16校验算法,校验值为2字节,传输时CRC⾼⼋位在前,低⼋位在后;CRC计算数据为信息块数据,不包含帧头、包号、包号反码。
3.2、YMODEM起始帧
Ymodem起始帧并不直接传输⽂件内容,⽽是先将⽂件名和⽂件⼤⼩置于数据帧中传输;起始帧是以SOH 133字节长度帧传输,格式如下。
帧头包序号包序号 取反⽂件名称⽂件⼤⼩填充区校验SOH0x000xFF filename+0x00filesize+0x00n字节0x00CRC16
其中包号为固定为0;
filename为⽂件名称,⽂件名称后必须加0x00作为结束;
filesize为⽂件⼤⼩值,⽂件⼤⼩值后必须加0x00作为结束;
余下未满128字节数据区域,则以0x00填充。
可以看出起始帧也是遵守3.1中Ymodem包格式的。
3.3、YMODEM数据帧
Ymodem数据帧传输,在信息块填充有效数据。
传输有效数据时主要考虑的是最后⼀包数据的是处理,SOH帧和STR帧有不同的处理。
(1)对于SOH帧,若余下数据⼩于128字节,则以0x1A填充,该帧长度仍为133字节。
(2)对于STX帧需考虑⼏种情况:
余下数据等于1024字节,以1029长度帧发送;
余下数据⼩于1024字节,但⼤于128字节,以1029字节帧长度发送,⽆效数据以0x1A填充;
余下数据等于128字节,以133字节帧长度发送;
余下数据⼩于128字节,以133字节帧长度发送,⽆效数据以0x1A填充。
3.4、YMODEM结束帧
Ymodem的结束帧采⽤SOH 133字节长度帧传输,该帧不携带数据(空包),即数据区、校验都以0x00填充。
帧头包序号包序号 取反信息块校验
0x010x000xff128个0x000x00 0x00
3.5、YMODEM握⼿信号
握⼿信号由接收⽅发起,在发送⽅开始传输⽂件前,接收⽅需发送YMODEM_C (字符C,ASII码为0x43)命令,发送⽅收到后,开始传输起始帧。
3.6、YMODEM命令
命令命令码说明
SOH0x01128字节数据包
STX0x021024字节的数据包
命令命令码说明
EOT0x04结束传输
ACK0x06回应
NAK0x15没回应,需要重传当前数据包
CA0x18取消传输
C0x43握⼿
3.7、⼀个YMODEM 传输过程
可以看出YMODEM只有起始帧、数据帧、结束帧的帧长度是133或者1029长度的,除此以外都是⼀个字节,这也提⾼了YMODEM的传输效率。
4、YMODEM⼯具
有些⼯具是⽀持YMODEM传输的,⽐如SecureCRT等。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。