📄 boot.c
字号:
#endif
#ifdef USE_CONFIGWORD_PROTECT
}//end config protect
#endif
#ifdef USE_BOOT_PROTECT
}//end bootloader protect
#endif
#ifdef USE_RUNAWAY_PROTECT
writeKey1 += 4; // Modify keys to ensure proper program flow
writeKey2 -= 4;
#endif
//write to flash memory if complete row is finished
if((bytesWritten % PM_ROW_SIZE) == 0)
{
#ifdef USE_RUNAWAY_PROTECT
//setup program flow protection test keys
keyTest1 = (0x0009 | temp) - length + bytesWritten - 5;
keyTest2 = (((0x557F << 1) + WT_FLASH) - bytesWritten) + 6;
#endif
#ifdef USE_BOOT_PROTECT //Protect the bootloader & reset vector
if((sourceAddr.Val < BOOT_ADDR_LOW || sourceAddr.Val > BOOT_ADDR_HI)){
#endif
#ifdef USE_CONFIGWORD_PROTECT //do not erase last page
if(sourceAddr.Val < (CONFIG_START & 0xFFFC00)){
#endif
#ifdef USE_VECTOR_PROTECT //do not erase first page
if(sourceAddr.Val >= VECTOR_SECTION){
#endif
//execute write sequence
WriteMem(PM_ROW_WRITE);
#ifdef USE_RUNAWAY_PROTECT
writeKey1 += 5; // Modify keys to ensure proper program flow
writeKey2 -= 6;
#endif
#ifdef USE_VECTOR_PROTECT
}//end vectors protect
#endif
#ifdef USE_CONFIGWORD_PROTECT
}//end config protect
#endif
#ifdef USE_BOOT_PROTECT
}//end boot protect
#endif
}
sourceAddr.Val = sourceAddr.Val + 2; //increment addr by 2
}//end while((bytesWritten-5) < length*PM_ROW_SIZE)
}//end WritePM(WORD length, DWORD_VAL sourceAddr)
/********************************************************************
* Function: void ErasePM(WORD length, DWORD_VAL sourceAddr)
*
* PreCondition:
*
* Input: length - number of pages to erase
* sourceAddr - page aligned address to erase
*
* Output: None.
*
* Side Effects: None.
*
* Overview: Erases number of pages from flash memory
*
* Note: None
********************************************************************/
void ErasePM(WORD length, DWORD_VAL sourceAddr)
{
WORD i=0;
#ifdef USE_RUNAWAY_PROTECT
WORD temp = (WORD)sourceAddr.Val;
#endif
while(i<length){
i++;
#ifdef USE_RUNAWAY_PROTECT
writeKey1++; // Modify keys to ensure proper program flow
writeKey2--;
#endif
//if protection enabled, protect BL and reset vector
#ifdef USE_BOOT_PROTECT
if(sourceAddr.Val < BOOT_ADDR_LOW || //do not erase bootloader
sourceAddr.Val > BOOT_ADDR_HI){
#endif
#ifdef USE_CONFIGWORD_PROTECT //do not erase last page
if(sourceAddr.Val < (CONFIG_START & 0xFFFC00)){
#endif
#ifdef USE_VECTOR_PROTECT //do not erase first page
if(sourceAddr.Val >= VECTOR_SECTION){
#endif
#ifdef USE_RUNAWAY_PROTECT
//setup program flow protection test keys
keyTest1 = (0x0009 | temp) + length + i + 7;
keyTest2 = (0x557F << 1) - ER_FLASH - i + 3;
#endif
//perform erase
Erase(sourceAddr.word.HW, sourceAddr.word.LW, PM_PAGE_ERASE);
#ifdef USE_RUNAWAY_PROTECT
writeKey1 -= 7; // Modify keys to ensure proper program flow
writeKey2 -= 3;
#endif
#ifdef USE_VECTOR_PROTECT
}//end vectors protect
#elif defined(USE_BOOT_PROTECT) || defined(USE_RESET_SAVE)
//Replace the bootloader reset vector
DWORD_VAL blResetAddr;
if(sourceAddr.Val < PM_PAGE_SIZE/2){
//Replace BL reset vector at 0x00 and 0x02 if erased
blResetAddr.Val = 0;
#ifdef USE_RUNAWAY_PROTECT
//setup program flow protection test keys
keyTest1 = (0x0009 | temp) + length + i;
keyTest2 = (0x557F << 1) - ER_FLASH - i;
#endif
replaceBLReset(blResetAddr);
}
#endif
#ifdef USE_CONFIGWORD_PROTECT
}//end config protect
#endif
#ifdef USE_BOOT_PROTECT
}//end bootloader protect
#endif
sourceAddr.Val += PM_PAGE_SIZE/2; //increment by a page
}//end while(i<length)
}//end ErasePM
/********************************************************************
* Function: void WriteTimeout()
*
* PreCondition: The programmed data should be verified prior to calling
* this funtion.
*
* Input: None.
*
* Output: None.
*
* Side Effects: None.
*
* Overview: This function writes the stored value of the bootloader
* timeout delay to memory. This function should only
* be called after sucessful verification of the programmed
* data to prevent possible bootloader lockout
*
* Note: None
********************************************************************/
void WriteTimeout()
{
#ifdef USE_RUNAWAY_PROTECT
WORD temp = (WORD)sourceAddr.Val;
#endif
//Write timeout value to memory
#ifdef DEV_HAS_WORD_WRITE
//write data into latches
WriteLatch((DELAY_TIME_ADDR & 0xFF0000)>>16,
(DELAY_TIME_ADDR & 0x00FFFF),
userTimeout.word.HW, userTimeout.word.LW);
#else
DWORD_VAL address;
WORD bytesWritten;
bytesWritten = 0;
address.Val = DELAY_TIME_ADDR & (0x1000000 - PM_ROW_SIZE/2);
//Program booloader entry delay to finalize bootloading
//Load 0xFFFFFF into all other words in row to prevent corruption
while(bytesWritten < PM_ROW_SIZE){
if(address.Val == DELAY_TIME_ADDR){
WriteLatch(address.word.HW, address.word.LW,
userTimeout.word.HW,userTimeout.word.LW);
}else{
WriteLatch(address.word.HW, address.word.LW,
0xFFFF,0xFFFF);
}
address.Val += 2;
bytesWritten +=4;
}
#endif
#ifdef USE_RUNAWAY_PROTECT
//setup program flow protection test keys
keyTest1 = (0x0009 | temp) - 1 - 5;
keyTest2 = ((0x557F << 1) + VERIFY_OK) + 6;
#endif
//Perform write to enable BL timeout
#ifdef DEV_HAS_WORD_WRITE
//execute write sequence
WriteMem(PM_WORD_WRITE);
#else
//execute write sequence
WriteMem(PM_ROW_WRITE);
#endif
#ifdef USE_RUNAWAY_PROTECT
writeKey1 += 5; // Modify keys to ensure proper program flow
writeKey2 -= 6;
#endif
}//end WriteTimeout
/*********************************************************************
* Function: void AutoBaud()
*
* PreCondition: UART Setup
*
* Input: None.
*
* Output: None.
*
* Side Effects: Resets WDT.
*
* Overview: Sets autobaud mode and waits for completion.
*
* Note: Contains code to handle UART errata issues for
PIC24FJ128 family parts, A2 and A3 revs.
********************************************************************/
void AutoBaud()
{
BYTE dummy;
UxMODEbits.ABAUD = 1; //set autobaud mode
while(UxMODEbits.ABAUD) //wait for sync character 0x55
{
asm("clrwdt"); //looping code so clear WDT
//if timer expired, jump to user code
if(IFS0bits.T3IF == 1){
ResetDevice(userReset.Val);
}
if(U1STAbits.OERR) UxSTAbits.OERR = 0;
if(U1STAbits.URXDA) dummy = UxRXREG;
}
//Workarounds for autobaud errata in some silicon revisions
#ifdef USE_WORKAROUNDS
//Workaround for autobaud innaccuracy
if(U1BRG == 0xD) U1BRG--;
if(U1BRG == 0x1A) U1BRG--;
if(U1BRG == 0x09) U1BRG--;
#ifdef USE_HI_SPEED_BRG
//Workarounds for ABAUD incompatability w/ BRGH = 1
UxBRG = (UxBRG+1)*4 -1;
if(U1BRG == 0x13) U1BRG=0x11;
if(U1BRG == 0x1B) U1BRG=0x19;
if(U1BRG == 0x08) U1BRG=0x22;
//Workaround for Odd BRG recieve error when BRGH = 1
if (U1BRG & 0x0001) U1BRG++;
#endif
#endif
}//end AutoBaud()
#if defined(USE_BOOT_PROTECT) || defined(USE_RESET_SAVE)
/*********************************************************************
* Function: void replaceBLReset(DWORD_VAL sourceAddr)
*
* PreCondition: None.
*
* Input: sourceAddr - the address to begin writing reset vector
*
* Output: None.
*
* Side Effects: None.
*
* Overview: Writes bootloader reset vector to input memory location
*
* Note: None.
********************************************************************/
void replaceBLReset(DWORD_VAL sourceAddr)
{
DWORD_VAL data;
#ifndef DEV_HAS_WORD_WRITE
WORD i;
#endif
#ifdef USE_RUNAWAY_PROTECT
WORD tempkey1;
WORD tempkey2;
tempkey1 = keyTest1;
tempkey2 = keyTest2;
#endif
//get BL reset vector low word and write
data.Val = 0x040000 + (0xFFFF & BOOT_ADDR_LOW);
WriteLatch(sourceAddr.word.HW, sourceAddr.word.LW, data.word.HW, data.word.LW);
//Write low word back to memory on word write capable devices
#ifdef DEV_HAS_WORD_WRITE
#ifdef USE_RUNAWAY_PROTECT
writeKey1 += 5; // Modify keys to ensure proper program flow
writeKey2 -= 6;
#endif
//perform BL reset vector word write bypassing flow protect
WriteMem(PM_WORD_WRITE);
#endif
//get BL reset vector high byte and write
data.Val = ((DWORD)(BOOT_ADDR_LOW & 0xFF0000))>>16;
WriteLatch(sourceAddr.word.HW,sourceAddr.word.LW+2,data.word.HW,data.word.LW);
#ifdef USE_RUNAWAY_PROTECT
keyTest1 = tempkey1;
keyTest2 = tempkey2;
#endif
//Write high byte back to memory on word write capable devices
#ifdef DEV_HAS_WORD_WRITE
#ifdef USE_RUNAWAY_PROTECT
writeKey1 += 5; // Modify keys to ensure proper program flow
writeKey2 -= 6;
#endif
//perform BL reset vector word write
WriteMem(PM_WORD_WRITE);
//Otherwise initialize row of memory to F's and write row containing reset
#else
for(i = 4; i < (PM_ROW_SIZE/PM_INSTR_SIZE*2); i+=2){
WriteLatch(sourceAddr.word.HW,sourceAddr.word.LW+i,0xFFFF,0xFFFF);
}
#ifdef USE_RUNAWAY_PROTECT
writeKey1 += 5; // Modify keys to ensure proper program flow
writeKey2 -= 6;
#endif
//perform BL reset vector word write
WriteMem(PM_ROW_WRITE);
#endif
}//end replaceBLReset()
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -