/*
 *	clipbakm.h
 *
 *	バックアップ管理
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2015 Naoyuki Sawa
 *
 *	* Sun May 03 17:00:13 JST 2015 Naoyuki Sawa
 *	- 1st リリース。
 *	  主に、SVD(電源電圧低下検出)割り込みでのバックアップを想定しました。
 *	- SVD割り込みを使用せずに、アプリケーション終了時のバックアップにも使用できます。
 *	  P/ECEで利用する場合は、後者の使用方法になる事の方が多いと思います。
 *	  その場合は、メインループでBakMgr_Exec()を呼び出す必要は有りません。
 *	  アプリケーション終了時に、BakMgr_Exec(),BakMgr_Commit()の順で呼び出して下さい。
 *	* Mon May 04 15:54:46 JST 2015 Naoyuki Sawa
 *	- 「アプリケーションプログラムの使用例」を追記しました。
 *	* Wed May 06 10:25:34 JST 2015 Naoyuki Sawa
 *	- 前回の版は、割り込みルーチンがメモリ内容を変更途中である値を、バックアップしてしまう可能性が有りました。
 *	  詳細については、前回のアーカイブ内のBakMgr_Exec()実装部のコメント「原子性の保証について」を参照してください。
 *	  今回の版で修正したので、どのようなタイミングでSVD割り込み(NMI)が発生しても、安定したメモリ内容をバックアップします。
 *	  具体的には、コメント「原子性の保証について」の、対策案①を採用しました。
 *	  コメント「原子性の保証について」では対策案②を採用する予定と書きましたが、再検討して対策案①を採用する事にしました。
 *	  理由は、メモリを4KB多く消費するデメリットよりも、割り込み応答性能を維持する事の方が、重要だと思ったからです。
 *	* Wed Nov 18 21:37:53 JST 2015 Naoyuki Sawa
 *	- 'extern "C" {'～'}'で囲みました。.cppを含むWin32プロジェクトからもインクルード出来るようにするためです。
 */
#ifndef __CLIP_BAKM_H__
#define __CLIP_BAKM_H__
#ifdef  __cplusplus
extern "C" {
#endif//__cplusplus
/****************************************************************************
 *	定数、構造体
 ****************************************************************************/
//当モジュールを単体で使用しBakMgr_FileWords,BakMgrCh_Maxを指定する場合は、アプリケーションヘッダファイル内で当ファイルをインクルードするよりも上の位置で定義せよ。
#ifndef BakMgr_FileWords
#define BakMgr_FileWords	(BLOCKSIZE/4)		//バックアップファイルのワード数。16の倍数で調整可能。16の倍数とする理由はBakMgr_CalcCheckSum()を参照せよ。
#endif//BakMgr_FileWords
#ifndef BakMgrCh_Max
#define BakMgrCh_Max		15			//バックアップチャンク番号の最大値(この値も含む)。0以上で調整可能。
#endif//BakMgrCh_Max
/*--------------------------------------------------------------------------*/
//バックアップチャンク
typedef struct _ST_BakMgrCh {
	uint32_t*		VramAddr;		//バックアップ対象とする揮発性RAMの先頭アドレス
	int			VramWords;		//バックアップ対象とする揮発性RAMのワード数
} ST_BakMgrCh;
/*--------------------------------------------------------------------------*/
//バックアップ管理
typedef struct _ST_BakMgr {
	struct {
	  unsigned		Valid		:1;				//初期化時にバックアップが有効だったならば1，無効だったならば0
	  unsigned		Side		:1;				//スナップショットA面([0])が有効ならば0，B面([1])が有効ならば1
	} Flag;
	ST_BakMgrCh		TBL_BakMgrCh[(BakMgrCh_Max+1)];			//バックアップチャンクテーブル				(!VramAddr)であるエントリ以降は未使用
	uint32_t		Snapshot[2/*0=A面,1=B面*/][BakMgr_FileWords];	//バックアップ対象とする揮発性RAMのスナップショット	BakMgr_Init()にて[0]にマジックナンバーを格納する。BakMgr_Exec()にて[1～(BakMgr_FileWords-1)]にバックアップ対象とする揮発性RAMのスナップショットをコピーする。
} ST_BakMgr;
/****************************************************************************
 *	アプリケーション用関数
 ****************************************************************************/
int BakMgr_Init(void (*fnReadFile)(uint32_t Buffer[/*BakMgr_FileWords*/]), int MagicNumber);
int BakMgr_Alloc(void* VramAddr, int VramWords, int bRestore);
void BakMgr_Exec();
void BakMgr_Commit(void (*fnWriteFile)(const uint32_t Buffer[/*BakMgr_FileWords*/]));
#ifdef  __cplusplus
}//extern "C"
#endif//__cplusplus
#endif//__CLIP_BAKM_H__
