/******************************************************************** * Function: main() * * Precondition: * * Input: None. * * Output: None. * * Side Effects: None. * * Overview: Main entry function. If there is a trigger or * if there is no valid application, the device * stays in firmware upgrade mode. * * * Note: None. ********************************************************************/ INT main(void) { UINT pbClk; UINT bSoftResetFlag = 0; // Setup configuration pbClk = SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE); InitLED(); TRISBbits.TRISB15 = 1;//test bSoftResetFlag = *(unsigned int *)(NVM_DATA); if(bSoftResetFlag == 1) { NVMErasePage((void*)NVM_DATA); NVMWriteWord((void*)(NVM_DATA), (unsigned int)0x00); } // Enter firmware upgrade mode if there is a trigger or if the application is not valid if(bSoftResetFlag == 1 || CheckTrigger() || !ValidAppPresent()) { // Initialize the transport layer - UART/USB/Ethernet TRANS_LAYER_Init(pbClk); while(!FRAMEWORK_ExitFirmwareUpgradeMode()) // Be in loop till framework recieves "run application" command from PC { // Enter firmware upgrade mode. // Be in loop, looking for commands from PC TRANS_LAYER_Task(); // Run Transport layer tasks FRAMEWORK_FrameWorkTask(); // Run frame work related tasks (Handling Rx frame, process frame and so on) // Blink LED (Indicates the user that bootloader is running). BlinkLED(); } // Close trasnport layer. TRANS_LAYER_Close(); } // No trigger + valid application = run application. JumpToApp(); return 0; }
/******************************************************************** * Function: main() * * Precondition: * * Input: None. * * Output: None. * * Side Effects: None. * * Overview: Main entry function. If there is a trigger or * if there is no valid application, the device * stays in firmware upgrade mode. * * * Note: None. ********************************************************************/ INT main(void) { UINT pbClk; // Setup configuration pbClk = SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE); InitLED(); mLED = 0; TRISAbits.TRISA4 = 1; // TEST pin CNPDAbits.CNPDA4 = 1; // Pull-down delay_us( 10 ); // Wait a bit until the port pin got pulled down. // Enter firmware upgrade mode if there is a trigger or if the application is not valid if(CheckTrigger() || !ValidAppPresent()) { // Initialize the transport layer - UART/USB/Ethernet TRANS_LAYER_Init(pbClk); while(!FRAMEWORK_ExitFirmwareUpgradeMode()) // Be in loop till framework recieves "run application" command from PC { // Enter firmware upgrade mode. // Be in loop, looking for commands from PC TRANS_LAYER_Task(); // Run Transport layer tasks FRAMEWORK_FrameWorkTask(); // Run frame work related tasks (Handling Rx frame, process frame and so on) // Blink LED (Indicates the user that bootloader is running). BlinkLED(); } // Close trasnport layer. TRANS_LAYER_Close(); mLED = 0; while ( CheckTrigger() ) {}; // Do not run the application while TEST is still tied to VCC. } // No trigger + valid application = run application. CNPDAbits.CNPDA4 = 0; // turn off Pull-down JumpToApp(); return 0; }
static void AppChoose(u8 *pData, u32 *pLen, volatile eCOM_STATUS *peStat) { static u8 flg = 0; if (*pLen > 0) { if ((*pData == 'C') || (*pData == 'c')) { if (flg == 0) flg++; if (flg && IS_TIMEOUT_1MS(eTim1, 100)) //二次确认 *peStat = eCOMDisplay; } *pLen = 0; } if (IS_TIMEOUT_1MS(eTim2, 200)) { JumpToApp(); Print("\n\r运行失败!"); while (1); } }
/******************************************************************** * Function: WriteHexRecord2Flash() * * Precondition: * * Input: None. * * Output: * * Side Effects: No return from here. * * Overview: Writes Hex Records to Flash. * * * Note: None. ********************************************************************/ void WriteHexRecord2Flash(UINT8* HexRecord) { static T_HEX_RECORD HexRecordSt; UINT8 Checksum = 0; UINT8 i; UINT WrData; UINT RdData; void* ProgAddress; UINT result; HexRecordSt.RecDataLen = HexRecord[0]; HexRecordSt.RecType = HexRecord[3]; HexRecordSt.Data = &HexRecord[4]; // Hex Record checksum check. for(i = 0; i < HexRecordSt.RecDataLen + 5; i++) { Checksum += HexRecord[i]; } if(Checksum != 0) { //Error. Hex record Checksum mismatch. //Indicate Error by switching ON all LEDs. //Error(); // Do not proceed further. ErrorFunction(); } else { // Hex record checksum OK. switch(HexRecordSt.RecType) { case DATA_RECORD: //Record Type 00, data record. HexRecordSt.Address.byte.MB = 0; HexRecordSt.Address.byte.UB = 0; HexRecordSt.Address.byte.HB = HexRecord[1]; HexRecordSt.Address.byte.LB = HexRecord[2]; // Derive the address. HexRecordSt.Address.Val = HexRecordSt.Address.Val + HexRecordSt.ExtLinAddress.Val + HexRecordSt.ExtSegAddress.Val; while(HexRecordSt.RecDataLen) // Loop till all bytes are done. { // Convert the Physical address to Virtual address. ProgAddress = (void *)PA_TO_KVA0(HexRecordSt.Address.Val); // Make sure we are not writing boot area and device configuration bits. if(((ProgAddress >= (void *)APP_FLASH_BASE_ADDRESS) && (ProgAddress <= (void *)APP_FLASH_END_ADDRESS)) && ((ProgAddress < (void*)DEV_CONFIG_REG_BASE_ADDRESS) || (ProgAddress > (void*)DEV_CONFIG_REG_END_ADDRESS))) { if(HexRecordSt.RecDataLen < 4) { // Sometimes record data length will not be in multiples of 4. Appending 0xFF will make sure that.. // we don't write junk data in such cases. WrData = 0xFFFFFFFF; memcpy(&WrData, HexRecordSt.Data, HexRecordSt.RecDataLen); } else { memcpy(&WrData, HexRecordSt.Data, 4); } // Write the data into flash. result = NVMemWriteWord(ProgAddress, WrData); // Assert on error. This must be caught during debug phase. if(result != 0) { while(1); } } // Increment the address. HexRecordSt.Address.Val += 4; // Increment the data pointer. HexRecordSt.Data += 4; // Decrement data len. if(HexRecordSt.RecDataLen > 3) { HexRecordSt.RecDataLen -= 4; } else { HexRecordSt.RecDataLen = 0; } } break; case EXT_SEG_ADRS_RECORD: // Record Type 02, defines 4th to 19th bits of the data address. HexRecordSt.ExtSegAddress.byte.MB = 0; HexRecordSt.ExtSegAddress.byte.UB = HexRecordSt.Data[0]; HexRecordSt.ExtSegAddress.byte.HB = HexRecordSt.Data[1]; HexRecordSt.ExtSegAddress.byte.LB = 0; // Reset linear address. HexRecordSt.ExtLinAddress.Val = 0; break; case EXT_LIN_ADRS_RECORD: // Record Type 04, defines 16th to 31st bits of the data address. HexRecordSt.ExtLinAddress.byte.MB = HexRecordSt.Data[0]; HexRecordSt.ExtLinAddress.byte.UB = HexRecordSt.Data[1]; HexRecordSt.ExtLinAddress.byte.HB = 0; HexRecordSt.ExtLinAddress.byte.LB = 0; // Reset segment address. HexRecordSt.ExtSegAddress.Val = 0; break; case END_OF_FILE_RECORD: //Record Type 01, defines the end of file record. HexRecordSt.ExtSegAddress.Val = 0; HexRecordSt.ExtLinAddress.Val = 0; // Disable any interrupts here before jumping to the application. JumpToApp(); break; default: HexRecordSt.ExtSegAddress.Val = 0; HexRecordSt.ExtLinAddress.Val = 0; break; } } }
void BOOTLDR_Run() { volatile UINT i; FILEHANDLE *myFile; FILEHANDLE *currentFile; FW_VERSION newVersion; CHAR buffer[64]; newVersion.major = 0; newVersion.minor = 0; newVersion.build = 0; //if(!ForcedFirmwareExists() && !NewerFirmwareExists() && ValidAppPresent()) if(!ShouldFlashFirmware(sTargetFile, &newVersion) && ValidAppPresent()) { // No new firmware to load. Jump // directly to the application JumpToApp(); } // At this point sTargetFile will have the name of the file we should use //strcpy(sTargetFile, "fw/force/v0_0_2.hex"); myFile = FATFS_fopen(sTargetFile,"r"); if(myFile == NULL)// Make sure the file is present. { //Indicate error and stay in while loop. ErrorFunction(); } // Erase Flash (Block Erase the program Flash) EraseFlash(); // Initialize the state-machine to read the records. record.status = REC_NOT_FOUND; while(1) { // For a faster read, read 512 bytes at a time and buffer it. readBytes = FATFS_fread((void *)&asciiBuffer[pointer], 1, 512, myFile); //readBytes = FSfread((void *)&asciiBuffer[pointer],1,512,myFile); if(readBytes == 0) { // Nothing to read. Come out of this loop // break; FATFS_fclose(myFile); // Something fishy. The hex file has ended abruptly, looks like there was no "end of hex record". //Indicate error and stay in while loop. ErrorFunction(); } for(i = 0; i < (readBytes + pointer); i ++) { // This state machine seperates-out the valid hex records from the read 512 bytes. switch(record.status) { case REC_FLASHED: case REC_NOT_FOUND: if(asciiBuffer[i] == ':') { // We have a record found in the 512 bytes of data in the buffer. record.start = &asciiBuffer[i]; record.len = 0; record.status = REC_FOUND_BUT_NOT_FLASHED; } break; case REC_FOUND_BUT_NOT_FLASHED: if((asciiBuffer[i] == 0x0A) || (asciiBuffer[i] == 0xFF)) { // We have got a complete record. (0x0A is new line feed and 0xFF is End of file) // Start the hex conversion from element // 1. This will discard the ':' which is // the start of the hex record. ConvertAsciiToHex(&record.start[1],hexRec); // We're done so let's close the file and update current.txt if(hexRec[3] == END_OF_FILE_RECORD) { FATFS_fclose(myFile); currentFile = FATFS_fopen("fw/current.txt", "wo"); if(currentFile != NULL) { sprintf(buffer, "v%d_%d_%d.hex", newVersion.major, newVersion.minor, newVersion.build); FATFS_fwrite(buffer, 1, strlen(buffer), currentFile); FATFS_fclose(currentFile); } } WriteHexRecord2Flash(hexRec); record.status = REC_FLASHED; // Blink the green LED to indicate programming in progress mLED_Green_Toggle(); } break; } // Move to next byte in the buffer. record.len ++; } if(record.status == REC_FOUND_BUT_NOT_FLASHED) { // We still have a half read record in the buffer. The next half part of the record is read // when we read 512 bytes of data from the next file read. memcpy(asciiBuffer, record.start, record.len); pointer = record.len; record.status = REC_NOT_FOUND; } else { pointer = 0; } }//while(1) }// end BOOTLDR_Run function
void RunApp(void) { CloseCon(); JumpToApp(); }
/******************************************************************** * Function: main() ********************************************************************/ INT main(void) { DWORD count1 = 0; BYTE timer_ro = 1; // switch to FRC w/PLL to keep up at higher baud rates (120MHz! PLLFBD=63; CLKDIVbits.PLLPOST = 0; CLKDIVbits.PLLPRE = 0; __builtin_write_OSCCONH(0x01); __builtin_write_OSCCONL(OSCCON | 0x01); while (OSCCONbits.COSC != 0b001); while (OSCCONbits.LOCK != 1); // Initialize I/O, UART and timer (interrupt) initIO(); led1Off(); led2Off(); led3Off(); printString("BL:V1.00:"); if (ValidAppPresent()) { while(count1<20) { if ((SWITCH1 == 0) || (SWITCH2 == 0)) // if either switch gets released, start app JumpToApp(); // Blink LEDs if (timer_ro) { if (TMR1 > 7000) { blinkLEDs(); count1++; timer_ro = 0; } } else if (TMR1 < 7000) timer_ro = 1; } printString("PB:"); } else { printString("NA:"); // No app present, enter bootloader regardless } T1CONbits.TON = 0; PR1 = 50000; // slow down blinking T1CONbits.TON = 1; blink_mode = 1; // Be in loop till framework recieves "run application" command from PC while(!ExitFirmwareUpgradeMode()) { uartTask(); // Run Transport layer tasks if(FrameWorkTask()) // Run frame work related tasks (Handling Rx frame, process frame and so on) { blink_mode = 2; // If we've communicated with the PC, use progress flashing } // Blink LEDs if (timer_ro) { if (TMR1 > 25000) { if (SWITCH1 && (SWITCH2 == 0)) // reset the device on SWITCH1 press reset(); blinkLEDs(); timer_ro = 0; } } else if (TMR1 < 25000) timer_ro = 1; } JumpToApp(); return 0; }
/******************************************************************** * Function: main() * * Precondition: * * Input: None. * * Output: None. * * Side Effects: None. * * Overview: Main entry function. If there is a trigger or * if there is no valid application, the device * stays in firmware upgrade mode. * * * Note: None. ********************************************************************/ int main(void) { // No trigger + valid application = run application. JumpToApp(); return 0; }