fs.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. /**************************************************************************************************
  2. Phyplus Microelectronics Limited confidential and proprietary.
  3. All rights reserved.
  4. IMPORTANT: All rights of this software belong to Phyplus Microelectronics
  5. Limited ("Phyplus"). Your use of this Software is limited to those
  6. specific rights granted under the terms of the business contract, the
  7. confidential agreement, the non-disclosure agreement and any other forms
  8. of agreements as a customer or a partner of Phyplus. You may not use this
  9. Software unless you agree to abide by the terms of these agreements.
  10. You acknowledge that the Software may not be modified, copied,
  11. distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy
  12. (BLE) integrated circuit, either as a product or is integrated into your
  13. products. Other than for the aforementioned purposes, you may not use,
  14. reproduce, copy, prepare derivative works of, modify, distribute, perform,
  15. display or sell this Software and/or its documentation for any purposes.
  16. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  17. PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  18. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  19. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  20. PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT,
  21. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  22. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  23. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  24. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  25. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  26. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  27. **************************************************************************************************/
  28. /*******************************************************************************
  29. * @file fs.c
  30. * @brief Contains all functions support for spi driver
  31. * @version 0.0
  32. * @date 18. Oct. 2017
  33. * @author
  34. *
  35. * Copyright(C) 2016, PhyPlus Semiconductor
  36. * All rights reserved.
  37. *
  38. *******************************************************************************/
  39. #include "osal.h"
  40. #include "common.h"
  41. #include "flash.h"
  42. #include "fs.h"
  43. #include "error.h"
  44. //#include "log.h"
  45. static uint8_t fs_sector_num;
  46. static uint32_t fs_offset_address;
  47. #define FS_ITEM_LEN_16BYTE 0
  48. #define FS_ITEM_LEN_32BYTE 1
  49. #define FS_ITEM_LEN_64BYTE 2
  50. #ifndef FS_SETTING
  51. #define FS_SETTING FS_ITEM_LEN_16BYTE
  52. #endif
  53. #if (FS_SETTING == FS_ITEM_LEN_16BYTE)
  54. #define FS_ITEM_LEN 16
  55. #elif (FS_SETTING == FS_ITEM_LEN_32BYTE)
  56. #define FS_ITEM_LEN 32
  57. #elif (FS_SETTING == FS_ITEM_LEN_64BYTE)
  58. #define FS_ITEM_LEN 64
  59. #else
  60. #error please check your config parameter
  61. #endif
  62. /*
  63. fs struct:
  64. sector0
  65. sector_head
  66. file_head(4byte)+file_data
  67. ...
  68. file_head(4byte)+file_data
  69. */
  70. //please do not modify the following parameters
  71. #define FS_ITEM_HEAD_LEN 4
  72. #define FS_ITEM_DATA_LEN (FS_ITEM_LEN - FS_ITEM_HEAD_LEN)
  73. #define FS_SECTOR_ITEM_NUM (4096/FS_ITEM_LEN - 1)
  74. #define FS_SECTOR_NUM_BUFFER_SIZE (312/4)
  75. #define FS_ABSOLUTE_ADDR(offset) (fs.cfg.sector_addr + offset)
  76. typedef enum{
  77. ITEM_DEL = 0x00,//zone is deleted
  78. ITEM_UNUSED = 0x03,//zone is free
  79. ITEM_USED = 0x02,//zone is used
  80. ITEM_RESERVED = 0x01//to be extend
  81. }item_pro;
  82. typedef enum{
  83. ITEM_SF = 0x03,//single frame file
  84. ITEM_MF_F = 0x01,//multiple frame file,first frame
  85. ITEM_MF_C = 0x02,//multiple frame file,continue frame
  86. ITEM_MF_E = 0x00//multiple frame file,end frame
  87. }item_frame;
  88. typedef enum{
  89. FLASH_UNCHECK = 0,//before analysis fs
  90. FLASH_NEW = 1,//new fs,its are 0xFF
  91. FLASH_ORIGINAL_ORDER = 2,//fs has data,its order is the original
  92. FLASH_NEW_ORDER = 3,//fs has data,its order is not the original
  93. FLASH_CONTEXT_ERROR = 4,//fs has data,but data is broken
  94. }FS_FLASH_TYPE;
  95. /*
  96. file head struct:
  97. len(12bit)+frame(2bit)+pro(2bit)+id(16bit)
  98. */
  99. typedef union
  100. {
  101. struct
  102. {
  103. uint32_t id:16;//file id
  104. uint32_t pro:2;//file property
  105. uint32_t frame:2;//file frame
  106. uint32_t len:12;//file length
  107. } b;
  108. uint32_t reg;
  109. } fs_item_t;
  110. /*
  111. sector head struct:
  112. sector_addr(one word)+(ff+index+item_len+sector_num)(one word)+(0xffffffff)(one word)~(0xffffffff)(one word)
  113. */
  114. typedef struct{
  115. uint32_t sector_addr;//fs start address
  116. uint8_t sector_num;//fs sector number
  117. uint8_t item_len;//item length
  118. uint8_t index;//sector index
  119. uint8_t reserved[FS_ITEM_LEN-7];
  120. }fs_cfg_t;
  121. typedef struct{
  122. fs_cfg_t cfg;
  123. uint8_t current_sector;//free sector index
  124. uint8_t exchange_sector;//exchange sector,only use it when garbage collect
  125. uint16_t offset;//free position in free sector index
  126. }fs_t;
  127. static fs_t fs;
  128. static bool fs_init_flag = false;
  129. typedef enum{
  130. SEARCH_FREE_ITEM = 0,
  131. SEARCH_APPOINTED_ITEM = 1,
  132. SEARCH_DELETED_ITEMS = 2,
  133. }search_type;
  134. extern uint32_t __psr(void);//check if in int process
  135. static void fs_erase_ucds_all_sector(void)
  136. {
  137. int i;
  138. for(i=0;i<fs_sector_num;i++)
  139. flash_sector_erase(fs_offset_address + (i*4096));
  140. }
  141. static void fs_erase_ucds_one_sector(uint32_t addr_erase)
  142. {
  143. flash_sector_erase(fs_offset_address + addr_erase);
  144. }
  145. static int spif_write(uint32_t addr,uint8_t* value,uint16_t len)
  146. {
  147. uint32_t i = 0,data;
  148. if(__psr()&0x3f){
  149. return PPlus_ERR_FS_IN_INT;
  150. }
  151. if((addr < fs_offset_address) || (addr >= (fs_offset_address+fs_sector_num*4096)) || ((addr&0x03)>0)){
  152. return PPlus_ERR_FS_PARAMETER;
  153. }
  154. while(i < len){
  155. switch(len - i)
  156. {
  157. case 1:
  158. data = *(value+i);
  159. break;
  160. case 2:
  161. data = *(value+i) + ((*(value+i+1)) << 8);
  162. break;
  163. case 3:
  164. data = *(value+i) + ((*(value+i+1)) << 8) + ((*(value+i+2)) << 16);
  165. break;
  166. default:
  167. data = *(value+i) + ((*(value+i+1)) << 8) + ((*(value+i+2)) << 16) + ((*(value+i+3)) << 24);
  168. break;
  169. }
  170. if(WriteFlash(addr,data) == 0){
  171. return PPlus_ERR_FS_WRITE_FAILED;
  172. }
  173. addr += 4;
  174. i += 4;
  175. }
  176. return PPlus_SUCCESS;
  177. }
  178. static uint32_t spif_read(uint32_t addr,uint8_t* buf,uint32_t len)
  179. {
  180. uint32_t i = 0,count = 0;
  181. uint32_t temp = 0;
  182. if ((addr < fs_offset_address) || (addr >= (fs_offset_address + fs_sector_num*4096)) || (buf == NULL) || (len == 0))
  183. {
  184. return PPlus_ERR_FS_PARAMETER;
  185. }
  186. else
  187. {
  188. count = len/4 + ((len % 4) ? 1 : 0);
  189. for(i = 0;i < count;i++)
  190. {
  191. temp = ReadFlashWord(addr + (i<<2));
  192. *(buf + (i << 2) + 0) = (temp & 0xff);
  193. *(buf + (i << 2) + 1) = (temp & 0xff00)>>8;
  194. *(buf + (i << 2) + 2) = (temp & 0xff0000)>>16;
  195. *(buf + (i << 2) + 3) = (temp & 0xff000000)>>24;
  196. }
  197. }
  198. return PPlus_SUCCESS;
  199. }
  200. static void check_addr(uint32_t* addr)
  201. {
  202. if((*addr % 4096) == 0)
  203. {
  204. *addr += sizeof(fs_cfg_t);
  205. if(*addr >= 4096 *fs_sector_num)
  206. *addr -= 4096 *fs_sector_num;
  207. }
  208. }
  209. static int fs_search_items(search_type type,uint32_t* para1,uint32_t* para2)
  210. {
  211. uint8_t m,n;
  212. uint16_t j,g_offset = 1;
  213. uint32_t sector_addr,ab_addr;
  214. fs_item_t i1;
  215. bool from_last_sector = false;
  216. for(m = 1;m < fs_sector_num;m++)
  217. {
  218. n = (m + fs.exchange_sector) % fs.cfg.sector_num;
  219. if(g_offset >= FS_SECTOR_ITEM_NUM){
  220. g_offset -= FS_SECTOR_ITEM_NUM;
  221. if(g_offset >= FS_SECTOR_ITEM_NUM){
  222. continue;
  223. }
  224. }
  225. if(SEARCH_FREE_ITEM == type)
  226. fs.current_sector = (m + fs.exchange_sector) % fs.cfg.sector_num;
  227. sector_addr = n * 4096;
  228. for(j = 1;j <= FS_SECTOR_ITEM_NUM;j++)
  229. {
  230. if(from_last_sector == true){
  231. from_last_sector = false;
  232. j += g_offset;
  233. }
  234. else{
  235. if(g_offset > 1){
  236. if((j - 2 + g_offset) < FS_SECTOR_ITEM_NUM){
  237. j = j - 1 + g_offset;
  238. }
  239. else{
  240. g_offset -= (FS_SECTOR_ITEM_NUM + 2 - j);
  241. from_last_sector = true;
  242. break;
  243. }
  244. }
  245. }
  246. ab_addr = sector_addr + (j * FS_ITEM_LEN);
  247. spif_read(FS_ABSOLUTE_ADDR(ab_addr),(uint8_t*)&i1,FS_ITEM_HEAD_LEN);
  248. switch(type)
  249. {
  250. case SEARCH_FREE_ITEM:
  251. {
  252. switch(i1.b.pro)
  253. {
  254. case ITEM_DEL:
  255. case ITEM_USED:
  256. {
  257. if(i1.b.frame == ITEM_MF_F)
  258. g_offset = (i1.b.len/FS_ITEM_DATA_LEN) + ((i1.b.len%FS_ITEM_DATA_LEN)?1:0);
  259. else
  260. g_offset = 1;
  261. }
  262. break;
  263. case ITEM_UNUSED:
  264. *para1 = ab_addr%4096;
  265. return PPlus_SUCCESS;
  266. default:
  267. break;
  268. }
  269. }
  270. break;
  271. case SEARCH_APPOINTED_ITEM:
  272. {
  273. switch(i1.b.pro)
  274. {
  275. case ITEM_DEL:
  276. case ITEM_USED:
  277. if((ITEM_USED == i1.b.pro) && (i1.b.id == (uint16)(*para1)))
  278. {
  279. *para2 = ab_addr;
  280. return PPlus_SUCCESS;
  281. }
  282. else
  283. {
  284. if(i1.b.frame == ITEM_MF_F)
  285. g_offset = (i1.b.len/FS_ITEM_DATA_LEN) + ((i1.b.len%FS_ITEM_DATA_LEN)?1:0);
  286. else
  287. g_offset = 1;
  288. }
  289. break;
  290. case ITEM_UNUSED:
  291. return PPlus_ERR_FS_NOT_FIND_ID;
  292. default:
  293. break;
  294. }
  295. }
  296. break;
  297. case SEARCH_DELETED_ITEMS:
  298. {
  299. switch(i1.b.pro)
  300. {
  301. case ITEM_DEL:
  302. {
  303. if(i1.b.frame == ITEM_MF_F){
  304. g_offset = (i1.b.len/FS_ITEM_DATA_LEN) + ((i1.b.len%FS_ITEM_DATA_LEN)?1:0);
  305. *para1 += g_offset*FS_ITEM_DATA_LEN;
  306. }
  307. else{
  308. g_offset = 1;
  309. *para1 += FS_ITEM_DATA_LEN;
  310. }
  311. *para2 += 1;
  312. }
  313. break;
  314. case ITEM_USED:
  315. {
  316. if(i1.b.frame == ITEM_MF_F){
  317. g_offset = (i1.b.len/FS_ITEM_DATA_LEN) + ((i1.b.len%FS_ITEM_DATA_LEN)?1:0);
  318. }
  319. else{
  320. g_offset = 1;
  321. }
  322. }
  323. break;
  324. case ITEM_UNUSED:
  325. return PPlus_SUCCESS;
  326. default:
  327. break;
  328. }
  329. }
  330. break;
  331. default:
  332. return PPlus_ERR_INVALID_PARAM;
  333. }
  334. }
  335. }
  336. switch(type)
  337. {
  338. case SEARCH_FREE_ITEM:
  339. return PPlus_ERR_FS_FULL;
  340. case SEARCH_APPOINTED_ITEM:
  341. return PPlus_ERR_FS_NOT_FIND_ID;
  342. default:
  343. return PPlus_SUCCESS;
  344. }
  345. }
  346. static int fs_get_free_item(void)
  347. {
  348. int ret;
  349. uint32_t posiztion = 0;
  350. if(fs_init_flag == false)
  351. return PPlus_ERR_FS_UNINITIALIZED;
  352. ret = fs_search_items(SEARCH_FREE_ITEM,&posiztion,0);
  353. if(PPlus_SUCCESS == ret){
  354. fs.offset = posiztion;
  355. }else if(PPlus_ERR_FS_FULL == ret){
  356. fs.offset = 4096;
  357. }
  358. return ret;
  359. }
  360. static int fs_init(void)
  361. {
  362. uint8_t i = 0,sector_order[FS_SECTOR_NUM_BUFFER_SIZE],ret = PPlus_ERR_FS_UNINITIALIZED;
  363. FS_FLASH_TYPE flash = FLASH_UNCHECK;
  364. fs_cfg_t flash_rd_cfg;
  365. fs.cfg.sector_addr = fs_offset_address;
  366. fs.cfg.sector_num = fs_sector_num;;
  367. fs.cfg.index = 0xff;
  368. fs.cfg.item_len = FS_ITEM_LEN;
  369. osal_memset((fs.cfg.reserved),0xff,(FS_ITEM_LEN-7)*sizeof(uint8_t));
  370. osal_memset((sector_order),0x00,FS_SECTOR_NUM_BUFFER_SIZE);
  371. for(i = 0;i < fs.cfg.sector_num;i++)
  372. {
  373. spif_read(FS_ABSOLUTE_ADDR(4096*i),(uint8_t*)(&flash_rd_cfg),sizeof(fs_cfg_t));
  374. if((flash_rd_cfg.sector_addr == fs.cfg.sector_addr) &&
  375. (flash_rd_cfg.sector_num == fs.cfg.sector_num) &&
  376. (flash_rd_cfg.item_len == fs.cfg.item_len))
  377. {
  378. if(flash_rd_cfg.index < (fs_sector_num - 1))
  379. {
  380. if(i == flash_rd_cfg.index)
  381. flash = FLASH_ORIGINAL_ORDER;
  382. else
  383. flash = FLASH_NEW_ORDER;
  384. sector_order[i] = flash_rd_cfg.index;
  385. fs.cfg.index = flash_rd_cfg.index;
  386. }
  387. else
  388. {
  389. flash = FLASH_CONTEXT_ERROR;
  390. break;
  391. }
  392. }
  393. else if((flash_rd_cfg.sector_addr == 0xffffffff) &&
  394. (flash_rd_cfg.sector_num == 0xff) &&
  395. (flash_rd_cfg.item_len == 0xff))
  396. {
  397. sector_order[i] = 0xff;
  398. }
  399. else
  400. {
  401. flash = FLASH_CONTEXT_ERROR;
  402. break;
  403. }
  404. }
  405. if(flash == FLASH_CONTEXT_ERROR){
  406. return PPlus_ERR_FS_CONTEXT;
  407. }
  408. if(fs.cfg.index == 0xff)
  409. flash = FLASH_NEW;
  410. if(flash == FLASH_NEW)
  411. {
  412. for(i = 0;i < (fs.cfg.sector_num - 1);i++)
  413. {
  414. fs.cfg.index = i;
  415. if(PPlus_SUCCESS != spif_write((FS_ABSOLUTE_ADDR(4096*i)),(uint8_t*)(&(fs.cfg)),sizeof(fs_cfg_t))){
  416. return PPlus_ERR_FS_WRITE_FAILED;
  417. }
  418. }
  419. fs.current_sector = 0;
  420. fs.exchange_sector = fs.cfg.sector_num - 1;
  421. fs.offset = sizeof(fs_cfg_t);
  422. fs_init_flag = TRUE;
  423. }
  424. else
  425. {
  426. for(i = 0;i < fs.cfg.sector_num;i++){
  427. if(sector_order[i] == 0)
  428. break;
  429. }
  430. if(i < fs.cfg.sector_num)
  431. {
  432. fs.exchange_sector = (i + fs.cfg.sector_num - 1) % fs.cfg.sector_num;
  433. fs_init_flag = TRUE;
  434. ret = fs_get_free_item();
  435. if((ret != PPlus_ERR_FS_FULL) && (ret != PPlus_SUCCESS)){
  436. return PPlus_ERR_FS_RESERVED_ERROR;
  437. }
  438. }
  439. }
  440. return PPlus_SUCCESS;
  441. }
  442. uint32_t hal_fs_get_free_size(void)
  443. {
  444. uint32_t size = 0;
  445. if(fs_init_flag == false){
  446. //LOG("fs_init_flag = false,free\n");
  447. return 0;
  448. }
  449. if(fs.offset < 4096)
  450. {
  451. size = ((fs.exchange_sector + fs.cfg.sector_num - fs.current_sector - 1)%fs.cfg.sector_num)*(4096-sizeof(fs_cfg_t));
  452. size += (4096 - fs.offset);
  453. size = size*FS_ITEM_DATA_LEN/FS_ITEM_LEN;
  454. }
  455. return size;
  456. }
  457. int hal_fs_get_garbage_size(uint32_t* garbage_file_num)
  458. {
  459. uint32_t garbage_size = 0,garbage_count = 0;
  460. int ret;
  461. if(fs_init_flag == false)
  462. return PPlus_ERR_FS_UNINITIALIZED;
  463. ret = fs_search_items(SEARCH_DELETED_ITEMS,&garbage_size,&garbage_count);
  464. if(PPlus_SUCCESS == ret){
  465. if(NULL != garbage_file_num)
  466. *garbage_file_num = garbage_count;
  467. return garbage_size;
  468. }
  469. return PPlus_ERR_FATAL;
  470. }
  471. int hal_fs_item_find_id(uint16_t id,uint32_t* id_addr)
  472. {
  473. int ret;
  474. uint32_t file_id = 0;
  475. if(fs_init_flag == false)
  476. return PPlus_ERR_FS_UNINITIALIZED;
  477. file_id = id & 0xffff;
  478. ret = fs_search_items(SEARCH_APPOINTED_ITEM,&file_id,id_addr);
  479. return ret;
  480. }
  481. int hal_fs_item_write(uint16_t id,uint8_t* buf,uint16_t len)
  482. {
  483. uint8_t frame_len,wr_buf[FS_ITEM_LEN];
  484. uint16_t i,item_len;
  485. uint32_t addr;
  486. fs_item_t i1;
  487. if(__psr()&0x3f){
  488. return PPlus_ERR_FS_IN_INT;
  489. }
  490. if(fs_init_flag == false){
  491. //LOG("fs_init_flag = false,write\n");
  492. return PPlus_ERR_FS_UNINITIALIZED;
  493. }
  494. if((buf == NULL) || (len == 0)||(len > 4095))
  495. return PPlus_ERR_FS_PARAMETER;
  496. if(len > hal_fs_get_free_size())
  497. return PPlus_ERR_FS_NOT_ENOUGH_SIZE;
  498. //if(hal_fs_item_find_id(id,&addr) == PPlus_SUCCESS)
  499. // return PPlus_ERR_FS_EXIST_SAME_ID;
  500. if(hal_fs_item_find_id(id,&addr) == PPlus_SUCCESS){
  501. if(PPlus_SUCCESS != hal_fs_item_del(id))
  502. return PPlus_ERR_FATAL;
  503. }
  504. item_len = len;
  505. i1.b.len = len;
  506. i1.b.id = id;
  507. i1.b.pro = ITEM_USED;
  508. if(len <= FS_ITEM_DATA_LEN)
  509. i1.b.frame = ITEM_SF;
  510. i = 0;
  511. while(len > 0)
  512. {
  513. if(len > FS_ITEM_DATA_LEN)
  514. {
  515. if(item_len == len)
  516. i1.b.frame = ITEM_MF_F;
  517. else
  518. i1.b.frame = ITEM_MF_C;
  519. frame_len = FS_ITEM_DATA_LEN;
  520. len -= FS_ITEM_DATA_LEN;
  521. }
  522. else
  523. {
  524. if((i1.b.frame == ITEM_MF_C) || (i1.b.frame == ITEM_MF_F))
  525. i1.b.frame = ITEM_MF_E;
  526. frame_len = len;
  527. len = 0;
  528. }
  529. addr = FS_ABSOLUTE_ADDR((fs.current_sector * 4096) + fs.offset);
  530. osal_memcpy(wr_buf,(uint8_t*)(&i1.reg),FS_ITEM_HEAD_LEN);
  531. osal_memcpy((wr_buf + FS_ITEM_HEAD_LEN),(buf + i),frame_len);
  532. if(PPlus_SUCCESS != spif_write(addr,wr_buf,(frame_len+FS_ITEM_HEAD_LEN)))
  533. return PPlus_ERR_FS_WRITE_FAILED;
  534. i += frame_len;
  535. fs.offset += FS_ITEM_LEN;
  536. if(fs.offset == 4096)
  537. {
  538. if(((fs.current_sector + 1) % fs.cfg.sector_num) != fs.exchange_sector)
  539. {
  540. fs.offset = sizeof(fs_cfg_t);
  541. fs.current_sector = (fs.current_sector + 1) % fs.cfg.sector_num;
  542. }
  543. }
  544. }
  545. return PPlus_SUCCESS;
  546. }
  547. int hal_fs_item_read(uint16_t id,uint8_t* buf,uint16_t buf_len,uint16_t* len)
  548. {
  549. uint8_t rd_len;
  550. uint16_t i = 0,temp_len;
  551. uint32_t addr;
  552. fs_item_t i1;
  553. if(__psr()&0x3f){
  554. return PPlus_ERR_FS_IN_INT;
  555. }
  556. if(fs_init_flag == false)
  557. return PPlus_ERR_FS_UNINITIALIZED;
  558. if((buf == NULL) || (buf_len == 0))
  559. return PPlus_ERR_FS_PARAMETER;
  560. if(hal_fs_item_find_id(id,&addr) == PPlus_SUCCESS)
  561. {
  562. spif_read(FS_ABSOLUTE_ADDR(addr),(uint8_t*)&i1,FS_ITEM_HEAD_LEN);
  563. if(len != NULL){
  564. *len = i1.b.len;
  565. }
  566. temp_len = i1.b.len;
  567. if(buf_len >= i1.b.len)
  568. {
  569. while(temp_len > 0)
  570. {
  571. rd_len = (temp_len >= FS_ITEM_DATA_LEN) ? FS_ITEM_DATA_LEN : temp_len;
  572. spif_read(FS_ABSOLUTE_ADDR(addr + FS_ITEM_HEAD_LEN),(buf + i),rd_len);
  573. temp_len -= rd_len;
  574. addr += FS_ITEM_LEN;
  575. i += rd_len;
  576. check_addr(&addr);
  577. }
  578. return PPlus_SUCCESS;
  579. }
  580. return PPlus_ERR_FS_BUFFER_TOO_SMALL;
  581. }
  582. return PPlus_ERR_FS_NOT_FIND_ID;
  583. }
  584. int hal_fs_item_del(uint16_t id)
  585. {
  586. uint16_t i = 0,count = 1;
  587. uint32_t addr = 0;
  588. fs_item_t i1;
  589. if(__psr()&0x3f){
  590. return PPlus_ERR_FS_IN_INT;
  591. }
  592. if(fs_init_flag == FALSE)
  593. return PPlus_ERR_FS_UNINITIALIZED;
  594. if(hal_fs_item_find_id(id,&addr) == PPlus_SUCCESS)
  595. {
  596. spif_read(FS_ABSOLUTE_ADDR(addr),(uint8_t*)&i1,FS_ITEM_HEAD_LEN);
  597. count = i1.b.len/FS_ITEM_DATA_LEN + ((i1.b.len % FS_ITEM_DATA_LEN)?1:0);
  598. for(i = 0;i < count;i++)
  599. {
  600. spif_read(FS_ABSOLUTE_ADDR(addr),(uint8_t*)&i1,FS_ITEM_HEAD_LEN);
  601. i1.b.pro = ITEM_DEL;
  602. if(PPlus_SUCCESS != spif_write(FS_ABSOLUTE_ADDR(addr),(uint8_t*)(&i1.reg),FS_ITEM_HEAD_LEN))
  603. return PPlus_ERR_FS_WRITE_FAILED;
  604. addr += FS_ITEM_LEN;
  605. check_addr(&addr);
  606. }
  607. return PPlus_SUCCESS;
  608. }
  609. else
  610. {
  611. return PPlus_ERR_FS_NOT_FIND_ID;
  612. }
  613. }
  614. int hal_fs_garbage_collect(void)
  615. {
  616. uint8_t i,j,buf[FS_ITEM_DATA_LEN];
  617. uint8_t from_sector_index = 0,to_sector_index = 0;
  618. uint32_t addr_rd=0,addr_wr=0,addr_erase;
  619. fs_item_t i1;
  620. if(__psr()&0x3f){
  621. return PPlus_ERR_FS_IN_INT;
  622. }
  623. if(fs_init_flag == FALSE)
  624. return PPlus_ERR_FS_UNINITIALIZED;
  625. to_sector_index = fs.exchange_sector;
  626. from_sector_index = (fs.exchange_sector + 1) % fs.cfg.sector_num;
  627. addr_wr = 4096*to_sector_index;
  628. for(i = 0;i < (fs.cfg.sector_num - 1);i++)
  629. {
  630. addr_rd = 4096*((from_sector_index + i) % fs.cfg.sector_num);
  631. addr_erase = addr_rd;
  632. fs.cfg.index = i;
  633. if(PPlus_SUCCESS != spif_write(FS_ABSOLUTE_ADDR((4096*((to_sector_index + i) % fs.cfg.sector_num))),(uint8_t*)(&(fs.cfg)),sizeof(fs_cfg_t)))
  634. return PPlus_ERR_FS_WRITE_FAILED;
  635. if(i == 0)
  636. addr_wr += sizeof(fs_cfg_t);
  637. addr_rd += sizeof(fs_cfg_t);
  638. for(j = 0;j < FS_SECTOR_ITEM_NUM;j++)
  639. {
  640. spif_read(FS_ABSOLUTE_ADDR(addr_rd),(uint8_t*)&i1,FS_ITEM_HEAD_LEN);
  641. if(i1.b.pro == ITEM_USED)
  642. {
  643. spif_read(FS_ABSOLUTE_ADDR(addr_rd + FS_ITEM_HEAD_LEN),buf,FS_ITEM_DATA_LEN);
  644. if(PPlus_SUCCESS != spif_write(FS_ABSOLUTE_ADDR(addr_wr),(uint8_t*)(&i1.reg),FS_ITEM_HEAD_LEN))
  645. return PPlus_ERR_FS_WRITE_FAILED;
  646. if(PPlus_SUCCESS != spif_write(FS_ABSOLUTE_ADDR(addr_wr + FS_ITEM_HEAD_LEN),buf,FS_ITEM_DATA_LEN))
  647. return PPlus_ERR_FS_WRITE_FAILED;
  648. addr_wr += FS_ITEM_LEN;
  649. check_addr(&addr_wr);
  650. }
  651. else if(i1.b.pro == ITEM_UNUSED)
  652. {
  653. break;
  654. }
  655. addr_rd += FS_ITEM_LEN;
  656. }
  657. fs_erase_ucds_one_sector(addr_erase);
  658. }
  659. return fs_init();
  660. }
  661. int hal_fs_format(uint32_t fs_start_address,uint8_t sector_num)
  662. {
  663. if(__psr()&0x3f){
  664. return PPlus_ERR_FS_IN_INT;
  665. }
  666. fs_init_flag = FALSE;
  667. if((fs_start_address % 0x1000) || (sector_num < 3)){
  668. return PPlus_ERR_INVALID_PARAM;
  669. }
  670. fs_sector_num = sector_num;
  671. fs_offset_address = fs_start_address;
  672. fs_erase_ucds_all_sector();
  673. return hal_fs_init(fs_start_address,sector_num);
  674. }
  675. int hal_fs_init(uint32_t fs_start_address,uint8_t sector_num)
  676. {
  677. if(fs_init_flag == TRUE){
  678. return PPlus_ERR_FS_UNINITIALIZED;
  679. }
  680. if((fs_start_address % 0x1000) || (sector_num < 3)){
  681. return PPlus_ERR_INVALID_PARAM;
  682. }
  683. fs_sector_num = sector_num;
  684. fs_offset_address = fs_start_address;
  685. return fs_init();
  686. }
  687. bool hal_fs_initialized(void)
  688. {
  689. return fs_init_flag;
  690. }