/****************************************************************************** 版权所有: 文件名称: e2prom_emu.c 文件版本: 01.01 创建作者: sunxi 创建日期: 2012-07-13 功能说明: e2prom仿真程序。 其它说明: 修改记录: */ /*------------------------------- 头文件 -------------------------------------- */ #include "bspconfig.h" #include "i2c.h" #include "ustimer.h" #include "gpio.h" #include "e2prom.h" #include "rt.h" /*------------------------------- 宏定义 -------------------------------------- */ #if CFG_BSP_DEBUG #define _DEBUG_E2PROM #endif /*------------------------------ 全局变量 ------------------------------------- */ int gf_e2prom; /*------------------------------ 函数声明 ------------------------------------- */ int e2prom_erase(uint32_t offset,uint32_t length); /*------------------------------ 外部函数 ------------------------------------- */ /****************************************************************************** 函数名称: e2prom_init 函数版本: 01.01 创建作者: sunxi 创建日期: 2008-08-06 函数说明: e2prom初始化。 参数说明: 无 返回值: 成功返回0. 修改记录: */ int e2prom_init(void) { int len; // 创建并打开文件 gf_e2prom = rt_file_open("/app/data/e2prom.bin", O_CREAT|O_RDWR, 0); if(IS_ERR(gf_e2prom)) { printf("e2prom file open err!\r\n"); return -1; } // 检查文件长度是否正确 len = rt_file_getfile_size(gf_e2prom); if(len < 0) { rt_file_close(gf_e2prom, 0); gf_e2prom = -1; return -2; } if(len == CFG_E2PROM_SIZE) { return 0; } //如果文件长度不为0,说明e2prom被破坏,不修改内容,直接错误返回, //方便以后问题查找。 if(len != 0) { rt_file_close(gf_e2prom, 0); gf_e2prom = -1; return -3; } // 如果文件长度为0,初始化e2prom 文件 if(e2prom_erase(0, CFG_E2PROM_SIZE) != 0) { rt_file_close(gf_e2prom, 0); gf_e2prom = -1; return -4; } return 0; } int e2prom_reinit(void) { if(gf_e2prom < 0) // 定值文件未打开 { // 创建并打开文件 gf_e2prom = rt_file_open("/app/data/e2prom.bin", O_CREAT|O_RDWR, 0); if(IS_ERR(gf_e2prom)) { return -1; } rt_err_clr(ERR_CODE_INIT_E2PROM, 0); } e2prom_erase(0, CFG_E2PROM_SIZE); return 0; } int e2prom_exit(void) { if(gf_e2prom >= 0) { rt_file_close(gf_e2prom, 0); gf_e2prom = -1; } return 0; } /****************************************************************************** 函数名称: e2prom_read 函数版本: 01.01 创建作者: sunxi 创建日期: 2008-08-06 函数说明: 从E2PROM中读出数据。 参数说明: offset(in):需要读的数据在E2PROM中的偏移量,和length之和不能大于 CFG_E2PROM_SIZE. buffer(out):读出数据的buffer。 length(in): 需要读出数据的长度,和offset之和不能大于CFG_E2PROM_SIZE。 返回值: 成功返回0. 修改记录: */ int e2prom_read(uint32_t offset, unsigned char *buffer, uint32_t length) { off_t pos; int ret; if(gf_e2prom < 0) { return -1; } //检查参数 if(buffer == 0 || (offset + length) > CFG_E2PROM_SIZE) { return -1; } if(length == 0) { return 0; } pos = offset; ret = rt_file_read(gf_e2prom, buffer, length, &pos); if(ret != (int)length) { return -2; } return 0; } /****************************************************************************** 函数名称: e2prom_write 函数版本: 01.01 创建作者: sunxi 创建日期: 2008-08-06 函数说明: 将数据写入E2PROM中。注意:E2PROM按页写的速度比按字节写的速度快, 所以如果应用程序将要写入的数据组织成 参数说明: offset(in):需要写入的数据在E2PROM中的偏移量,和length之和不能大于 CFG_E2PROM_SIZE. buffer(in):写入数据的buffer。 length(in): 需要写入数据的长度,和offset之和不能大于CFG_E2PROM_SIZE。 返回值: 成功返回0. 修改记录: */ int e2prom_write(uint32_t offset, unsigned char *buffer, uint32_t length) { off_t pos; int ret; if(gf_e2prom < 0) { return -1; } //检查参数 if(buffer == 0 || (offset + length) > CFG_E2PROM_SIZE) { return -1; } if(length == 0) { return 0; } pos = offset; ret = rt_file_write(gf_e2prom, buffer, length, &pos); if(ret != (int)length) { return -2; } return 0; } int e2prom_erase(uint32_t offset, uint32_t length) { unsigned char *buf; off_t off; size_t len; int ret; if(gf_e2prom < 0) { return -1; } buf = rt_malloc(CFG_E2PROM_SIZE); if(buf == NULL) { return -2; } memset(buf,-1,CFG_E2PROM_SIZE); off = offset; while(length) { len = length>CFG_E2PROM_SIZE ? CFG_E2PROM_SIZE:length; length -= len; ret = rt_file_write(gf_e2prom, buf, len, &off); if(ret != (int)len) { rt_free(buf); return -3; } } rt_free(buf); return 0; } /*------------------------------ 内部函数 ------------------------------------- */ /*------------------------------ 测试函数 ------------------------------------- */ #ifdef _DEBUG_E2PROM #include "rt.h" #define E2PROM_TEST_SIZE 1044 //必须是偶数 int e2prom_test(void) { int ret; unsigned long us0,us; unsigned long i,offset,length; static unsigned short buffer[E2PROM_TEST_SIZE/2]; rt_printf("e2prom_test start...\r\n"); offset = 0; while(offset < CFG_E2PROM_SIZE) { //写 length = (CFG_E2PROM_SIZE - offset) > E2PROM_TEST_SIZE ? E2PROM_TEST_SIZE : (CFG_E2PROM_SIZE - offset); for(i=0;i E2PROM_TEST_SIZE ? E2PROM_TEST_SIZE : (CFG_E2PROM_SIZE - offset); memset(buffer,0,E2PROM_TEST_SIZE); us0 = ustimer_get_origin(); ret = e2prom_read(offset,(unsigned char *)buffer,length); us = ustimer_get_duration(us0); rt_printf("e2prom_read:(offset=%lu,ret=%d,us=%lu)\r\n",offset,ret,us); if(ret != 0) { break; } //比较 for(i=0;i