通信设计应用
FLASHQueue[ ] | |
Queue Index | Data Flash Address |
31 | 0xC1F0-0xC1FF |
30 | 0xC1E0-0xC1EF |
29 | 0xC1D0-0xC1DF |
. . . . | . . . . |
2 | 0xC020-0xC05F |
1 | 0xC010-0xC03F |
0 | 0xC000-0xC00F |
u16 flashErasePage(void *); u16 flashEraseSector(void *); u16 flashEraseAll(void); u16 dataFlashWrite(u16 *pAddress, u16 iData); u16 dataFlashErasePage(void *); u16 dataFlashEraseSector(void *); u16 dataFlashEraseAll(void);Next, add linker defines to assign the appropriate address for each routine. For the IAR linker file, the added lines would look like this:
-DflashEraseSector=0x8XXX -DflashErasePage=0x8XXX -DflashEraseAll=0x8XXXReplace 0x8XXX with the appropriate memory address for each routine. Other compilers may use a different method for adding these references.
Routine Number | Routine Name | Entry Point ROMTable = ROM[800Dh] | Entry Point Physical Address |
1 | flashWrite | ROM[ROMTable] | 0x8XXX |
2 | flashErasePage | ROM[ROMTable + 1] | 0x8XXX |
3 | flashEraseAll | ROM[ROMTable + 2] | 0x8XXX |
4 | moveDP0 | ROM[ROMTable + 3] | 0x8XXX |
16 | flashEraseSector | ROM[ROMTable + 15] | 0x8XXX |
17 | dataFlashWrite | ROM[ROMTable + 16] | 0x8XXX |
19 | dataFlashErasePage | ROM[ROMTable + 18] | 0x8XXX |
20 | dataFlashEraseSector | ROM[ROMTable + 19] | 0x8XXX |
21 | dataFlashEraseAll | ROM[ROMTable + 20] | 0x8XXX |
Routine: | u16 flashWrite(u16 *pDest, u16 *pSrc) |
Summary: | Programs a single page (32 words) of program-flash memory. |
Inputs: | DP[0]—Destination address in flash memory. DP[1]—Source address in SRAM holding 32 words of data to write. |
Outputs: | Carry: Set on error and cleared on success. If set, then A[0] contains one of the following error codes: 1: failure due to software timeout 2: failure reported by hardware (DQ5/FERR) 4: command not supported SW_FERR—Set on error, cleared on success. |
Notes: | The watchdog must not be active or the watchdog timeout must be set long enough to complete this routine without triggering a reset. |
; This routine is callable by C code using the following prototype ; u16 flashWrite(u16 *pDest, u16 *pSrc); ; flashWrite: move APC, #0 ; No auto inc/dec of accumulator. move AP, #2 ; Set ACC to A[2]. move DP[0], #0800Dh ; This is where the address of the table is stored. move ACC, @DP[0] ; Get the location of the routine table. add #14 ; Add the index to the flashWrite routine. move DP[0], ACC move ACC, @DP[0] ; Retrieve the address of the routine. push DP[1] ; Save Frame Pointer on the stack. move DP[0],A[0] ; Move argument 0(dest address) to DP[0]. move DP[1],A[1] ; Move argument 1(src address) to DP[1]. call ACC ; Execute the routine. pop DP[1] ; Restore Frame Pointer. ret ; Status returned in A[0].FlashErasePage()
Routine: | u16 flashErasePage(void *pAddress) |
Summary: | Erases a two-page block of program-flash memory. |
Inputs: | A[0]—Address located in the two-page block to erase, i.e., to erase pages 0 and 1, A[0] can contain any address from 0x0000 to 0x001F. |
Outputs: | Carry: Set on error and cleared on success. If set, then A[0] contains one of the following error codes: 1: failure due to software timeout 2: failure reported by hardware (DQ5/FERR) 4: command not supported SW_FERR—Set on error, cleared on success. |
Notes: | The watchdog must not be active or the watchdog timeout must be set long enough to complete this routine without triggering a reset. |
; This routine is callable by C code using the following prototype ; u16 flashErasePage(void *pAddress); ; flashErasePage: move APC, #0 ; No auto inc/dec of accumulator. move AP, #1 ; Set ACC to A[1]. move DP[0], #0800Dh ; This is where the address of the table is stored. move ACC, @DP[0] ; Get the location of the routine table. add #1 ; Add the index to the flashEraseSector routine. move DP[0], ACC move ACC, @DP[0] ; Retrieve the address of the routine. call ACC ; Execute the routine. ret ; Status returned in A[0].FlashEraseAll()
Routine: | Void flashEraseAll(void) |
Summary: | Erases the entire program and data-flash memory. This routine can only be called from RAM. |
Inputs: | None |
Outputs: | Carry: Set on error and cleared on success. SW_FERR—Set on error, cleared on success. |
Notes: | The watchdog must not be active or the watchdog timeout must be set long enough to complete this routine without triggering a reset. |
; This routine is callable by C code using the following prototype ; void flashEraseAll(void); ; flashEraseAll: move APC, #0 ; No auto inc/dec of accumulator. move AP, #0 ; Set ACC to A[0]. move DP[0], #0800Dh ; This is where the address of the table is stored. move ACC, @DP[0] ; Get the location of the routine table. add #2 ; Add the index to the flashEraseAll routine. move DP[0], ACC move ACC, @DP[0] ; Retrieve the address of the routine. call ACC ; Execute the routine. retmoveDP0
Routine: | moveDP0 |
Summary: | Reads a single word of flash memory. |
Inputs: | DP[0]—Source address in flash memory. Add 0x8000 to read program flash. |
Outputs: | GR will contain the data at specified address. |
Notes: | This function cannot be called directly from C because the argument and return register are not compatible with C calling conventions. |
; This routine is callable by C code using the following prototype ; u16 flashRead(u16 *pAddress); ; flashRead: move APC, #0 ; No auto inc/dec of accumulator. move AP, #1 ; Set ACC to A[1]. move DP[0], #0800Dh ; This is where the address of the table is stored. move ACC, @DP[0] ; Get the location of the routine table. add #3 ; Add the index to the moveDP0 routine. move DP[0], ACC move ACC, @DP[0] ; Retrieve the address of the routine. push DP[1] ; Save Frame Pointer on the stack. move DP[0],A[0] ; Move argument 0(src address) to DP[0]. call ACC ; Execute the routine. pop DP[1] ; Restore Frame Pointer. move A[0],GR ret ; Data word returned in A[0].FlashEraseSector()
Routine: | u16 flashEraseSector(void *pAddress) |
Summary: | Erases a single sector of program-flash memory. |
Inputs: | A[0]—Address located in the sector to erase. |
Outputs: | Carry: Set on error and cleared on success. If set, then A[0] contains one of the following error codes: 1: failure due to software timeout 2: failure reported by hardware (DQ5/FERR) 4: command not supported SW_FERR—Set on error, cleared on success. |
Notes: | The watchdog must not be active or the watchdog timeout must be set long enough to complete this routine without triggering a reset. |
; This routine is callable by C code using the following prototype ; u16 flashEraseSector(void *pAddress); ; flashEraseSector: move APC, #0 ; No auto inc/dec of accumulator. move AP, #1 ; Set ACC to A[1]. move DP[0], #0800Dh ; This is where the address of the table is stored. move ACC, @DP[0] ; Get the location of the routine table. add #15 ; Add the index to the flashEraseSector routine. move DP[0], ACC move ACC, @DP[0] ; Retrieve the address of the routine. call ACC ; Execute the routine. ret ; Status returned in A[0].DataFlashWrite()
Routine: | u16 dataFlashWrite(void *pAddress, u16 *pData) |
Summary: | Programs a single word of data-flash memory. |
Inputs: | A[0]—Word address in flash memory to which to write. A[1] —Word value to write to flash memory. |
Outputs: | Carry: Set on error and cleared on success. If set, then A[0] contains one of the following error codes: 1: failure due to software timeout 2: failure reported by hardware (DQ5/FERR) 4: command not supported SW_FER —Set on error, cleared on success. |
Notes: | The watchdog must not be active or the watchdog timeout must be set long enough to complete this routine without triggering a reset. |
; This routine is callable by C code using the following prototype ; u16 dataFlashWrite(void *pAddress, u16 iData); ; dataFlashWrite: move APC, #0 ; No auto inc/dec of accumulator. move AP, #2 ; Set ACC to A[2]. move DP[0], #0800Dh ; This is where the address of the table is stored. move ACC, @DP[0] ; Get the location of the routine table. add #16 ; Add the index to the flashWrite routine. move DP[0], ACC move ACC, @DP[0] ; Retrieve the address of the routine. call ACC ; Execute the routine. ret ; Status returned in A[0].DataFlashErasePage()
Routine: | u16 dataFlashErasePage(void *pAddress) |
Summary: | Erases two pages of data-flash memory. |
Inputs: | A[0]—Address located in the two-page block to erase, i.e., to erase pages 0 and 1, A[0] can contain address 0x4000 or 0x4001. |
Outputs: | Carry: Set on error and cleared on success. If set, then A[0] contains one of the following error codes: 1: failure due to software timeout 2: failure reported by hardware (DQ5/FERR) 4: command not supported SW_FERR—Set on error, cleared on success. |
Notes: | The watchdog must not be active or the watchdog timeout must be set long enough to complete this routine without triggering a reset. |
; This routine is callable by C code using the following prototype ; u16 dataFlashErasePage(void *pAddress); ; dataFlashErasePage: move APC, #0 ; No auto inc/dec of accumulator. move AP, #1 ; Set ACC to A[1]. move DP[0], #0800Dh ; This is where the address of the table is stored. move ACC, @DP[0] ; Get the location of the routine table. add #18 ; Add the index to the dataFlashErasePage routine. move DP[0], ACC move ACC, @DP[0] ; Retrieve the address of the routine. call ACC ; Execute the routine. ret ; Status returned in A[0].DataFlashEraseSector()
Routine: | u16 dataFlashEraseSector(void *pAddress) |
Summary: | Erases a single sector of data-flash memory. |
Inputs: | A[0]—Address located in the sector to erase. |
Outputs: | Carry: Set on error and cleared on success. If set, then A[0] contains one of the following error codes: 1: failure due to software timeout 2: failure reported by hardware (DQ5/FERR) 4: command not supported SW_FERR—Set on error, cleared on success. |
Notes: | The watchdog must not be active or the watchdog timeout must be set long enough to complete this routine without triggering a reset. |
; This routine is callable by C code using the following prototype ; u16 dataFlashEraseSector(void *pAddress); ; dataFlashEraseSector: move APC, #0 ; No auto inc/dec of accumulator. move AP, #1 ; Set ACC to A[1]. move DP[0], #0800Dh ; This is where the address of the table is stored. move ACC, @DP[0] ; Get the location of the routine table. add #19 ; Add the index to the dataFlashEraseSector routine. move DP[0], ACC move ACC, @DP[0] ; Retrieve the address of the routine. call ACC ; Execute the routine. ret ; Status returned in A[0].dataFlashEraseAll
Routine: | void dataFlashEraseAll(void) |
Summary: | Erases the entire data flash memory. |
Inputs: | None |
Outputs: | Carry: Set on error and cleared on success. SW_FERR—Set on error, cleared on success. |
Notes: | The watchdog must not be active or the watchdog timeout must be set long enough to complete this routine without triggering a reset. |
; This routine is callable by C code using the following prototype ; void dataFlashEraseAll(void); ; dataFlashEraseAll: move APC, #0 ; No auto inc/dec of accumulator. move AP, #0 ; Set ACC to A[0]. move DP[0], #0800Dh ; This is where the address of the table is stored. move ACC, @DP[0] ; Get the location of the routine table. add #20 ; Add the index to the flashEraseAll routine. move DP[0], ACC move ACC, @DP[0] ; Retrieve the address of the routine. call ACC ; Execute the routine. ret
You cannot erase or program from the same flash page from which you are executing code. This is not normally a problem since the flash boot-loader application should never be erased during IAP. |
The watchdog must not be enabled, or the watchdog timeout must be set long enough to complete this routine without triggering a reset before calling the flashEraseSector() or flashErasePage() routine. If the watchdog time out occurs before the erase is complete, it will reset the part. |
Because the System Control Register bit, SC.UPA, must be set to 0 to access the Utility ROM, a Utility ROM routine cannot be called directly from program memory addresses ≥ 0x8000. If access to a Utility ROM routine is required from a program in upper memory (≥ 0x8000), the program must indirectly call the ROM routine through a routine residing in lower memory (< 0x8000). This restriction effectively limits the boot loader to = 64KB (32KB x 16). |
typedef struct { u16 iSize; // The size of the application in words u32 iCRC; // The CRC of the application u8 ID[8]; // ID string for current application } APPLICATION_HEADER;Using the information from this header, the boot loader can check the validity of the main application program and report the version identification if requested.
/* // VerySimpleReFlash() // As simple as it gets. // Step 1. Wait for erase command, then erase flash. // Step 2. Wait for program command, program flash one word at a time. */ void VerySimpleReFlash() { u16 iStatus; // The status returned from flash utility ROM calls s32 iSize; // The size of the main code to program u16 *pAddress = 0x2000; // The starting address of the main application u16 i; InitializeCOMM(); // Can be CAN or UART. WaitForEraseCommand(); // Assume that application starts at the beginning of a sector. for (i=C_START_SECTOR;i0) { u16 iData[32]; Get32WordsFromCOMM(iData); iStatus = flashWrite(pAddress, iData); if (iStatus) break; pAddress += 32; iSize -= 32; UpdateWatchdog(); // Prevent timeout } SendFlashWriteResponse(iStatus); ResetMicro(); }
全部0条评论
快来发表一下你的评论吧 !