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会把其他小代码量的函数烧写其中。最好从最大地址算起。
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮