キーワード: MAXQ7665C, ページ消去可能, フラッシュ, MAXQ, インアプリケーション, プログラミング
関連製品 |
FLASHQueue[ ] | |
Queue Index | Data Flash Address |
7 | 0xC038-0xC03F |
6 | 0xC030-0xC037 |
5 | 0xC028-0xC02F |
4 | 0xC020-0xC027 |
3 | 0xC018-0xC01F |
2 | 0xC010-0xC017 |
1 | 0xC008-0xC00F |
0 | 0xC000-0xC007 |
u16 flashErasePage(void *); u16 flashEraseSector(void *); u16 flashEraseAll(void); u16 dataFlashWriteE(u16 *pAddress, u16 iData); u16 dataFlashErasePage(void *); u16 dataFlashEraseSector(void *); u16 dataFlashEraseAll(void); u16 dataFlashReadE(u16 *pAddress, u16 iData);次に、リンカ定義を追加して、各ルーチンに適切なアドレスを割り当てますIARリンカのファイルの場合、追加された行は、次のようになります。
-DflashEraseSector=0x8XXX -DflashErasePage=0x8XXX -DflashEraseAll=0x8XXX . . .ルーチンごとに0x8XXXを適切なメモリアドレスに置き換えます。他のコンパイラは、このようなリファレンスを追加するのに別の手法を使用する場合があります。
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 |
18 | dataFlashWriteE | ROM[ROMTable + 17] | 0x8XXX |
19 | dataFlashErasePage | ROM[ROMTable + 18] | 0x8XXX |
20 | dataFlashEraseSector | ROM[ROMTable + 19] | 0x8XXX |
21 | dataFlashEraseAll | ROM[ROMTable + 20] | 0x8XXX |
22 | dataFlashReadE | ROM[ROMTable + 21] | 0x8XXX |
ルーチン: | u16 flashWrite(u16 *pDest, u16 *pSrc) |
要約: | プログラムフラッシュメモリの単一ページ(32ワード)をプログラムします。 |
入力: | DP[0]—フラッシュメモリ内のディスティネーションアドレス DP[1]—書き込む32ワードのデータを保持するSRAM内のソースアドレス |
出力: | キャリー:エラー時にセットされ、成功時にクリアされます。セットされた場合、A[0]には、以下のエラーコードの1つが含まれます。 1: ソフトウェアのタイムアウトによる失敗 2: ハードウェアによって報告される失敗(DQ5/FERR) 4: サポートされていないコマンド SW_FERR—エラー時にセットされ、成功時にクリアされます。 |
注: | ウォッチドッグを有効にしないでください。あるいはウォッチドッグのタイムアウトを十分に長く設定することによって、リセットが起動されることなくこのルーチンが完了するようにしてください。 |
; 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()
ルーチン: | u16 flashErasePage(void *pAddress) |
要約: | プログラムフラッシュメモリの2ページブロックを消去します。 |
入力: | A[0]—消去する2ページブロック(すなわちページ0とページ1)に位置付けられたアドレス。A[0]には、0x0000~0x001Fの任意のアドレスを記入することができます。 |
出力: | キャリー:エラー時にセットされ、成功時にクリアされます。セットされた場合、A[0]には、以下のエラーコードの1つが含まれます。 1: ソフトウェアのタイムアウトによる失敗 2: ハードウェアによって報告される失敗(DQ5/FERR) 4: サポートされていないコマンド SW_FERR—エラー時にセットされ、成功時にクリアされます。 |
注: | ウォッチドッグを有効にしないでください。あるいはウォッチドッグのタイムアウトを十分に長く設定することによって、リセットが起動されることなくこのルーチンが完了するようにしてください。 |
; 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()
ルーチン: | Void flashEraseAll(void) |
要約: | プログラムとデータのフラッシュメモリ全体を消去します。このルーチンはRAMからのみ呼び出すことができます。 |
入力: | なし |
出力: | キャリー:エラー時にセットされ、成功時にクリアされます。 SW_FERR—エラー時にセットされ、成功時にクリアされます。 |
注: | ウォッチドッグを有効にしないでください。あるいはウォッチドッグのタイムアウトを十分に長く設定することによって、リセットが起動されることなくこのルーチンが完了するようにしてください。 |
; 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
ルーチン: | moveDP0 |
要約: | プログラムフラッシュメモリの単一ワードを読み出します。 |
入力: | DP[0]—フラッシュメモリ内のソースアドレス。プログラムフラッシュを呼び出す0x8000を追加 |
出力: | GRは、指定したアドレスにデータが含まれます。 |
注: | この関数は、引数と戻りのレジスタがCの呼出し仕様に適合していないため、Cからじかに呼び出すことはできません。 |
; 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()
ルーチン: | u16 flashEraseSector(void *pAddress) |
要約: | プログラムフラッシュメモリの単一セクタを消去します。 |
入力: | A[0]—消去するセクタに位置付けられたアドレス |
出力: | キャリー:エラー時にセットされ、成功時にクリアされます。セットされた場合、A[0]には、以下のエラーコードの1つが含まれます。 1: ソフトウェアのタイムアウトによる失敗 2: ハードウェアによって報告される失敗(DQ5/FERR) 4: サポートされていないコマンド SW_FERR—エラー時にセットされ、成功時にクリアされます。 |
注: | ウォッチドッグを有効にしないでください。あるいはウォッチドッグのタイムアウトを十分に長く設定することによって、リセットが起動されることなくこのルーチンが完了するようにしてください。 |
; 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].dataFlashWriteE()
ルーチン: | u16 dataFlashWriteE(void *pAddress, u16 *pData) |
要約: | データフラッシュメモリの単一ワードをプログラムします。 |
入力: | A[0]—書き込むフラッシュメモリのワードアドレス A[1]—フラッシュメモリに書き込むワード値 |
出力: | キャリー:エラー時にセットされ、成功時にクリアされます。セットされた場合、A[0]には、以下のエラーコードの1つが含まれます。 1: ソフトウェアのタイムアウトによる失敗 2: ハードウェアによって報告される失敗(DQ5/FERR) 4: サポートされていないコマンド SW_FERR—エラー時にセットされ、成功時にクリアされます。 |
注: | ウォッチドッグを有効にしないでください。あるいはウォッチドッグのタイムアウトを十分に長く設定することによって、リセットが起動されることなくこのルーチンが完了するようにしてください。このルーチンはdataFlashReadE()とセットになるルーチンです。 |
; This routine is callable by C code using the following prototype ; u16 dataFlashWriteE(void *pAddress, u16 iData); ; dataFlashWriteE: 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()
ルーチン: | u16 dataFlashErasePage(void *pAddress) |
要約: | データフラッシュメモリの2ページを消去します。 |
入力: | A[0]—消去する2ページブロック(すなわちページ0とページ1)に位置付けられたアドレス。A[0]には、0x4000あるいは0x4001のアドレスを記入することができます。 |
出力: | キャリー:エラー時にセットされ、成功時にクリアされます。セットされた場合、A[0]には、以下のエラーコードの1つが含まれます。 1: ソフトウェアのタイムアウトによる失敗 2: ハードウェアによって報告される失敗(DQ5/FERR) 4: サポートされていないコマンド SW_FERR—エラー時にセットされ、成功時にクリアされます。 |
注: | ウォッチドッグを有効にしないでください。あるいはウォッチドッグのタイムアウトを十分に長く設定することによって、リセットが起動されることなくこのルーチンが完了するようにしてください。 |
; 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()
ルーチン: | u16 dataFlashEraseSector(void *pAddress) |
要約: | データフラッシュメモリの単一セクタを消去します。 |
入力: | A[0]—消去するセクタに位置付けられたアドレス |
出力: | キャリー:エラー時にセットされ、成功時にクリアされます。セットされた場合、A[0]には、以下のエラーコードの1つが含まれます。 1: ソフトウェアのタイムアウトによる失敗 2: ハードウェアによって報告される失敗(DQ5/FERR) 4: サポートされていないコマンド SW_FERR—エラー時にセットされ、成功時にクリアされます。 |
注: | ウォッチドッグを有効にしないでください。あるいはウォッチドッグのタイムアウトを十分に長く設定することによって、リセットが起動されることなくこのルーチンが完了するようにしてください。 |
; 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()
ルーチン: | void dataFlashEraseAll(void) |
要約: | データフラッシュメモリ全体を消去します。 |
入力: | なし |
出力: | キャリー:エラー時にセットされ、成功時にクリアされます。 SW_FERR—エラー時にセットされ、成功時にクリアされます。 |
注: | ウォッチドッグを有効にしないでください。あるいはウォッチドッグのタイムアウトを十分に長く設定することによって、リセットが起動されることなくこのルーチンが完了するようにしてください。 |
; 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. retdataFlashReadE
ルーチン: | dataFlashReadE |
要約: | フラッシュメモリの単一ワードを読み出します。 |
入力: | A[0]—フラッシュメモリ内のソースアドレス。 |
出力: | A[0]—指定したアドレスにデータが含まれます。 |
注: | dataFlashWriteE()とセットとなるルーチンです。 |
; This routine is callable by C code using the following prototype ; u16 flashReadE(u16 *pAddress); ; dataFlashReadE: 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 #21 ; Add the index to the dataFlashReadE routine. move DP[0], ACC move ACC, @DP[0] ; Retrieve the address of the routine. call ACC ; Execute the routine. ret ; Data word returned in A[0].
コードを実行しているフラッシュページと同じフラッシュページから消去またはプログラムすることはできません。これは通常、問題にはなりません。フラッシュのブートローダアプリケーションはIAPの間に決して消去してはならないからです。 |
ウォッチドッグを有効にしないでください。あるいはウォッチドッグのタイムアウトを十分に長く設定することによって、flashEraseSector()またはflashErasePage()のルーチンを呼び出す前に、リセットが起動されることなくこのルーチンが完了するようにしてください。消去が完了する前にウォッチドッグのタイムアウトが発生すると、製品がリセットされます。 |
ユーティリティROMにアクセスするためには、システム制御レジスタビットSC.UPAを0に設定する必要があるため、0x8000あるいはこれよりも大きなプログラムメモリからじかにユーティリティROMルーチンを呼び出すことはできません。上位のメモリ(≧ 0x8000)のプログラムからユーティリティROMルーチンにアクセスする必要がある場合、下位のメモリ(< 0x8000)に置かれたルーチンを通してROMルーチンを間接的に呼び出す必要があります。このため、実質的にブートローダは64KB (32KB x 16)以下に制限されます。 |
図5のフローチャートは、簡易ブートローダアプリケーションの動作を示しています。簡易アプリケーションのヘッダは、次のようになります。
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;このヘッダの情報を使用することによって、ブートローダは、要求がある場合に、メインアプリケーションプログラムの妥当性を検査し、バージョンの識別番号を報告することができます。
/* // VerySimpleReFlash() // As simple as it gets. // Step 1. Wait for erase command, then erase flash. // Step 2. Wait for program command, then 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;i<C_SECTOR_END;++i) { iStatus = flashEraseSector(C_ADDRESS_SECTOR_1); if (iStatus != 0) break; } SlowDownWatchdogUpdate(); // If watchdog enabled slow down to prevent timeout SendFlashErasedResponse(iStatus); UpdateWatchdog(); // Prevent timeout. if (iStatus) ResetMicro(); iSize = WaitForProgramCommand(); while (iSize > 0) { u16 iData[32]; Get32WordsFromCOMM(iData); iStatus = flashWrite(pAddress, iData); if (iStatus) break; pAddress += 32; iSize -= 32; UpdateWatchdog(); // Prevent timeout. } SendFlashWriteResponse(iStatus); ResetMicro(); }