Use flash para simular a experiência do usuário da eeprom
void ee_flashInit() : Formato Flash, apenas o flash formatado pode usar as duas funções da API a seguir.ee_uint8 ee_readDataFromFlash() : Leia dadosee_uint8 ee_writeDataToFlash(); : Escreva dadosvariableLists enum para ler e escrever dados no flash através desta tabelaPrimeiro insira o arquivo de cabeçalho e preencha as quatro macros integralmente de acordo com os comentários
SECTOR_SIZE : o tamanho da capacidade de um setor (a unidade de armazenamento mínima do flash) no momento flashee_flashWrite : Flash Write Operação Driver Nome da Funçãoee_flashRead : flash Leia o nome do driver da operação Nomeee_flashEraseASector : Flash apaga um setor (a unidade de memória mínima do flash) Nome da função do driverMacros preenchíveis (nenhum enchimento não afeta a operação da função)
BLOCk_SECTOR_NUM : Quantos setores existem em um bloco de flash?Duas macros especiais:
SECTORS(x) : retorna o tamanho total do setor xBLOCKS(x) : retorna o tamanho total do bloco x Para usar essa macro, você precisa preencher o macro BLOCk_SECTOR_NUM com antecedência. As duas macros acima são usadas principalmente para transferir parâmetros da função ee_flashInit() para facilitar o uso de endereços flash.
Exemplo:
// 首先在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 );
}O flash só pode transformar 1 em 0 e só pode transformar 0 em 1, apagando um setor inteiro (a estrutura mínima de armazenamento do flash). Portanto, se um endereço escrito for escrito, se for escrito novamente, ele inevitavelmente causará o bit que se tornou 0 a se tornar 1, resultando na invalidação dos dados.
A idéia deste programa é escrever os dados que você deseja reescrever para a área que não foi escrita posteriormente. Os dados gravados antes serão invalidados e os dados escritos mais recentes serão considerados válidos. Aguarde até que toda a área esteja cheia, transfira os dados válidos para outra área e depois apague toda a área atual.
O diagrama de estrutura interna do Flash implementado pelo programa:

Depois de executar o flash de formatação void ee_flashInit() , o layout do flash formatado é mostrado na figura acima.
Área de índice total: contém duas áreas, área de índice e área de reescrita
Área do índice : a estrutura do índice usada para armazenar cada dados. A posição do endereço de cada estrutura de índice é fixa. Por exemplo, o endereço dos dados nº 1 é 0x00, então o endereço dos dados nº 2 é 0x08. O usuário pode especificar o tamanho da área de índice. Para a especificação de tamanho, consulte a seguinte fórmula: o número de dados que podem ser armazenados na área de índice = o número total de bytes na área de índice/8
/* 数据索引结构 */
typedef struct
{
/* 当前数据状态 */
ee_uint16 dataStatus ;
/* 当前数据大小 */
ee_uint16 dataSize ;
/* 当前数据在数据区的地址(相对于dataStartAddr的偏移地址) */
ee_uint16 dataAddr ;
/* 当前数据被重写的地址(相对于overwriteAddr的偏移地址),默认为0xFFFF */
ee_uint16 dataOverwriteAddr ;
} ee_dataIndex ;Área de reescrita : quando os dados na área do índice de dados são reescritos, a estrutura do índice de reescrita é salva na área atual
Reescrever área de contagem : alocada automaticamente pelo programa e o usuário não precisa se importar. Esta área registra quantas vezes a área de reescrita atual foi gravada e é usada para localizar a localização gratuita da área de reescrita.
Área de dados: salve o valor real que armazenamos no flash. O tamanho e o endereço de lida e gravação de cada valor são gerenciados pela estrutura do índice da área de índice.
Área de troca : quando a área de atividade estiver cheia, todos os índices de dados válidos da área de atividade são transferidos para essa área como área de atividade e, ao mesmo tempo, limpe a área de atividade anterior e use -a como a próxima área de atividade.
Gerenciamento de status :
O gerenciamento de estado é usado para lidar com vários fenômenos anormais de microcontroladores, como a falta de energia do microcontrolador ao operar o flash.