/****************************************************************************** 版权所有: 文件名称: flash_at45db321.c 文件版本: 01.01 创建作者: sunxi 创建日期: 2008-08-19 功能说明: SPI FLASH 仿真驱动程序。 其它说明: 修改记录: 仿真程序测试结果: flash_test begin! block_size=512,blocks=8192. flash_init ok(gf_flash=4703c710)! at45DB321Erase (us=2368315,ret=0)! at45DB321Erase verify ok(us=122126)! at45DB321Write ok(us=30182426)! at45DB321Write verify ok(us=118453)! at45DB321Erase (us=2485398,ret=0)! at45DB321Erase verify ok(us=121824)! at45DB321Write ok(us=65194996)! at45DB321Write verify ok(us=130880)! flash_test end! */ /*------------------------------- 头文件 -------------------------------------- */ #include #include "bspconfig.h" #include "ustimer.h" #include "flash.h" #include "gpio.h" #include "rt.h" /*------------------------------- 宏定义 -------------------------------------- */ //#if CFG_BSP_DEBUG #define _DEBUG_FLASH //#endif /*------------------------------ 全局变量 ------------------------------------- */ int gf_flash; /*------------------------------ 函数声明 ------------------------------------- */ /*------------------------------ 外部函数 ------------------------------------- */ /****************************************************************************** 函数名称: flash_init 函数版本: 01.01 创建作者: sunxi 创建日期: 2008-08-19 函数说明: flash初始化。 参数说明: 无 返回值: 成功返回0. 修改记录: */ int flash_init(void) { int file_size; // 创建并打开文件 gf_flash = rt_file_open("/app/data/flash.bin",O_CREAT|O_RDWR,0); if(IS_ERR(gf_flash)) { gf_flash = 0; return -1; } // 检查文件长度是否正确 file_size = rt_file_getfile_size(gf_flash); if(file_size < 0) { rt_file_close(gf_flash, NULL); gf_flash = -1; return -2; } if(file_size == CFG_FLASH_SIZE) { return 0; } //如果文件长度不为0,说明FLASH被破坏,不修改内容,直接错误返回, //方便以后问题查找。 if(file_size != 0) { rt_file_close(gf_flash,NULL); gf_flash = 0; return -3; } // 如果文件长度为0,初始化FLASH 文件 if(flash_erase(0,CFG_FLASH_SIZE) != 0) { rt_file_close(gf_flash,NULL); gf_flash = 0; return -4; } return 0; } int flash_exit(void) { if(gf_flash >= 0) { rt_file_close(gf_flash,NULL); gf_flash = 0; } return 0; } /****************************************************************************** 函数名称: flash_read 函数版本: 01.01 创建作者: sunxi 创建日期: 2008-08-21 函数说明: 从FLASH中读出数据。 参数说明: offset(in):需要读的数据在FLASH中的偏移量,和length之和不能大于 CFG_FLASH_SIZE. buffer(out):读出数据的buffer。 length(in): 需要读出数据的长度,和offset之和不能大于CFG_FLASH_SIZE。 返回值: 成功返回0. 修改记录: */ int flash_read(uint32_t offset,unsigned char * buffer,uint32_t length) { off_t pos; int ret; if(gf_flash == 0) { return -1; } //检查参数 if(buffer == 0 || (offset + length) > CFG_FLASH_SIZE) { return -1; } if(length == 0) { return 0; } pos = offset; ret = rt_file_read(gf_flash,buffer,length,&pos); if(ret != length) { return -2; } return 0; } /****************************************************************************** 函数名称: flash_write 函数版本: 01.01 创建作者: sunxi 创建日期: 2008-08-21 函数说明: 将数据写入FLASH中。 参数说明: offset(in):需要写入的数据在FLASH中的偏移量,和length之和不能大于 CFG_FLASH_SIZE. buffer(in):写入数据的buffer。 length(in): 需要写入数据的长度,和offset之和不能大于CFG_FLASH_SIZE。 返回值: 成功返回0. 修改记录: */ int flash_write(uint32_t offset,unsigned char * buffer,uint32_t length) { off_t pos; int ret; if(gf_flash == 0) { return -1; } //检查参数 if(buffer == 0 || (offset + length) > CFG_FLASH_SIZE) { return -1; } if(length == 0) { return 0; } pos = offset; ret = rt_file_write(gf_flash,buffer,length,&pos); if(ret != length) { return -2; } return 0; } /****************************************************************************** 函数名称: flash_erase 函数版本: 01.01 创建作者: sunxi 创建日期: 2008-08-21 函数说明: 擦除FLASH中的指定区域。注意擦除是以页(CFG_FLASH_PAGE_SIZE)为单位 擦除的,为了保证用户指定的区域一定被擦除,实际擦除的长度可能大于指定 的长度,用户应小心处理这个问题。 参数说明: offset(in):需要擦除的页在FLASH中的偏移量,和length之和不能大于 CFG_FLASH_SIZE. length(in): 需要擦除的长度,和offset之和不能大于CFG_FLASH_SIZE。 返回值: 成功返回0. 修改记录: */ #define FLASH_ERASE_LENGTH (128*1024) int flash_erase(uint32_t offset,uint32_t length) { unsigned char *buf; off_t off; size_t len; int ret; if(gf_flash == 0) { return -1; } buf = rt_malloc(FLASH_ERASE_LENGTH); if(buf == NULL) { return -2; } memset(buf,-1,FLASH_ERASE_LENGTH); off = offset; while(length) { len = length>FLASH_ERASE_LENGTH ? FLASH_ERASE_LENGTH:length; length -= len; ret = rt_file_write(gf_flash,buf,len,&off); if(ret != len) { rt_free(buf); return -3; } } rt_free(buf); return 0; } /****************************************************************************** 函数名称: at45db321_sector_protection 函数版本: 01.01 创建作者: sunxi 创建日期: 2008-10-10 函数说明: 启用FLASH的扇区保护功能。 参数说明: 无。 返回值: 成功返回0. 修改记录: */ int at45db321_sector_protection(void) { return 0; } /*------------------------------ 内部函数 ------------------------------------- */ /*------------------------------ 测试函数 ------------------------------------- */ #ifdef _DEBUG_FLASH #define FLASH_BLOCK_SIZE CFG_FLASH_PAGE_SIZE int flash_test(void) { int ret; uint32_t i,j,block_size,blocks; uint32_t us0,us; unsigned int gTestBuf[FLASH_BLOCK_SIZE/sizeof(int)]; block_size = FLASH_BLOCK_SIZE; // blocks = CFG_FLASH_SIZE/FLASH_BLOCK_SIZE; blocks = 1; rt_printf("flash_test begin!\r\n"); rt_printf("block_size=%d,blocks=%d.\r\n",block_size,blocks); // 初始化 if(gf_flash == 0) { ret = flash_init(); if(ret != 0) { rt_printf("flash_init error(ret=%d)!\r\n" ,ret); return -1; } } rt_printf("flash_init ok(gf_flash=%p)!\r\n",gf_flash); //擦除整个flash。 us0 = ustimer_get_origin(); ret = flash_erase(0,blocks*block_size); us = ustimer_get_duration(us0); rt_printf("at45DB321Erase (us=%d,ret=%d)!\r\n",us,ret); //确认擦除OK us0 = ustimer_get_origin(); for(i=0;i