PIC在线升级源码分析

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会把其他小代码量的函数烧写其中。最好从最大地址算起。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值