spiFlashFat.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. #include "spiFlashFat.h"
  2. #include "spiFlash.h"
  3. #define SFILE_VALID_MARK 0x20115028
  4. #define INVALID_FID 0xff
  5. #define SERR_SUCC 0
  6. #define SERR_INIT_FAIL 1
  7. #define SERR_ERACE_FAIL 2
  8. #define SERR_WRITE_FAIL 3
  9. #define SERR_READ_FAIL 4
  10. #define SERR_FILE_FULL 5
  11. #define SERR_SIZE_FULL 6
  12. static unsigned char spiFatErr=0;
  13. unsigned char spi_flash_get_err(void){return spiFatErr;}
  14. /*SPI FLASH 使用地址划分*/
  15. /*第一块,用于系统参数保存使用,自带备份,每个文件暂时2个sector*/
  16. /*第一块,用于应用创建使用*/
  17. #define MAX_SFILE_NUM 5 //1区最多可以创建多少个系统参数文件
  18. #define SFILE_BLOCK_1_START_ADDR 0 //1区起始地址
  19. #define SFILE_BLOCK_1_SIZE_BYTE (2*MAX_SFILE_NUM*SECTOR_SIZE_BYTE) //1区总大小
  20. /*第二块,用于文件暂时存储,不带备份,异常掉电可能丢失*/
  21. #define SFILE_BLOCK_2_START_ADDR (SFILE_BLOCK_1_START_ADDR+SFILE_BLOCK_1_SIZE_BYTE)//2区起始地址
  22. #define SFILE_BLOCK_2_SIZE_BYTE (SECTOR_SIZE_BYTE+SECTOR_SIZE_BYTE*128)//2区总大小
  23. //检测是否超出存储范围
  24. #define SFILE_USER_MAX (SFILE_BLOCK_1_SIZE_BYTE+SFILE_BLOCK_2_SIZE_BYTE)
  25. #if(SFILE_USER_MAX>SPI_FLASH_MAX_SIZE)
  26. #error "USER FLASH SIZE OVERFLOW"
  27. #endif
  28. /***********************************第一块文件系统实现*************************************/
  29. #pragma pack(push)
  30. #pragma pack(1)
  31. typedef struct{//放在sector最后
  32. unsigned short crc16;
  33. unsigned int mark;
  34. }SFILE_INFO_DEF;
  35. #pragma pack(pop)
  36. #define SFILE_VALID_SIZE (SECTOR_SIZE_BYTE-sizeof(SFILE_INFO_DEF)) //每个系统文件最多能存的用户有效数据
  37. /*格式化文件*/
  38. bool spi_flash_file_format(unsigned char fid){
  39. char i;
  40. SPI_PWR_LOCK;
  41. if(fid>=MAX_SFILE_NUM || spiFlashInit()==false){
  42. spiFatErr=SERR_INIT_FAIL;SPI_PWR_RELEAS;
  43. return INVALID_FID;
  44. }
  45. for(i=0;i<2;i++){
  46. if(false==spiFlashSectorErace(SFILE_BLOCK_1_START_ADDR+(fid*2+i)*SECTOR_SIZE_BYTE)){
  47. spiFatErr=SERR_ERACE_FAIL;SPI_PWR_RELEAS;
  48. return false;
  49. }
  50. }
  51. SPI_PWR_RELEAS;
  52. return true;
  53. }
  54. /*格式化区域所有文件*/
  55. bool spi_flash_files_format(void){
  56. char i;
  57. SPI_PWR_LOCK;
  58. for(i=0;i<MAX_SFILE_NUM;i++){
  59. if(false==spi_flash_file_format(i)){
  60. SPI_PWR_RELEAS;
  61. return false;
  62. }
  63. }
  64. SPI_PWR_RELEAS;
  65. return true;
  66. }
  67. /*文件读数据*/
  68. bool spi_flash_file_read(unsigned char fid, unsigned int addr, unsigned char *ptr, unsigned int size){
  69. int len=size;
  70. //都从使用区读,备份区只在开机时作恢复使用
  71. if(spiFlashInit()==false){
  72. spiFatErr=SERR_INIT_FAIL;
  73. return false;
  74. }
  75. //读取
  76. if(len>SFILE_VALID_SIZE) len=SFILE_VALID_SIZE;
  77. if(false==spiFlashDataRead(SFILE_BLOCK_1_START_ADDR+2*fid*SECTOR_SIZE_BYTE+addr, ptr, len)){
  78. spiFatErr=SERR_READ_FAIL;
  79. return false;
  80. }
  81. return true;
  82. }
  83. /*文件写数据*/
  84. bool spi_flash_file_write(unsigned char fid, unsigned int addr, unsigned char *ptr, unsigned int size){
  85. unsigned char tmp[SECTOR_SIZE_BYTE];
  86. unsigned int len=size;
  87. SFILE_INFO_DEF *info=tmp+SFILE_VALID_SIZE;
  88. //先写备份区,再写使用区
  89. //1,先读使用区数据
  90. if(false==spiFlashDataRead(SFILE_BLOCK_1_START_ADDR+2*fid*SECTOR_SIZE_BYTE, tmp, SECTOR_SIZE_BYTE)){
  91. spiFatErr=SERR_READ_FAIL;
  92. return false;
  93. }
  94. //2,修改缓存数据
  95. if(len>SFILE_VALID_SIZE) len=SFILE_VALID_SIZE;
  96. memcpy(tmp+addr, ptr, len);
  97. info->mark=SFILE_VALID_MARK;
  98. info->crc16=make_crc16(tmp, SFILE_VALID_SIZE);
  99. info->crc16 += make_crc16(tmp+SECTOR_SIZE_BYTE-4);
  100. SPI_PWR_LOCK;
  101. //3,写到备份区
  102. if(false==spiFlashDataWrite(SFILE_BLOCK_1_START_ADDR+2*fid*SECTOR_SIZE_BYTE+SECTOR_SIZE_BYTE, tmp, SECTOR_SIZE_BYTE)){
  103. spiFatErr=SERR_WRITE_FAIL;
  104. SPI_PWR_RELEAS;
  105. return false;
  106. }
  107. //4,写到使用区
  108. if(false==spiFlashDataWrite(SFILE_BLOCK_1_START_ADDR+2*fid*SECTOR_SIZE_BYTE, tmp, SECTOR_SIZE_BYTE)){
  109. spiFatErr=SERR_WRITE_FAIL;
  110. SPI_PWR_RELEAS;
  111. return false;
  112. }
  113. SPI_PWR_RELEAS;
  114. return true;
  115. }
  116. /*检测是否需要恢复,不会出现两个sector都异常*/
  117. static bool spi_flash_file_check(void){
  118. unsigned char i;
  119. unsigned char tmp[SECTOR_SIZE_BYTE];
  120. SFILE_INFO_DEF info1,info2;
  121. unsigned short crc16_1,crc16_2;
  122. if(spiFlashInit()==false){
  123. spiFatErr=SERR_INIT_FAIL;
  124. return false;
  125. }
  126. for(i=0;i<MAX_SFILE_NUM;i++){
  127. //读取使用区,得出mark,crc16
  128. if(false==spiFlashDataRead(SFILE_BLOCK_1_START_ADDR+2*i*SECTOR_SIZE_BYTE, tmp, SECTOR_SIZE_BYTE)){
  129. spiFatErr=SERR_READ_FAIL;
  130. return false;
  131. }
  132. memcpy((unsigned char *)&info1, tmp+SECTOR_SIZE_BYTE-sizeof(SFILE_INFO_DEF), sizeof(SFILE_INFO_DEF));
  133. //计算crc16
  134. crc16_1=make_crc16(tmp, SECTOR_SIZE_BYTE-sizeof(SFILE_INFO_DEF));
  135. crc16_1 += make_crc16(tmp+SECTOR_SIZE_BYTE-4,4);
  136. //读取备份区,得出mark,crc16
  137. if(false==spiFlashDataRead(SFILE_BLOCK_1_START_ADDR+(2*i+1)*SECTOR_SIZE_BYTE, tmp, SECTOR_SIZE_BYTE)){
  138. spiFatErr=SERR_READ_FAIL;
  139. return false;
  140. }
  141. memcpy((unsigned char *)&info2, tmp+SECTOR_SIZE_BYTE-sizeof(SFILE_INFO_DEF), sizeof(SFILE_INFO_DEF));
  142. //计算crc16
  143. crc16_2=make_crc16(tmp, SECTOR_SIZE_BYTE-sizeof(SFILE_INFO_DEF));
  144. crc16_2 += make_crc16(tmp+SECTOR_SIZE_BYTE-4,4);
  145. //比较
  146. if(info1.mark==SFILE_VALID_MARK && info1.crc16==crc16_1) {}//使用区正常,不需要处理
  147. else if(info2.mark==SFILE_VALID_MARK && info2.crc16==crc16_2){//使用区不正常,备区正常,备拷贝到使用区
  148. if(false==spiFlashDataWrite(SFILE_BLOCK_1_START_ADDR+(2*i+1)*SECTOR_SIZE_BYTE, tmp, SECTOR_SIZE_BYTE)){
  149. spiFatErr=SERR_WRITE_FAIL;
  150. SPI_PWR_RELEAS;
  151. return false;
  152. }
  153. }else if(info1.mark!=0xffffffff){//未format过,fotmat之
  154. if(false==spi_flash_file_format(i)){
  155. spiFatErr=SERR_ERACE_FAIL;
  156. return false;
  157. }
  158. }
  159. }
  160. return true;
  161. }
  162. /***********************************第二块文件系统实现*************************************/
  163. #pragma pack(push)
  164. #pragma pack(1)
  165. typedef struct{
  166. unsigned int mark;//文件是否有效标识
  167. unsigned int startAddr;//文件起始地址
  168. unsigned int size;//文件大小
  169. unsigned short crc16//结构体crc16
  170. }SFAT_INFO_DEF;
  171. #define MAX_SFAT_NUM 10
  172. typedef struct{
  173. SFAT_INFO_DEF files[MAX_SFAT_NUM];
  174. unsigned char validFiles;//有效文件个数
  175. unsigned int validSize;//区域可用空间
  176. unsigned short crc16;//结构体crc16
  177. }SFAT_LIST_DEF;
  178. #pragma pack(pop)
  179. static SFAT_LIST_DEF sFat;
  180. /*搜索空文件*/
  181. static unsigned char spi_flash_fat_get_empty(void){
  182. int i;
  183. for(i=0;i<MAX_SFAT_NUM;i++){
  184. if(sFat.files[i].mark != SFILE_VALID_MARK) return i;
  185. }
  186. return INVALID_FID;
  187. }
  188. /*格式化区域*/
  189. bool spi_flash_fat_format(void){
  190. unsigned int i,addr=SFILE_BLOCK_2_START_ADDR;
  191. if(spiFlashInit()==false){
  192. spiFatErr=SERR_INIT_FAIL;
  193. return false;
  194. }
  195. //擦除整块区域
  196. for(i=0;i<SFILE_BLOCK_2_SIZE_BYTE;i+=SECTOR_SIZE_BYTE){
  197. if(false==spiFlashSectorErace(addr+i)){
  198. spiFatErr=SERR_ERACE_FAIL;
  199. return false;
  200. }
  201. }
  202. //初始化结构体
  203. memset((unsigned char *)&sFat, 0, sizeof(SFAT_LIST_DEF));
  204. sFat.validSize=SFILE_BLOCK_2_SIZE_BYTE-SECTOR_SIZE_BYTE;
  205. //更新到内存
  206. if(spiFlashDataWrite(addr, (unsigned char *)&sFat, sizeof(SFAT_LIST_DEF))){
  207. spiFatErr=SERR_WRITE_FAIL;
  208. return false;
  209. }
  210. return true;
  211. }
  212. /*区域中新建文件*/
  213. /*sectorNum:文件占用多少sector
  214. 返回:INVALID_FID, 失败 , else 文件ID*/
  215. unsigned char spi_flash_fat_create(unsigned short sectorNum){
  216. unsigned char fid;
  217. SFAT_INFO_DEF *info;
  218. if(spiFlashInit()==false){
  219. spiFatErr=SERR_INIT_FAIL;
  220. return INVALID_FID;
  221. }
  222. //查找空文件
  223. fid=spi_flash_fat_get_empty();
  224. if(fid==INVALID_FID){
  225. spiFatErr=SERR_FILE_FULL;
  226. return fid;
  227. }
  228. info=&sFat.files[fid];
  229. //初始化文件
  230. memset((unsigned char *)info, 0, sizeof(SFAT_INFO_DEF));
  231. info->mark=SFILE_VALID_MARK;
  232. if(fid==0) info->startAddr=SECTOR_SIZE_BYTE;//第一个文件放在列表sector的下sector开始
  233. else info->startAddr=sFat.files[fid-1].startAddr+sFat.files[fid-1].size;
  234. info->size=sectorNum*SECTOR_SIZE_BYTE;
  235. if(info->size<sFat.validSize){
  236. spiFatErr=SERR_SIZE_FULL;
  237. return INVALID_FID;
  238. }
  239. info->crc16=make_crc16((unsigned char *)info,sizeof(SFAT_INFO_DEF)-2);
  240. //更新剩余
  241. sFat.validSize -= info->size;
  242. sFat.validFiles++;
  243. sFat.crc16=make_crc16((unsigned char *)&sFat, sizeof(SFAT_LIST_DEF)-2);
  244. //保存
  245. if(spiFlashDataWrite(SFILE_BLOCK_2_START_ADDR, (unsigned char *)&sFat, sizeof(SFAT_LIST_DEF))){//恢复
  246. spiFatErr=SERR_WRITE_FAIL;
  247. return INVALID_FID;
  248. }
  249. return fid;
  250. }
  251. ////////////////////////////////////////////////////////////////////////////////////////////
  252. /*spi文件系统初始化,读写前先调用*/
  253. void spiFlashInitApiInit(void){
  254. spi_flash_file_check();//检测是否需要备份的恢复
  255. }