我的工程中,期望将LM3s5791的FLASH分为4部分:0~0x0FFF为Bootloader;0x1000~0x8FFF为App代码;0x9000~0x10FFF存放Update时的代码;0x11000~0x20000为备份的代码。在Bootloader中,如果检测到上一次的复位是由于按了RESET键触发的(即RSTn 管脚置低),则将备份区的代码(0x11000~)拷贝到App代码部分,之后再运行更新后的App;在Bootloader中,如果检测到上一次的复位是由软件触发的,则将Update部分的代码拷至App部分,之后再运行更新后的App,否则直接运行App。
我遇到的问题是,虽然进行了按键重启,但是重启后复位寄存器RESC的Bit0并没有置位。故而,程序没能实现按Reset键后运行备份区的代码。但是,如果在应用部分使用了软件复位函数SysCtlReset();,则复位后Bootloader时会进入CheckSWReset()的分支。复位检测的代码以及Bootloader时的代码如下所示:
/******************************************************************************
* Function name : unsigned long CheckSWReset(void)
* Description : judge if last reset source is a software reset.
* Returns : 1 or 0.
* Inputs : None.
******************************************************************************/
unsigned long
CheckSWReset(void)
{
unsigned long int reset_source = 0;
reset_source = HWREG(SYSCTL_RESC);
//according to RESC reg bit0~5 and bit 16 are available.
HWREG(SYSCTL_RESC) &= ~0x0001003F;
if ((reset_source & SYSCTL_RESC_SW) && !(reset_source & (SYSCTL_RESC_POR | SYSCTL_RESC_EXT)))
{
if (reset_flag != 0x43215678)
{
reset_flag = 0;
return 1;
}
}
return 0;
}//CheckSWReset
/******************************************************************************
* Function name : unsigned long CheckButtonReset(void)
* Description : judge if last reset source is a button action.
* Returns : 1 or 0.
* Inputs : None.
******************************************************************************/
unsigned long
CheckButtonReset(void)
{
unsigned long int reset_source;
reset_source = HWREG(SYSCTL_RESC);
//clear all Reset source.
HWREG(SYSCTL_RESC) &= ~0x0001003F;
if ((reset_source & SYSCTL_RESC_EXT))
{
if (reset_flag != 0x43215678)
{
reset_flag = 0;
return (1);
}
else return 0;
}
else return (0);
}
bootloader时运行的代码如下所示:
if(CheckSWReset())
{
//LED indication
GPIOPinWrite(GPIO_PORTG_BASE,0xf0, 0xf0);
// run application
reset_flag = 0;
SysCtlDelay(8000000);
//LED indication
GPIOPinWrite(GPIO_PORTG_BASE,0xf0, 0x00);
CallApplication();
}
else if(CheckButtonReset()||CheckForceUpdate())
{
if(CheckButtonReset())
{
//LED indication
GPIOPinWrite(GPIO_PORTG_BASE,0x30, 0x30);
}
else
{
//LED indication
GPIOPinWrite(GPIO_PORTG_BASE,0xA0, 0xA0);
}
//Erase the application flash. start from APP_START_ADDRESS to 0x64FF.
for(ulTemp = APP_START_ADDRESS; ulTemp < UPD_START_ADDRESS;
ulTemp += FLASH_PAGE_SIZE)
{
//Erase the application
BL_FLASH_ERASE_FN_HOOK(ulTemp);
}
for(ulFlashAddr = BACKUP_START_ADDRESS,ulTemp = APP_START_ADDRESS ;
ulFlashAddr < 0x20000;ulTemp += 4)
{
puldata = (unsigned char *)ulFlashAddr;
BLInternalFlashProgram(ulTemp,puldata,4);
ulFlashAddr += 4;
}
// run application
//LED indication
GPIOPinWrite(GPIO_PORTG_BASE,0xF0, 0x00);
reset_flag = 0;
CallApplication();
}
else
{
GPIOPinWrite(GPIO_PORTG_BASE,0xF0, 0x00);
// run application
reset_flag = 0;
CallApplication();
// ((void (*)(void))0x1001)();
}