| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 |
- /******************************************************************************
- 版权所有:
- 文件名称: 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 <string.h>
- #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<blocks;i++)
- {
- ret = flash_read(i*block_size,(unsigned char *)gTestBuf,block_size);
- if(ret != 0)
- {
- rt_printf("at45db321Read failure(i=%d,ret=%d)!\r\n",i,ret);
- return -1;
- }
- for(j=0;j<block_size/sizeof(int);j++)
- {
-
- if(gTestBuf[j] != 0xffffffff)
- {
- rt_printf("at45DB321Erase verify failure(i=%d,j=%d,data=0x%08x)!\r\n",i,j,gTestBuf[j]);
- return -1;
- }
- }
- }
- us = ustimer_get_duration(us0);
- rt_printf("at45DB321Erase verify ok(us=%d)!\r\n",us);
- //整个flash写0
- memset(gTestBuf,0,sizeof(gTestBuf));
- us0 = ustimer_get_origin();
- for(i=0;i<blocks;i++)
- {
- ret = flash_write(i*block_size,(unsigned char *)gTestBuf,block_size);
- if(ret != 0)
- {
- rt_printf("at45DB321Write failure(i=%d,ret=%d)!\r\n",i,ret);
- return -1;
- }
- }
- us = ustimer_get_duration(us0);
- rt_printf("at45DB321Write ok(us=%d)!\r\n",us);
- //检查整个flash是否全为0
- us0 = ustimer_get_origin();
- for(i=0;i<blocks;i++)
- {
- ret = flash_read(i*block_size,(unsigned char *)gTestBuf,block_size);
- if(ret != 0)
- {
- rt_printf("at45db321Read failure(i=%d,ret=%d)!\r\n",i,ret);
- return -1;
- }
-
- for(j=0;j<block_size/sizeof(int);j++)
- {
-
- if(gTestBuf[j] != 0)
- {
- rt_printf("at45DB321Write verify failure(i=%d,j=%d,data=0x%08x)!\r\n",i,j,gTestBuf[j]);
- return -1;
- }
- }
- }
- us = ustimer_get_duration(us0);
- rt_printf("at45DB321Write verify ok(us=%d)!\r\n",us);
- //擦除整个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<blocks;i++)
- {
- ret = flash_read(i*block_size,(unsigned char *)gTestBuf,block_size);
- if(ret != 0)
- {
- rt_printf("at45db321Read failure(i=%d,ret=%d)!\r\n",i,ret);
- return -1;
- }
-
- for(j=0;j<block_size/sizeof(int);j++)
- {
-
- if(gTestBuf[j] != 0xffffffff)
- {
- rt_printf("at45DB321Erase verify failure(i=%d,j=%d,data=0x%08x)!\r\n",i,j,gTestBuf[j]);
- return -1;
- }
- }
- }
- us = ustimer_get_duration(us0);
- rt_printf("at45DB321Erase verify ok(us=%d)!\r\n",us);
- //整个flash写测试数据
- us0 = ustimer_get_origin();
- for(i=0;i<blocks;i++)
- {
- //初始化写数据
- for(j=0;j<block_size/sizeof(int);j++)
- {
- gTestBuf[j] = i*block_size/sizeof(int) + j;
- }
- //写
- ret = flash_write(i*block_size,(unsigned char *)gTestBuf,block_size);
- if(ret != 0)
- {
- rt_printf("at45DB321Write failure(i=%d,ret=%d)!\r\n",i,ret);
- return -1;
- }
- }
- us = ustimer_get_duration(us0);
- rt_printf("at45DB321Write ok(us=%d)!\r\n",us);
- //读出并校验数据
- us0 = ustimer_get_origin();
- for(i=0;i<blocks;i++)
- {
- ret = flash_read(i*block_size,(unsigned char *)gTestBuf,block_size);
- if(ret != 0)
- {
- rt_printf("at45db321Read failure(i=%d,ret=%d)!\r\n",i,ret);
- return -1;
- }
-
- for(j=0;j<block_size/sizeof(int);j++)
- if(gTestBuf[j] != i*block_size/sizeof(int) + j)
- {
- rt_printf("at45DB321Write verify failure(i=%d,j=%d,data=0x%08x)!\r\n",i,j,gTestBuf[j]);
- return -1;
- }
- }
- us = ustimer_get_duration(us0);
- rt_printf("at45DB321Write verify ok(us=%d)!\r\n",us);
-
- rt_printf("flash_test end!\r\n\n");
-
- return 0;
- }
- #endif
|