大家好!
现在有个问题要请教下大家。
是这样的,我现在在做一个使用RS485进行在线升级固件的程序,使用的是PIC18F45K80系列单片机,由于存储容量有限,外扩了存储器MX25L1606E系列,现在下载程序和更新升级都可以正常执行了,就是我在发送软件复位指令时,单片机每次收到复位指令都复位了两次。
举个例子:当单片机接收完升级数据包时,我将单片机的ROM最后一字节改为除0x55以外的任何值,并发送软件复位指令,具体代码如下(是参考PIC官方提供的代码):
TBLPTR = END_FLASH - 1;
EECON1 = 0x84;
TABLAT = APPLICATION_INVALID;//0x56
asm("TBLWT *");
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1;
NOP();
NOP();
//BOOTLOADER_INDICATOR = BL_INDICATOR_OFF;
RESET();
此时单片机会重启,并用下列检测函数来检测ROM的最后一个字节是否为0x55,如果不是则进入升级处理函数,由于我在之前设置了ROM的最后一个字节为非0x55的值,因此Bootload_Required函数会返回true,进入升级程序,这是对的。
// *****************************************************************************
bool Bootload_Required ()
{
// ******************************************************************
// Check a variable in flash to initiate bootloader
// ******************************************************************
// This section reads the last location in
// memory to see if the location is 0x55.
// if it's 0x55, it runs the application.
// Any other value runs the bootloader.
TBLPTR = END_FLASH - 1;
/*
* bit 7 EEPGD: Flash Program or Data EEPROM Memory Select bit
1 = Accesses Flash program memory
0 = Accesses data EEPROM memory
*/
EECON1 = 0x80;
asm("TBLRD *+");//Flash读操作
/*
* TBLPTR points to a byte address in program space.
Executing TBLRD places the byte pointed to into TABLAT
*/
if (((uint16_t)TABLAT) != APPLICATION_VALID)//最后一个字节不是0x55则进行升级
{
return (true);
}
return (false);
}
在升级程序完成后(这里内容较多,我就省略了,总之能正常升级),我又执行以下代码,也就是将ROM最后一个字节改为0x55,并且发送软件复位指令,期望直接执行新程序,代码如下所示:
TBLPTR = END_FLASH - 1;
EECON1 = 0x84;
TABLAT = APPLICATION_VALID;//0x55升级成功标志
asm("TBLWT *");
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1;
NOP();
NOP();
BOOTLOADER_INDICATOR = BL_INDICATOR_OFF;
RESET();
此时如果再复位Bootload_Required应该返回false,直接执行新程序才对,然而又重新执行了一遍升级程序,那应该就是Bootload_Required这个函数返回了true,不知道是什么原因,如果是关电后再重新开机则不会出现这个现象,大家能帮忙分析下是大概是什么原因吗?在此先谢谢大家了!是不是软件复位复位和硬件复位不同造成的。