PIC在线升级源码分析

2019-04-15 11:51发布

1:概述

    最近两周都在做PIC在线升级的功能,最终看到升级成功的提示,难以掩盖成功的喜悦。决定把我两周中遇到的问题和大家分享一下,希望能给正在做升级功能的人一些帮助。有理解错误的地方请大家给以指正。

2:基本流程

    硬件连接:PC<=====>232转485<=====>PIC<=====>EEPROM     软件逻辑:                    1) MFC发送开始升级指令--->PIC初始化接收485BUF--->校验包--->写数据至EEPROM                    2) MFC发送文件结束指令--->PIC写升级文件标志至EEPROM--->Reset                    3) PIC读取EEPROM升级标志--->跳转至固定Program地址--->擦除原有program--->读取EEPROM--->写PIC Flash--->Reset      最终实现状态:在未断电重启的情况下,成功升级PIC程序,MFC程序检测升级成功。

3:错误包处理

     MFC端:当MFC应用程序读取ACK包,检查状态为错误会重传此序号包。错误重传延续5次。      PIC端  :当读取EEPROM数据写PIC Flash,会读取写入数据比对,如若出错将重新写入。

4:部分代码

PIC写升级文件部分代码: while (g_485_rec_buff.data_len < len) { ClrWdt(); Delay100TCYx(100); if(error++ > 30) return; } error = 0; check = CheckSum(ptr, len - 1); if(pdata->checksum != check) { pdata->pack.state = WRONG; g_485_rec_buff.data_len = 0; h_485_usart2_write_nbyte((char *)&pdata->pack, sizeof(UPPACK)); continue; } if(pdata->pack.state == END) { binfo.valid[0] = 'U'; binfo.valid[1] = 'P'; eeprom_write_page(EEPROM_UPDATE_INFO_ADDR, (unsigned char *)&binfo,sizeof(binfo)); break; } if(pdata->pack.state == SENDING) { eeprom_write_page(EEPROM_UPDATE_DATA_ADDR + binfo.file_size, pdata->data, pdata->pack.len); binfo.file_size += pdata->pack.len; pdata->pack.state = RIGHT; g_485_rec_buff.len = 0; h_485_usart2_write_nbyte((char *)&pdata->pack, sizeof(UPPACK)); continue; } MFC重传部分代码 while(TRUE) { memset((unsigned char *)&lpdata, 0, sizeof(UPDATA)); nRBytes = fread((char *)&lpdata.data, 1, BUFFSIZE, fp); if(nRBytes <= 0) break; lpdata.pack.len = nRBytes; lpdata.pack.seq = seq++; // package seq lpdata.pack.state = SENDING; RESEND: // if wrong will be send the same data until five times. lpdata.checksum = CheckSum((unsigned char *)&lpdata, sizeof(UPDATA) - 1); CleanSendBuf(scom.hCom); WriteBytes(scom.hCom, (char *)&lpdata, sizeof(UPDATA)); Sleep(300); memset((char *)&uppack, 0, sizeof(UPPACK)); if(ReadBytes(scom.hCom, (char *)&uppack, sizeof(UPPACK)) > 0) { if(uppack.state == WRONG) { if(ErrorNum++ <= 5) { goto RESEND; } else { ErrorNum = 0; Sleep(400); goto ERRORUP; } } ErrorNum = 0; if(uppack.state == RIGHT) { i += 64; m_progress_update.SetPos(i); continue; } goto RESEND; } else { goto ERRORUP; } } }

5:部分截图


6:遇到问题错误总结

     1) MPLAB 编译器中编写指针赋值时,出现485无法接收数据的现象。      2) MPLAB 编译器中如果传参为运算乘时,出现运算错误。      3) EEPROM 在写最大页128Bytes时,需要写128 * N的地址。否则出现写入数据不完全的现象。具体我也没有理解。      4) 在擦除PIC 时,注意计算其擦除块的大小,避免擦除固定升级代码。      5) 固定升级代码中一定不能调用固定升级代码区域之外的函数。以免擦除后再次调用程序跑飞的现象。      6) 在计算固定升级代码时,中间不能有间隔。MPLAB会把其他小代码量的函数烧写其中。最好从最大地址算起。