flashを使用して、 eepromのユーザーエクスペリエンスをシミュレートします
void ee_flashInit() :フォーマットフラッシュ、フォーマットされたフラッシュのみが次の2つのAPI関数を使用できます。ee_uint8 ee_readDataFromFlash() :データを読み取りますee_uint8 ee_writeDataToFlash(); :データを書き込みますvariableLists維持する必要があります最初にヘッダーファイルを入力し、コメントに従って4つのマクロを完全に記入してください
SECTOR_SIZE :現在のフラッシュのセクターの容量サイズ(フラッシュの最小ストレージユニット)ee_flashWrite :フラッシュ書き込み操作ドライバー機能名ee_flashRead :フラッシュ操作ドライバー機能名を読み取りますee_flashEraseASector :フラッシュ消去セクター(フラッシュの最小メモリユニット)ドライバー機能名を消去充填可能なマクロ(詰め物が機能操作に影響しない)
BLOCk_SECTOR_NUM :フラッシュブロックにはいくつのセクターがありますか?2つの特別なマクロ:
SECTORS(x) : xセクターの合計サイズを返しますBLOCKS(x) : xブロックの合計サイズを返します。このマクロを使用するには、事前にMacro BLOCk_SECTOR_NUMを入力する必要があります。上記の2つのマクロは、主にee_flashInit()関数のパラメーターを転送するために使用され、フラッシュアドレスの使用を容易にします。
例:
// 首先在flash_MemMang.h枚举类型中添加数据名,用于管理数据
typedef enum
{
// 用户将变量名添加到下面
G_MYSENSORDATA ,
G_FLOAT ,
// DATA_NUM用于标识flash中一共存了多少个数据(不允许删改)
DATA_NUM ,
} variableLists ;
//------------------主函数-------------
/* 创建flash管理句柄 */
ee_flash_t g_fm ;
/* 想要存入flash中的变量 */
int g_mySensorData = 16 ;
float g_float = 3.14 ;
char g_txt [ 20 ] = "change data test" ;
int main ( void )
{
int dataTmp = 0 ;
float ftmp = 0 ;
char tt [ 20 ];
/* 格式化传入地址的格式 */
ee_flashInit ( & g_fm , /* 管理句柄 */
SECTORS ( 0 ), /* 索引区起始地址 */
SECTORS ( 2 ), /* 交换索引区起始地址 */
2 , /* 总索引区大小(单位:扇区) */
1 , /* 索引区大小(详见README图例,indexRegionSize) */
SECTORS ( 4 ), /* 数据区起始地址 */
SECTORS ( 5 ), /* 交换数据区起始地址 */
1 ); /* 数据区大小(单位:扇区) */
/* 数据写入顺序错误,写入失败 */
ee_writeDataToFlash ( & g_fm , & g_float , sizeof ( g_float ), G_FLOAT );
ee_writeDataToFlash ( & g_fm , & g_mySensorData , sizeof ( g_mySensorData ), G_MYSENSORDATA );
/* 正确将数据写入flash */
ee_writeDataToFlash ( & g_fm , & g_mySensorData , sizeof ( g_mySensorData ), G_MYSENSORDATA );
ee_writeDataToFlash ( & g_fm , & g_float , sizeof ( g_float ), G_FLOAT );
/* 将数据读出 */
ee_readDataFromFlash ( & g_fm , & dataTmp , G_MYSENSORDATA );
ee_readDataFromFlash ( & g_fm , & ftmp , G_FLOAT );
/* 将G_FLOAT管理的数据改成g_txt */
ee_writeDataToFlash ( & g_fm , g_txt , strlen ( g_txt ) + 1 , G_FLOAT );
/* 再读取一次数据 */
dataTmp = 0 ;
ee_readDataFromFlash ( & g_fm , & dataTmp , G_MYSENSORDATA );
ee_readDataFromFlash ( & g_fm , & tt , G_FLOAT );
}フラッシュは1を0にしか変えず、セクター全体(フラッシュの最小ストレージ構造)を消去することにより、0にしか1に変えることができます。したがって、書かれたアドレスが書かれている場合、それが再び記述された場合、それは必然的に0になったビットを1にし、データの無効化になります。
このプログラムのアイデアは、後で書かれていないエリアに書き直したいデータを書くことです。以前に記述されたデータは無効になり、最新の書面によるデータは有効と見なされます。エリア全体がいっぱいになるまで待って、有効なデータを別の領域に転送し、現在のすべての領域を消去します。
プログラムによって実装されたフラッシュの内部構造図:

void ee_flashInit()のフォーマットフラッシュを実行した後、フォーマットされたフラッシュレイアウトを上の図に示します。
合計インデックスエリア:インデックスエリアと書き換え領域の2つの領域が含まれています
インデックス領域:各データを保存するために使用されるインデックス構造。各インデックス構造のアドレス位置は固定されています。たとえば、データNo. 1のアドレスは0x00で、データNo. 2のアドレスは0x08です。ユーザーは、インデックス領域のサイズを指定できます。サイズの仕様については、次の式を参照してください。インデックス領域に保存できるデータの数=インデックスエリアのバイトの総数/8
/* 数据索引结构 */
typedef struct
{
/* 当前数据状态 */
ee_uint16 dataStatus ;
/* 当前数据大小 */
ee_uint16 dataSize ;
/* 当前数据在数据区的地址(相对于dataStartAddr的偏移地址) */
ee_uint16 dataAddr ;
/* 当前数据被重写的地址(相对于overwriteAddr的偏移地址),默认为0xFFFF */
ee_uint16 dataOverwriteAddr ;
} ee_dataIndex ;書き換え領域:データインデックス領域のデータが書き換えられた場合、現在の領域に書き換えインデックス構造が保存されます
カウントエリアの書き換え:プログラムによって自動的に割り当てられているため、ユーザーは気にする必要がありません。この領域は、現在の書き換え領域の数の数の数を記録し、書き換えエリアの自由な場所を見つけるために使用されます。
データ領域:Flashで保存する実際の値を保存します。各値のサイズと読み取りおよび書き込みオフセットアドレスは、インデックス領域のインデックス構造によって管理されます。
交換領域:アクティビティエリアがいっぱいの場合、アクティビティエリアのすべての有効なデータインデックスがアクティビティエリアとしてこの領域に転送され、同時に以前のアクティビティエリアをクリアし、次のアクティビティエリアとして使用します。
ステータス管理:
国家管理は、フラッシュを操作する際のマイクロコントローラーの停電など、マイクロコントローラーのさまざまな異常な現象に対処するために使用されます。