文章目录
一种基于EEPROM存储结构的微型数据库
1. 介绍
DBS(database)是一种基于EEPROM存储结构的微型数据库,此数据库的设计目的是解决数据存储过程中发生异常而导致系统发生严重错误。使用一个结构体数组数据结构实现数据存储、数据管理、数据应用。
2. 设计思想:
1. 构建数据库
2. 初始化两段地址,将数据循环逐个写入数据库
3. a段数据自校验,b段数据校验
当a/b两段数据校验都成功,则返回成功标志
当a/b两段数据校验都失败,则返回失败标志
当a段数据校验成功,b段数据校验失败,则使用a段数据覆盖b段数据
当b段数据校验成功,a段数据校验失败,则使用b段数据覆盖a段数据
3. 构建数据库结构体成员
typedef struct
{
INT32U pk;
INT32U offset;
INT8U permission;
INT8U lock;
INT16U length;
INT8U *pdata;
} DBS_TABLE_ITEM;
4. 封装数据库
volatile DBS_TABLE_ITEM dbs_par_format[] =
{
// pk //offset //permission //lock //length // *pdata
{dbs_par_pk_crc, 0, 0x10, 0, 2, (INT8U *)dbs_parinit_crc},
{dbs_par_pk_isinit, 2, 0x10, 0, 1, (INT8U *)dbs_parinit_isinit},
{dbs_par_pk_value1, 3, 0x10, 0, 1, (INT8U *)dbs_parinit_value1},
{dbs_par_pk_value2, 4, 0x10, 0, 1, (INT8U *)dbs_parinit_value2},
{dbs_par_pk_value3, 5, 0x10, 0, 1, (INT8U *)dbs_parinit_value3},
{dbs_par_pk_value4, 6, 0x10, 0, 1, (INT8U *)dbs_parinit_value4},
{dbs_par_pk_value5, 7, 0x10, 0, 1, (INT8U *)dbs_parinit_value5}
}
5. 初始化EEPROM数据库
volatile DBS_TABLE_ITEM dbs_par_format[] =
{
uint32_t Dbs_initParTable()
{
uint32_t counter = 0;
uint32_t n = 0;
uint16_t data = 0;
uint8_t temp0 = 0;
uint8_t temp1 = 0;
Epm_readData(dbs_par_amemstart + dbs_par_format[dbs_par_pk_isinit].offset, &temp0);
Epm_readData(dbs_par_bmemstart + dbs_par_format[dbs_par_pk_isinit].offset, &temp1);
if ((temp0 != 0X5A) && (temp1 != 0x5A))
{
for (counter = 0; counter < dbs_par_rows; counter++)
{
for (n = 0; n < dbs_par_format[counter].length; n++)
{
dbs_par_memory[dbs_par_format[counter].offset + n] = *(dbs_par_format[counter].pdata + n);
}
}
dbs_par_memory[dbs_par_format[dbs_par_pk_isinit].offset] = 0X5A;
data = Crc_cal((uint8_t *)(dbs_par_memory + 2), dbs_par_memsize - 2);
dbs_par_memory[0] = (uint8_t)(data & 0XFF);
dbs_par_memory[1] = (uint8_t)((data >> 8) & 0XFF);
for (counter = 0; counter < dbs_par_memsize; counter++)
{
Epm_wrtieData(dbs_par_amemstart + counter, dbs_par_memory[counter]);
Epm_wrtieData(dbs_par_bmemstart + counter, dbs_par_memory[counter]);
}
}
for (counter = 0; counter < dbs_par_memsize; counter++)
{
Epm_readData(dbs_par_amemstart + counter, (uint8_t *)(dbs_par_memory + counter));
}
data = Crc_cal((uint8_t *)(dbs_par_memory + 2), dbs_par_memsize - 2);
if (((uint8_t)(data & 0XFF) == dbs_par_memory[0]) && ((uint8_t)((data >> 8) & 0XFF) == dbs_par_memory[1]))
{
temp0 = 1;
}
else
{
temp0 = 0;
}
for (counter = 0; counter < dbs_par_memsize; counter++)
{
Epm_readData(dbs_par_bmemstart + counter, (uint8_t *)(dbs_par_memory + counter));
}
data = Crc_cal((uint8_t *)(dbs_par_memory + 2), dbs_par_memsize - 2);
if (((uint8_t)(data & 0XFF) == dbs_par_memory[0]) && ((uint8_t)((data >> 8) & 0XFF) == dbs_par_memory[1]))
{
temp1 = 1;
}
else
{
temp1 = 0;
}
if ((temp0 == 1) && (temp1 == 1))
{
return 1;
}
else if ((temp0 != 1) && (temp1 != 1))
{
return 0;
}
else if ((temp0 == 1) && (temp1 != 1))
{
for (counter = 0; counter < dbs_par_memsize; counter++)
{
Epm_readData(dbs_par_amemstart + counter, (uint8_t *)(dbs_par_memory + counter));
}
for (counter = 0; counter < dbs_par_memsize; counter++)
{
Epm_wrtieData(dbs_par_bmemstart + counter, dbs_par_memory[counter]);
}
return 1;
}
else if ((temp0 != 1) && (temp1 == 1))
{
for (counter = 0; counter < dbs_par_memsize; counter++)
{
Epm_readData(dbs_par_bmemstart + counter, (uint8_t *)(dbs_par_memory + counter));
}
for (counter = 0; counter < dbs_par_memsize; counter++)
{
Epm_wrtieData(dbs_par_amemstart + counter, dbs_par_memory[counter]);
}
return 1;
}
}
6. 写入数据库操作
uint32_t Dbs_setParValue(uint32_t pk, uint8_t *data, uint32_t length)
{
uint32_t counter = 0;
uint16_t temp = 0;
uint8_t value = 0;
if (pk >= dbs_par_rows)
{
return 0;
}
if (dbs_par_format[pk].lock == 1)
{
return 0;
}
if (dbs_par_format[pk].permission == 0x20)
{
return 0;
}
if (dbs_par_format[pk].length < length)
{
return 0;
}
/* 写入数据 */
if (length == 0)
{
length = dbs_par_format[pk].length;
for (counter = 0; counter < length; counter++)
{
dbs_par_memory[dbs_par_format[pk].offset + counter] = 0x00;
Epm_wrtieData(dbs_par_amemstart + dbs_par_format[pk].offset + counter, 0x00);
Epm_wrtieData(dbs_par_bmemstart + dbs_par_format[pk].offset + counter, 0x00);
}
}
else
{
for (counter = 0; counter < length; counter++)
{
dbs_par_memory[dbs_par_format[pk].offset + counter] = *(data + counter);
Epm_wrtieData(dbs_par_amemstart + dbs_par_format[pk].offset + counter, *(data + counter));
Epm_wrtieData(dbs_par_bmemstart + dbs_par_format[pk].offset + counter, *(data + counter));
}
if (dbs_par_format[pk].length > length)
{
dbs_par_memory[dbs_par_format[pk].offset + length] = 0x00;
Epm_wrtieData(dbs_par_amemstart + dbs_par_format[pk].offset + length, 0x00);
Epm_wrtieData(dbs_par_bmemstart + dbs_par_format[pk].offset + length, 0x00);
}
}
temp = Crc_cal((uint8_t *)(dbs_par_memory + 2), dbs_par_memsize - 2);
dbs_par_memory[0] = (uint8_t)(temp & 0XFF);
dbs_par_memory[1] = (uint8_t)((temp >> 8) & 0XFF);
Epm_wrtieData(dbs_par_amemstart + 0, (uint8_t)(temp & 0XFF));
Epm_wrtieData(dbs_par_amemstart + 1, (uint8_t)((temp >> 8) & 0XFF));
Epm_wrtieData(dbs_par_bmemstart + 0, (uint8_t)(temp & 0XFF));
Epm_wrtieData(dbs_par_bmemstart + 1, (uint8_t)((temp >> 8) & 0XFF));
return 1;
}
7. 从数据库读出操作
uint32_t Dbs_getParValue(uint32_t pk, INT8U *data, uint32_t *length)
{
uint32_t counter = 0;
if (pk >= dbs_par_rows)
{
return 0;
}
if (dbs_par_format[pk].lock == 1)
{
return 0;
}
if (dbs_par_format[pk].permission == 0x30)
{
return 0;
}
*length = dbs_par_format[pk].length;
for (counter = 0; counter < dbs_par_format[pk].length; counter++)
{
*(data + counter) = dbs_par_memory[dbs_par_format[pk].offset + counter];
}
return 1;
}
8. 基于STM32F103硬件平台的源码获取
链接: 源码获取地址.