赞
踩
主要思想就是将FLASH 分配一块区域给我们的管理机,然后用索引的方式累积写FLASH,中途不进行擦写,在存满整个分区时进行统一擦写,读取根据ID进行读取,并且加上了数据校验,异常回调。主要用于存储系统配置,运行记录等。支持多个存储管理机管理不同的区域。
- typedef struct{
- unsigned int PageSize; //页大小
- unsigned int Pages; //写的总页数
- unsigned int StartAddr; //起始地址
- unsigned int DriftAddr; //偏移地址需要大于四字节
- unsigned int Number; //总共有效条数
- unsigned char * Buffer; //数据缓冲区地址
- unsigned int ReadAddr; //读地址,用于节省查找时间提高效率
- unsigned int WriteAddr; //写地址,用于节省时间提高查找空区效率
- void (* Error_Handle)(FERROR err, unsigned char * src, unsigned int len);
- }FlashConfig;
PageSize:用户为该管理机提供的存储分区业大小。同时也最小擦除单位。
Pages:存储分区页大小。
StartAddr:存储分区起始地址。
DriftAddr:需要存储数据的数据宽度
Number:需要存储的数据条数,也就是最大ID,这里如果你相同类型的数据有多条有效数据,就通过ID来进行区分。打个比方:周一到周五的菜单,每天固定三个菜,要进行存储的话,就需要提供五组数据,那么日期就是ID,用来区分周几。
Buffer:这个是你数据的内存首地址,这个在后面不同的接口会有介绍
ReadAddr:读地址,由于查找最后一块有效数据地址随着分区的大小,查找时间会相应的变长,所以在系统上电初始化的时候将最后一块有效数据块首地址记录,之后就不用再从子分区0查找了,提高系统执行效率,这个保留在这,暂未实现,后面的版本会加入。
WriteAddr:写地址,与上面一样。
Error_Handle:错误回调,如未实现,请赋值为NULL
- void open_service()
- {
- //这里可提供线程安全防止中断flash操作,由close_service释放安全锁
- eeplog("%s", "open service\n");
- }
-
- void close_service()
- {
- eeplog("%s", "close service\n");
- }
-
-
- /**
- * @brief 写储存器接口。
- * @param addr:写首地址
- sd:写入的数据首地址
- len:写入的长度
- * @retval None
- */
- void write_flash(unsigned int addr, const unsigned char * sd, unsigned int len){
- unsigned short * pt = (unsigned short *)sd;
- HAL_FLASH_Unlock();
- for(int i = 0; i < len/2; i++)
- {
- HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, addr+i*2, *(pt+i));
- }
- HAL_FLASH_Lock();
- }
-
- /**
- * @brief 擦除储存器接口
- * @param addr:擦除地址
- * @param 擦写长度,暂时未用到,保留,接口默认擦除一页,
- * @retval None
- */
- void erase_flash(unsigned int addr, unsigned int len){
- uint32_t PageError = 0;
- FLASH_EraseInitTypeDef pEraseInit;
- pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
- pEraseInit.PageAddress = addr;
- pEraseInit.NbPages = 1;
- HAL_FLASH_Unlock();
- HAL_StatusTypeDef s = HAL_FLASHEx_Erase(&pEraseInit, &PageError);
- HAL_FLASH_Lock();
- }
-
- /**
- * @brief 读储存器接口.
- * @param addr:读起始地址
- sd:读数据缓存区首地址
- len:读的长度
- * @retval None
- */
- void read_flash(unsigned int addr, unsigned char * sd, unsigned int len){
- unsigned short * pt = (unsigned short *)sd;
- for(int i = 0; i < len / 2; i++){
- pt[i] = *((__IO uint16_t*)(addr+i*2));
- }
- }
erase_flash:这里的长度其实无效,这里需要提供的是擦除一页的接口,这里也许会有人说NAND Flash,最小擦除单位为1块,也就是64页,怎么办呢?这里你就需要在配置管理类的时候,将页数量配置为1,然后页大小不超过一块的大小就可以。
- /*********************************************************************************
- *Copyright(C) -
- *FileName: eeprom.c
- *Author: 我不是阿沸
- *Version: 6.1.0
- *Date: 2023.08.20
- *Description: 用于嵌入式系统保存数据至存储器,兼容大多数存储器,经内部算法优化,擦写寿命可达:正常寿命*100倍,这个取决于你分配的空间大小,空间越大寿命越长。
- *Others: 互斥需自己实现
-
- *History:
- 1.Date:2023/04/03
- Author:我不是阿沸
- Modification:增加自定义互斥接口,由用户实现
- 2.Date:2023/05/16
- Author:我不是阿沸
- Modification:修改相关接口实现方式
- 3.Date:2023/07/18
- Author:我不是阿沸
- Modification:修改读写数据实现方式
- 4.Date:2023/08/20
- Author:我不是阿沸
- Modification:删除冗余成分
- 4.Date:2023/010/24
- Author:我不是阿沸
- Modification:增加查找分区地址记录,只需上电查找一次,提高效率
- 5.其他修改
- **********************************************************************************/
-
- #include "eeprom.h"
-
- void open_service()
- {
- //HAL_FLASH_Unlock();
- //这里可提供线程安全防止中断flash操作,由close_service释放安全锁
- eeplog("%s", "open service\n");
- }
-
-
- void close_service()
- {
- eeplog("%s", "close service\n");
- //HAL_FLASH_Lock();
- }
-
-
- //ProgramGroup programGroups[10];
- /**
- * @brief 写储存器接口。
- * @param addr:写首地址
- sd:写入的数据首地址
- len:写入的长度
- * @retval None
- */
- void write_flash(epmu32 addr, const epmu8 * sd, epmu32 len){
- //注意,这里传入的sd必须是偶数地址,不然在转换为16位时会出现字节对齐的情况
- uint64_t * pt = (uint64_t *)sd;
- HAL_FLASH_Unlock();
- //rt_kprintf("\nlen:%d\n", len);
- Flash_If_Write((uint8_t*)sd, addr, len);
- // for(int i = 0; i < len/8; i++)
- // {
- // HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr+i*8, *(pt+i));
- // }
- HAL_FLASH_Lock();
- }
-
-
- /**
- * @brief 擦除储存器接口
- * @param addr:擦除地址
- * @retval None
- */
- void erase_flash(epmu32 addr, epmu32 len){
-
- epmu32 PageError = 0;
- //FLASH_EraseInitTypeDef pEraseInit;
- HAL_FLASH_Unlock();
-
-
- Flash_If_Erase(addr);
-
- HAL_FLASH_Lock();
- }
-
-
- /**
- * @brief 读储存器接口.
- * @param addr:读起始地址
- @param sd:读数据缓存区首地址
- @param len:读的长度
- * @retval None
- */
- void read_flash(epmu32 addr, epmu8 * sd, epmu32 len){
-
- uint64_t * pt = (uint64_t *)sd;
- // for(int i = 0; i < len / 8; i++){
- // pt[i] = *((__IO uint64_t*)(addr+i*8));
- // }
- Flash_If_Read(sd, addr, len);
- }
-
-
- /**
- * @brief 校验数据接口
- * @param src:需要校验的数据首地址
- len:要校验的长度
- * @retval epmbool:返回校验成功或者失败
- */
- epmbool check_flash(epmu8 *src, epmu32 len){
- eeplog("start check data\n");
- epmu32 src_ckeck = epm_crc32(src, len -4);
- epmu32 dec_ckeck = epmu32_buffer_max((src+ len - 4));
- if(src_ckeck != dec_ckeck) {
- eeplog("data check error!\n");
- return EPMFALSE;
- }
- eeplog("data check success!\n");
- return EPMTRUE;
- }
-
- /**
- * @brief 判断第一块存储区是否进行初始化
- * @param flg:分区信息
- * @retval epmbool:true:存储区已初始化 false:未初始化
- */
- epmbool isinit_first_block(FlashConfig flg){
- epmu8 ch[10];
- read_flash(flg.start_addr, ch, 8);
- int i = 0;
- for(; i < 8; i++){
- if(ch[i] != 0xA5) break;
- }
- if(i != 8) return EPMFALSE;
- return EPMTRUE;
-
- }
-
- /**
- * @brief 第一块存储区初始化,写入初始化信息
- * @param flg:分区信息
- * @retval epmbool:true:存储区初始化成功 false:分区损坏
- */
- epmbool first_block_init(FlashConfig flg){
- eeplog("Is check epm init?\n");
- epmu8 ch[10];
- memset(ch, 0xA5, 8);
-
- eeplog("Sector not initialized, about to initialize...\n");
- for(int m = 0; m < flg.pages; m++){
- erase_flash(flg.start_addr+m*flg.page_size, flg.page_size);
- }
- write_flash(flg.start_addr, ch, 8);
- read_flash(flg.start_addr, ch, 8);
- for(int i = 0; i < 8; i++){
- if(ch[i] != 0xA5) {
- eeplog("Sector initialization default!!!!!!!!!!!!!!!\n");
- return EPMFALSE;
- }
- }
- eeplog("Sector initialization successful\n");
- return EPMTRUE;
- }
-
-
- /**
- * @brief 校验flash读出的数据是否为空
- * @param data:需要校验的数据首地址
- len:数据的长度
- * @retval epmbool:未被写入过数据返回true
- */
- epmbool is_eeprom_null(FlashConfig flg, epmu8 * data, int len){
- int n = 0;
- eeplog("Is flash empty?\n");
- for(n = 0; n < len; n++){
- if(data[n] != 0xff){
- eeplog("flash isn`t empty\n");
- return EPMFALSE;
- }
- }
- eeplog("flash is empty\n");
- return EPMTRUE;
- }
-
-
-
- /**
- * @brief CRC32校验
- * @param data:需要校验的数据首地址
- len:数据的长度
- * @retval CRC32校验值
- */
- #define POLY 0xEDB88320UL
- epmu32 epm_crc32(epmu8 * data, epmu32 datalen)
- {
- const uint8_t *bytes = data;
- uint32_t crc = 0xFFFFFFFFUL;
-
- // 循环处理每个字节
- for (size_t i = 0; i < datalen; i++) {
- crc ^= bytes[i]; // 把当前字节与 crc 的低 8 位进行异或操作
-
- // 处理当前字节的 8 位,每次处理一位
- for (int j = 0; j < 8; j++) {
- if (crc & 1) { // 如果 crc 的最低位为 1,则右移并与多项式除数进行异或操作
- crc = (crc >> 1) ^ POLY;
- } else { // 否则,只右移一个比特位
- crc >>= 1;
- }
- }
- }
-
- return ~crc; // 取反操作得到最终结果
- }
-
- /**
- * @brief 初始化分区信息
- * @param 分区信息指针
- * @param 起始地址
- * @param 偏移地址,子存储区大小
- * @param 有效数据条数
- * @param 分区占用存储器页数
- * @param 存储器叶大小
- * @param 数据缓存区指针
- * @param 错误回调接口
- * @retval none
- */
- void eeprom_init(FlashConfig * flg, epmu32 start_addr, epmu8 drift_addr, epmu16 number, epmu16 pages, epmu32 page_size, epmu8 * buffer, error_handle error)
- {
- flg->find_flag = EPMFALSE;
- flg->find_addr = start_addr;
- flg->start_addr = start_addr;
- flg->drift_addr = drift_addr;
- flg->number = number;
- flg->pages = pages;
- flg->page_size = page_size;
- flg->buffer = buffer;
- flg->error = error;
- }
-
-
- /**
- * @brief 顺序查找flash空区
- * @param flg:分区信息
- * @retval int:返回空区首地址
- */
- epmu32 epm_seq_search_addr(FlashConfig * flg){
- int findCount = flg->page_size * flg->pages / (flg->drift_addr+4);
-
- epmu32 start_addr = flg->start_addr;
- epmu32 find_addr = start_addr;
- epmu8 data[200];
- int i;
-
- open_service();
- eeplog("epy find start!\n");
- //这里注意,首地址为初始化校验区,无有效数据
-
- if(flg->find_flag == EPMFALSE)
- {
- epmbool bl = isinit_first_block(*flg);
- if(bl == EPMFALSE) {
- close_service();
- flg->find_flag = EPMTRUE;
- flg->find_addr = start_addr;
- return start_addr;
- }
-
- for(i = 1; i < findCount; i++){
- read_flash(start_addr + i*(flg->drift_addr+4), data, flg->drift_addr+4);
-
- if(is_eeprom_null(*flg, data, flg->drift_addr+4) == EPMTRUE){
- find_addr = start_addr + i*(flg->drift_addr+4);
- eeplog("epy find end, return emp addr!\n");
- break;
- }
- }
- if(i == findCount)
- {
- find_addr = start_addr + findCount*(flg->drift_addr+4);
- }
- else
- {
-
- }
- flg->find_addr = find_addr;
- flg->find_flag = EPMTRUE;
-
- }
- close_service();
- return flg->find_addr;
- }
-
- /**
- * @brief 写入数据
- * @param flg:分区信息
- data:需要写入的数据
- * @retval int:返回对应的空区首地址
- */
- FERROR epm_write_data(FlashConfig * flg, const epmu8 * data){
- epmu8 ch[200] = {0};
- epmu8 chb[200] = {0};
- epmu32 addr = flg->start_addr;
- int findCount = flg->page_size * flg->pages / (flg->drift_addr+4);
- addr = epm_seq_search_addr(flg);
-
- if(flg->find_addr >= flg->start_addr + findCount* (flg->drift_addr+4))
- {
- flg->find_addr = flg->start_addr;
- addr = flg->start_addr;
- }
-
- open_service();
- if(addr == flg->start_addr){
- epmbool b = first_block_init(*flg);
-
- if(b == EPMFALSE){
- flg->error(InitError, NULL, 0);
-
- close_service();
- return InitError;
- }
-
- for(int i = 0; i < flg->number; i++){
- memcpy(ch, flg->buffer+i*flg->drift_addr, flg->drift_addr);
-
- epmu32 src_ckeck = epm_crc32(ch, flg->drift_addr);
-
- buffer_epmu32_max(src_ckeck, (ch+flg->drift_addr));
-
- write_flash(addr +(i+1)*(flg->drift_addr+4), ch, flg->drift_addr+4);
-
- //这里可适当加入回读错误处理
- }
- flg->find_addr = addr + (flg->drift_addr+4)*(flg->number+1);
- eeplog("addr:%08X\n", addr);
- close_service();
- return Success;
- }
-
- memcpy(ch, data, flg->drift_addr);
- epmu32 src_ckeck = epm_crc32(ch, flg->drift_addr);
- buffer_epmu32_max(src_ckeck, (ch+flg->drift_addr));
-
-
-
- write_flash(addr, ch, flg->drift_addr+4);
- read_flash(addr, chb, flg->drift_addr+4);
- flg->find_addr += (flg->drift_addr+4);
-
- if(flg->find_addr >= flg->start_addr + findCount* (flg->drift_addr+4))
- {
- flg->find_addr = flg->start_addr;
- }
-
- int m = 0;
- for( ; m < flg->drift_addr+4; m++){
- if(chb[m] != ch[m]){
- break;
- }
- }
-
- if(flg->drift_addr+4 == m)
- {
-
- close_service();
- eeplog("%s", "data write succse");
- return Success;
- }
- else
- {
- eeplog("%s", "data write error, sd have bad block");
- }
- close_service();
- eeplog("%s", "data write error, sd have bad block");
- return WriteError;
- }
-
-
-
- /**
- * @brief 读出数据
- * @param flg:分区信息
- data:需要写入的数据
- * @retval NONE
- */
- FERROR epm_read_data(FlashConfig *flg, epmu8 * data){
-
- epmu32 addr = epm_seq_search_addr(flg);
- epmu8 ch[200];
-
- if(flg->drift_addr+4 >= 200) return IndexError;
-
- if(addr == flg->start_addr){
- flg->error(Empty, NULL, 0);
- return Empty;
- }
- else{
- addr -= (flg->drift_addr+4);
- open_service();
-
- read_flash(addr, ch, flg->drift_addr+4);
- close_service();
- if(check_flash(ch, flg->drift_addr+4) == EPMFALSE){
- flg->error(ReadError, NULL, 0);
- return ReadError;
- }
- memcpy(data, ch, flg->drift_addr);
- }
-
-
- return Success;
- }
-
-
- /**
- * @brief 查询全部数据 ,并且通过ID写入对应的缓冲区
- * @param flg:分区信息
- * @retval void
- */
- void epm_select_all_data(FlashConfig * flg)
- {
- int findCount = (flg->page_size * flg->pages) / (flg->drift_addr+4);
- epmu32 start_addr = flg->start_addr;
- int i, n;
- epmu8 ch[200] = {0};
-
- if(flg->drift_addr+4 >= 200) return;
-
- open_service();
-
- epmbool b = isinit_first_block(*flg);
-
- if(b == EPMFALSE){
- flg->error(InitError, NULL, 0);
- close_service();
- return;
- }
- for(i = 1; i < findCount; i++){
- read_flash(start_addr + i*(flg->drift_addr+4), ch, flg->drift_addr+4);
- if(is_eeprom_null(*flg, ch, flg->drift_addr+4) == EPMTRUE)
- {
- break;
- }
-
- if(check_flash(ch, flg->drift_addr+4) == EPMFALSE){
- if(flg->error != NULL)
- {
- flg->error(CheckError, ch, flg->drift_addr);
- }
- continue;
- }
-
- int id = *((epmu16*)ch);
- if(id >= flg->number) id = flg->number - 1;
- for(n = 0; n < flg->drift_addr; n++){
- flg->buffer[id*flg->drift_addr+n] = ch[n];
- }
- }
- close_service();
- return;
- }
-
-
- /**
- * @brief 通过索引查询多条数据数据
- * @param flg:分区信息
- start:开始条数,这里换算成地址为:flg->drift_addr* start
- num:查寻条数
- * @retval int:返回对应的空区首地址
- */
- void epm_select_data(FlashConfig * flg, epmu32 start, epmu32 num)
- {
- epmu32 start_addr = flg->start_addr;
-
- epmu8 ch[200] = {0};
- if(flg->drift_addr+ 4 >= 200) return;
-
- open_service();
- for(int i = 1; i < num && i < flg->number; i++){
- read_flash(start_addr + (i+start)*(flg->drift_addr+4), ch, flg->drift_addr+4);
- if(check_flash(ch, flg->drift_addr+4) == EPMFALSE){
- flg->error(CheckError, ch, flg->drift_addr);
- continue;
- }
- for(int n = 0; n < flg->drift_addr; n++){
- flg->buffer[(i-1)*flg->drift_addr+n] = ch[n];
- }
- }
- close_service();
- return;
- }
-
-
eeprom.h:
- /*********************************************************************************
- *Copyright(C) -
- *FileName: eeprom.h
- *Author: 我不是阿沸
- *Version: 6.1.0
- *Date: 2023.08.20
- *Description: 用于嵌入式系统保存数据至存储器,兼容大多数存储器,经内部算法优化,擦写寿命可达:正常寿命*100倍,这个取决于你分配的空间大小,空间越大寿命越长。
- *Others: 互斥需自己实现
-
- *History:
- 1.Date:2023/04/03
- Author:我不是阿沸
- Modification:增加自定义互斥接口,由用户实现
- 2.Date:2023/05/16
- Author:我不是阿沸
- Modification:修改相关接口实现方式
- 3.Date:2023/07/18
- Author:我不是阿沸
- Modification:修改读写数据实现方式
- 4.Date:2023/08/20
- Author:我不是阿沸
- Modification:删除冗余成分
- 4.Date:2023/010/24
- Author:我不是阿沸
- Modification:增加查找分区地址记录,只需上电查找一次,提高效率
- 5.其他修改
- **********************************************************************************/
-
- #ifndef __EEPROMS_H
- #define __EEPROMS_H
-
- #include <stdio.h>
- #include "if_flash.h"
- #include <stdio.h>
- #include <string.h>
-
-
-
- //#define __EEPDEBUG
- #ifdef __EEPDEBUG
- #define eeplog(format, ...) \
- rt_kprintf("[%s:%d->%s]:"format, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
- #else
- #define eeplog(format, ...)
- #endif
-
- #define FLASH_PAGE_STEP FLASH_PAGE_SIZE
- #define START_ADDRESS (uint32_t)0x08000000
-
- #define epmu32_buffer_min(x) (epmu32)(*((x+3))<<24 | *((x)+2)<<16 | *((x)+1)<<8 | *(x))
- #define epmu32_buffer_max(x) (epmu32)(*(x)<<24 | *((x)+1)<<16 | *((x)+2)<<8 | *((x)+3))
-
- #define epmu16_buffer_min(x) (epmu16)(*((x)+1)<<8 | *(x))
- #define epmu16_buffer_max(x) (epmu16)(*(x)<<8 | *(x+1))
-
- #define buffer_epmu32_min(x, buf) {(buf)[0] = (x); (buf)[1] = (x)>>8; (buf)[2] = (x)>>16; (buf)[3] = (x)>>24;}
- #define buffer_epmu32_max(x, buf) {(buf)[3] = (x); (buf)[2] = (x)>>8; (buf)[1] = (x)>>16; (buf)[0] = (x)>>24;}
-
- #define buffer_epmu16_min(x, buf) {(buf)[0] = (x); (buf)[1] = (x)>>8;}
- #define buffer_epmu16_max(x, buf) {(buf)[1] = (x); (buf)[0] = (x)>>8;}
-
-
- typedef unsigned int epmu32;
- typedef unsigned short epmu16;
- typedef unsigned char epmu8;
-
-
-
- typedef enum flash_error{
- Success,
- WriteError,
- ReadError,
- IndexError,
- CheckError,
- InitError,
- Empty
- }FERROR;
-
-
- typedef enum{
- EPMFALSE,
- EPMTRUE
- }epmbool;
-
-
- typedef void (* error_handle)(FERROR err, epmu8 * src, epmu32 len);
-
-
-
- typedef struct{
- epmu32 page_size; //页大小
- epmu16 pages; //写的总页数
- epmu32 start_addr; //起始地址
- epmu8 drift_addr; //偏移地址需要大于四字节
- epmu32 number; //总共有效条数
- epmu8 * buffer; //数据缓冲区地址
- epmu32 find_addr;
- epmbool find_flag;
- error_handle error;
- }FlashConfig;
-
- void eeprom_init(FlashConfig * flg, epmu32 start_addr, epmu8 drift_addr, epmu16 number, epmu16 pages, epmu32 page_size, epmu8 * buffer, error_handle error);
- epmu32 epm_seq_search_addr(FlashConfig * flg);
- void epm_select_data(FlashConfig * flg, epmu32 start, epmu32 num);
- epmu32 epm_crc32(epmu8 * data, epmu32 datalen);
- epmbool check_flash(epmu8 *src, epmu32 len);
- void erase_flash(epmu32 addr, epmu32 len);
- void write_flash(epmu32 addr, const epmu8 * sd, epmu32 len);
- void read_flash(epmu32 addr, epmu8 * sd, epmu32 len);
- FERROR epm_read_data(FlashConfig *flg, epmu8 * data);
- FERROR epm_write_data(FlashConfig * flg, const epmu8 * data);
- void epm_select_all_data(FlashConfig * flg);
-
- #endif
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
main.c
- #include "stdio.h"
- #include "eeprom.h"
-
-
- typedef struct
- {
- char id;
- char depth; //宽度
- short cmp;
- short angle;
-
- short temp; //温度
- short count; //执行次数
- short width; //间隔时间
- short lc ; //lc开关值
- unsigned int freq;
- int expand;
- int outi;
- int kp1;
- int ki1;
- int kd1;
- int power;
- int kp2;
- int ki2;
- int kd2;
- int outv;
- int kp3;
- int ki3;
- int kd3;
- int y1;
- int y2;
- int y3;
- int ts;
- int xx;
- }Preset;
-
- Preset preset;
-
- FlashConfig PresetCfg;
-
-
- void preset_config_ehandle(FERROR err, unsigned char * src, unsigned int len)
- {
- eeplog("preset_config_ehandle error:%d\n", err);
- }
-
-
- void printf_preset(Preset p)
- {
- eeplog("freq:%d,cmp:%d,angle:%d,expand:%d,temp:%d,count:%d,width:%d,depth:%d", p.freq, p.cmp, p.angle, p.expand, p.temp, p.count, p.width, p.depth);
- }
-
- epmbool write_preset(void)
- {
- //printf_preset(preset);
- epm_write_data(&PresetCfg, (unsigned char *)&preset);
- return EPMTRUE;
- }
-
-
- /**
- * @brief read_preset 读取预设组
- * @param
- * @retval bool:读取是否成功
- */
- epmbool read_preset(void)
- {
- epm_read_data(&PresetCfg, (unsigned char * )&preset);
- return EPMTRUE;
- }
-
-
-
-
- epmbool preset_config_init(void){
- eeplog("size:%d\n", sizeof(Preset));
- eeprom_init(&PresetCfg, 59*FLASH_PAGE_STEP + START_ADDRESS, sizeof(Preset), 1, 4,
- FLASH_PAGE_STEP, (unsigned char * )&preset, preset_config_ehandle);
- read_preset();
- printf_preset(preset);
- return EPMTRUE;
- }
-
-
-
-
-
-
如有疑问可以评论区留言,或者联系QQ:2227273007,另外附上eeprom的源文件:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。