flash_emu.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. /******************************************************************************
  2. 版权所有:
  3. 文件名称: flash_at45db321.c
  4. 文件版本: 01.01
  5. 创建作者: sunxi
  6. 创建日期: 2008-08-19
  7. 功能说明: SPI FLASH 仿真驱动程序。
  8. 其它说明:
  9. 修改记录: 仿真程序测试结果:
  10. flash_test begin!
  11. block_size=512,blocks=8192.
  12. flash_init ok(gf_flash=4703c710)!
  13. at45DB321Erase (us=2368315,ret=0)!
  14. at45DB321Erase verify ok(us=122126)!
  15. at45DB321Write ok(us=30182426)!
  16. at45DB321Write verify ok(us=118453)!
  17. at45DB321Erase (us=2485398,ret=0)!
  18. at45DB321Erase verify ok(us=121824)!
  19. at45DB321Write ok(us=65194996)!
  20. at45DB321Write verify ok(us=130880)!
  21. flash_test end!
  22. */
  23. /*------------------------------- 头文件 --------------------------------------
  24. */
  25. #include <string.h>
  26. #include "bspconfig.h"
  27. #include "ustimer.h"
  28. #include "flash.h"
  29. #include "gpio.h"
  30. #include "rt.h"
  31. /*------------------------------- 宏定义 --------------------------------------
  32. */
  33. //#if CFG_BSP_DEBUG
  34. #define _DEBUG_FLASH
  35. //#endif
  36. /*------------------------------ 全局变量 -------------------------------------
  37. */
  38. int gf_flash;
  39. /*------------------------------ 函数声明 -------------------------------------
  40. */
  41. /*------------------------------ 外部函数 -------------------------------------
  42. */
  43. /******************************************************************************
  44. 函数名称: flash_init
  45. 函数版本: 01.01
  46. 创建作者: sunxi
  47. 创建日期: 2008-08-19
  48. 函数说明: flash初始化。
  49. 参数说明: 无
  50. 返回值: 成功返回0.
  51. 修改记录:
  52. */
  53. int flash_init(void)
  54. {
  55. int file_size;
  56. // 创建并打开文件
  57. gf_flash = rt_file_open("/app/data/flash.bin",O_CREAT|O_RDWR,0);
  58. if(IS_ERR(gf_flash))
  59. {
  60. gf_flash = 0;
  61. return -1;
  62. }
  63. // 检查文件长度是否正确
  64. file_size = rt_file_getfile_size(gf_flash);
  65. if(file_size < 0)
  66. {
  67. rt_file_close(gf_flash, NULL);
  68. gf_flash = -1;
  69. return -2;
  70. }
  71. if(file_size == CFG_FLASH_SIZE)
  72. {
  73. return 0;
  74. }
  75. //如果文件长度不为0,说明FLASH被破坏,不修改内容,直接错误返回,
  76. //方便以后问题查找。
  77. if(file_size != 0)
  78. {
  79. rt_file_close(gf_flash,NULL);
  80. gf_flash = 0;
  81. return -3;
  82. }
  83. // 如果文件长度为0,初始化FLASH 文件
  84. if(flash_erase(0,CFG_FLASH_SIZE) != 0)
  85. {
  86. rt_file_close(gf_flash,NULL);
  87. gf_flash = 0;
  88. return -4;
  89. }
  90. return 0;
  91. }
  92. int flash_exit(void)
  93. {
  94. if(gf_flash >= 0)
  95. {
  96. rt_file_close(gf_flash,NULL);
  97. gf_flash = 0;
  98. }
  99. return 0;
  100. }
  101. /******************************************************************************
  102. 函数名称: flash_read
  103. 函数版本: 01.01
  104. 创建作者: sunxi
  105. 创建日期: 2008-08-21
  106. 函数说明: 从FLASH中读出数据。
  107. 参数说明:
  108. offset(in):需要读的数据在FLASH中的偏移量,和length之和不能大于
  109. CFG_FLASH_SIZE.
  110. buffer(out):读出数据的buffer。
  111. length(in): 需要读出数据的长度,和offset之和不能大于CFG_FLASH_SIZE。
  112. 返回值: 成功返回0.
  113. 修改记录:
  114. */
  115. int flash_read(uint32_t offset,unsigned char * buffer,uint32_t length)
  116. {
  117. off_t pos;
  118. int ret;
  119. if(gf_flash == 0)
  120. {
  121. return -1;
  122. }
  123. //检查参数
  124. if(buffer == 0 || (offset + length) > CFG_FLASH_SIZE)
  125. {
  126. return -1;
  127. }
  128. if(length == 0)
  129. {
  130. return 0;
  131. }
  132. pos = offset;
  133. ret = rt_file_read(gf_flash,buffer,length,&pos);
  134. if(ret != length)
  135. {
  136. return -2;
  137. }
  138. return 0;
  139. }
  140. /******************************************************************************
  141. 函数名称: flash_write
  142. 函数版本: 01.01
  143. 创建作者: sunxi
  144. 创建日期: 2008-08-21
  145. 函数说明: 将数据写入FLASH中。
  146. 参数说明:
  147. offset(in):需要写入的数据在FLASH中的偏移量,和length之和不能大于
  148. CFG_FLASH_SIZE.
  149. buffer(in):写入数据的buffer。
  150. length(in): 需要写入数据的长度,和offset之和不能大于CFG_FLASH_SIZE。
  151. 返回值: 成功返回0.
  152. 修改记录:
  153. */
  154. int flash_write(uint32_t offset,unsigned char * buffer,uint32_t length)
  155. {
  156. off_t pos;
  157. int ret;
  158. if(gf_flash == 0)
  159. {
  160. return -1;
  161. }
  162. //检查参数
  163. if(buffer == 0 || (offset + length) > CFG_FLASH_SIZE)
  164. {
  165. return -1;
  166. }
  167. if(length == 0)
  168. {
  169. return 0;
  170. }
  171. pos = offset;
  172. ret = rt_file_write(gf_flash,buffer,length,&pos);
  173. if(ret != length)
  174. {
  175. return -2;
  176. }
  177. return 0;
  178. }
  179. /******************************************************************************
  180. 函数名称: flash_erase
  181. 函数版本: 01.01
  182. 创建作者: sunxi
  183. 创建日期: 2008-08-21
  184. 函数说明: 擦除FLASH中的指定区域。注意擦除是以页(CFG_FLASH_PAGE_SIZE)为单位
  185. 擦除的,为了保证用户指定的区域一定被擦除,实际擦除的长度可能大于指定
  186. 的长度,用户应小心处理这个问题。
  187. 参数说明:
  188. offset(in):需要擦除的页在FLASH中的偏移量,和length之和不能大于
  189. CFG_FLASH_SIZE.
  190. length(in): 需要擦除的长度,和offset之和不能大于CFG_FLASH_SIZE。
  191. 返回值: 成功返回0.
  192. 修改记录:
  193. */
  194. #define FLASH_ERASE_LENGTH (128*1024)
  195. int flash_erase(uint32_t offset,uint32_t length)
  196. {
  197. unsigned char *buf;
  198. off_t off;
  199. size_t len;
  200. int ret;
  201. if(gf_flash == 0)
  202. {
  203. return -1;
  204. }
  205. buf = rt_malloc(FLASH_ERASE_LENGTH);
  206. if(buf == NULL)
  207. {
  208. return -2;
  209. }
  210. memset(buf,-1,FLASH_ERASE_LENGTH);
  211. off = offset;
  212. while(length)
  213. {
  214. len = length>FLASH_ERASE_LENGTH ? FLASH_ERASE_LENGTH:length;
  215. length -= len;
  216. ret = rt_file_write(gf_flash,buf,len,&off);
  217. if(ret != len)
  218. {
  219. rt_free(buf);
  220. return -3;
  221. }
  222. }
  223. rt_free(buf);
  224. return 0;
  225. }
  226. /******************************************************************************
  227. 函数名称: at45db321_sector_protection
  228. 函数版本: 01.01
  229. 创建作者: sunxi
  230. 创建日期: 2008-10-10
  231. 函数说明: 启用FLASH的扇区保护功能。
  232. 参数说明: 无。
  233. 返回值: 成功返回0.
  234. 修改记录:
  235. */
  236. int at45db321_sector_protection(void)
  237. {
  238. return 0;
  239. }
  240. /*------------------------------ 内部函数 -------------------------------------
  241. */
  242. /*------------------------------ 测试函数 -------------------------------------
  243. */
  244. #ifdef _DEBUG_FLASH
  245. #define FLASH_BLOCK_SIZE CFG_FLASH_PAGE_SIZE
  246. int flash_test(void)
  247. {
  248. int ret;
  249. uint32_t i,j,block_size,blocks;
  250. uint32_t us0,us;
  251. unsigned int gTestBuf[FLASH_BLOCK_SIZE/sizeof(int)];
  252. block_size = FLASH_BLOCK_SIZE;
  253. // blocks = CFG_FLASH_SIZE/FLASH_BLOCK_SIZE;
  254. blocks = 1;
  255. rt_printf("flash_test begin!\r\n");
  256. rt_printf("block_size=%d,blocks=%d.\r\n",block_size,blocks);
  257. // 初始化
  258. if(gf_flash == 0)
  259. {
  260. ret = flash_init();
  261. if(ret != 0)
  262. {
  263. rt_printf("flash_init error(ret=%d)!\r\n" ,ret);
  264. return -1;
  265. }
  266. }
  267. rt_printf("flash_init ok(gf_flash=%p)!\r\n",gf_flash);
  268. //擦除整个flash。
  269. us0 = ustimer_get_origin();
  270. ret = flash_erase(0,blocks*block_size);
  271. us = ustimer_get_duration(us0);
  272. rt_printf("at45DB321Erase (us=%d,ret=%d)!\r\n",us,ret);
  273. //确认擦除OK
  274. us0 = ustimer_get_origin();
  275. for(i=0;i<blocks;i++)
  276. {
  277. ret = flash_read(i*block_size,(unsigned char *)gTestBuf,block_size);
  278. if(ret != 0)
  279. {
  280. rt_printf("at45db321Read failure(i=%d,ret=%d)!\r\n",i,ret);
  281. return -1;
  282. }
  283. for(j=0;j<block_size/sizeof(int);j++)
  284. {
  285. if(gTestBuf[j] != 0xffffffff)
  286. {
  287. rt_printf("at45DB321Erase verify failure(i=%d,j=%d,data=0x%08x)!\r\n",i,j,gTestBuf[j]);
  288. return -1;
  289. }
  290. }
  291. }
  292. us = ustimer_get_duration(us0);
  293. rt_printf("at45DB321Erase verify ok(us=%d)!\r\n",us);
  294. //整个flash写0
  295. memset(gTestBuf,0,sizeof(gTestBuf));
  296. us0 = ustimer_get_origin();
  297. for(i=0;i<blocks;i++)
  298. {
  299. ret = flash_write(i*block_size,(unsigned char *)gTestBuf,block_size);
  300. if(ret != 0)
  301. {
  302. rt_printf("at45DB321Write failure(i=%d,ret=%d)!\r\n",i,ret);
  303. return -1;
  304. }
  305. }
  306. us = ustimer_get_duration(us0);
  307. rt_printf("at45DB321Write ok(us=%d)!\r\n",us);
  308. //检查整个flash是否全为0
  309. us0 = ustimer_get_origin();
  310. for(i=0;i<blocks;i++)
  311. {
  312. ret = flash_read(i*block_size,(unsigned char *)gTestBuf,block_size);
  313. if(ret != 0)
  314. {
  315. rt_printf("at45db321Read failure(i=%d,ret=%d)!\r\n",i,ret);
  316. return -1;
  317. }
  318. for(j=0;j<block_size/sizeof(int);j++)
  319. {
  320. if(gTestBuf[j] != 0)
  321. {
  322. rt_printf("at45DB321Write verify failure(i=%d,j=%d,data=0x%08x)!\r\n",i,j,gTestBuf[j]);
  323. return -1;
  324. }
  325. }
  326. }
  327. us = ustimer_get_duration(us0);
  328. rt_printf("at45DB321Write verify ok(us=%d)!\r\n",us);
  329. //擦除整个flash
  330. us0 = ustimer_get_origin();
  331. ret = flash_erase(0,blocks*block_size);
  332. us = ustimer_get_duration(us0);
  333. rt_printf("at45DB321Erase (us=%d,ret=%d)!\r\n",us,ret);
  334. //确认擦除OK
  335. us0 = ustimer_get_origin();
  336. for(i=0;i<blocks;i++)
  337. {
  338. ret = flash_read(i*block_size,(unsigned char *)gTestBuf,block_size);
  339. if(ret != 0)
  340. {
  341. rt_printf("at45db321Read failure(i=%d,ret=%d)!\r\n",i,ret);
  342. return -1;
  343. }
  344. for(j=0;j<block_size/sizeof(int);j++)
  345. {
  346. if(gTestBuf[j] != 0xffffffff)
  347. {
  348. rt_printf("at45DB321Erase verify failure(i=%d,j=%d,data=0x%08x)!\r\n",i,j,gTestBuf[j]);
  349. return -1;
  350. }
  351. }
  352. }
  353. us = ustimer_get_duration(us0);
  354. rt_printf("at45DB321Erase verify ok(us=%d)!\r\n",us);
  355. //整个flash写测试数据
  356. us0 = ustimer_get_origin();
  357. for(i=0;i<blocks;i++)
  358. {
  359. //初始化写数据
  360. for(j=0;j<block_size/sizeof(int);j++)
  361. {
  362. gTestBuf[j] = i*block_size/sizeof(int) + j;
  363. }
  364. //写
  365. ret = flash_write(i*block_size,(unsigned char *)gTestBuf,block_size);
  366. if(ret != 0)
  367. {
  368. rt_printf("at45DB321Write failure(i=%d,ret=%d)!\r\n",i,ret);
  369. return -1;
  370. }
  371. }
  372. us = ustimer_get_duration(us0);
  373. rt_printf("at45DB321Write ok(us=%d)!\r\n",us);
  374. //读出并校验数据
  375. us0 = ustimer_get_origin();
  376. for(i=0;i<blocks;i++)
  377. {
  378. ret = flash_read(i*block_size,(unsigned char *)gTestBuf,block_size);
  379. if(ret != 0)
  380. {
  381. rt_printf("at45db321Read failure(i=%d,ret=%d)!\r\n",i,ret);
  382. return -1;
  383. }
  384. for(j=0;j<block_size/sizeof(int);j++)
  385. if(gTestBuf[j] != i*block_size/sizeof(int) + j)
  386. {
  387. rt_printf("at45DB321Write verify failure(i=%d,j=%d,data=0x%08x)!\r\n",i,j,gTestBuf[j]);
  388. return -1;
  389. }
  390. }
  391. us = ustimer_get_duration(us0);
  392. rt_printf("at45DB321Write verify ok(us=%d)!\r\n",us);
  393. rt_printf("flash_test end!\r\n\n");
  394. return 0;
  395. }
  396. #endif