You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

543 lines
18 KiB

1 year ago
1 year ago
1 year ago
  1. #include "zeeprom_fs.h"
  2. #include "one_conduction_board.h"
  3. static zeeprom_header_t m_eeprom_header;
  4. static bool m_is_init = false;
  5. static filehandler_t m_filehandler[2];
  6. static int m_fd_off;
  7. /*******************************************************************************
  8. * *
  9. *******************************************************************************/
  10. static filehandler_t* filehandler_find(int fd);
  11. static filehandler_t* filehandler_alloc();
  12. static void filehandler_rlease(int fd);
  13. static int32_t sector_mgr_find_earliest_file_created_index();
  14. static int32_t sector_mgr_free_sector(int32_t fileuuid);
  15. static zeeprom_sector_info_t* sector_mgr_find_idle_sector();
  16. static bool sector_mgr_sector_is_open(int32_t fileuuid);
  17. static zeeprom_sector_info_t* sector_mgr_force_find_idle_sector();
  18. static void sector_mgr_open_sector(int32_t fileuuid);
  19. static void sector_mgr_close_sector(int32_t fileuuid);
  20. // static zeeprom_sector_info_t* sector_mgr_find_fileheader(int32_t fileuuid);
  21. static zeeprom_sector_info_t* sector_mgr_find_end_sector(int32_t fileuuid);
  22. static zeeprom_sector_info_t* sector_mgr_find_sector(int32_t fileuuid, int32_t sector_index_in_file);
  23. static int32_t sector_mgr_file_get_size(int32_t fileuuid);
  24. static zeeprom_sector_info_t* sector_mgr_find_fileheader_by_filename(uint8_t* fileid);
  25. static int32_t sector_mgr_get_sector_offset(zeeprom_sector_info_t* sector);
  26. static int32_t sector_mgr_get_sector_rom_add(zeeprom_sector_info_t* sector);
  27. static void zeeprom_read(int32_t add, uint8_t* data, uint16_t len);
  28. static void zeeprom_write(int32_t add, const uint8_t* data, uint16_t len);
  29. static int32_t compute_checksum(uint8_t* data, uint16_t len);
  30. /*******************************************************************************
  31. * CODE *
  32. *******************************************************************************/
  33. static bool m_eeprom_header_inited = false;
  34. int zeeprom_fs_init() { //
  35. SingleLeadECG_eeprom_init();
  36. if (!m_eeprom_header_inited) {
  37. zeeprom_read(0, (uint8_t*)&m_eeprom_header, sizeof(m_eeprom_header));
  38. int32_t checksum_val = compute_checksum((uint8_t*)&m_eeprom_header, sizeof(m_eeprom_header) - sizeof(m_eeprom_header.checksum));
  39. if (checksum_val != m_eeprom_header.checksum) {
  40. memset(&m_eeprom_header, 0, sizeof(m_eeprom_header));
  41. }
  42. }
  43. m_is_init = true;
  44. m_eeprom_header_inited = true;
  45. return 0;
  46. }
  47. int zeeprom_fs_uinit() { //
  48. // zeeprom_write(0, (uint8_t*)&m_eeprom_header, sizeof(m_eeprom_header));
  49. SingleLeadECG_eeprom_uninit();
  50. m_is_init = false;
  51. return 0;
  52. }
  53. zeeprom_header_t* zeeprom_fs_get_header() { return &m_eeprom_header; }
  54. int zeeprom_fs_open(uint8_t* filename, wrflag_t wrflag) {
  55. ZASSERT(m_is_init);
  56. /**
  57. * @brief
  58. * 1. ļѾڣļ
  59. * 2. ļڣ 򴴽ļ
  60. *
  61. * ļ:
  62. * 1. ҵһ
  63. * 2. ʼļͷ
  64. */
  65. filehandler_t* fileHander = filehandler_alloc();
  66. if (!fileHander) {
  67. ZLOGI("fileHander_alloc fail");
  68. return -1;
  69. }
  70. if (wrflag == kwrflag_write_only) {
  71. /*******************************************************************************
  72. * дļ *
  73. *******************************************************************************/
  74. zeeprom_sector_info_t* sectorHeaderInfo = NULL;
  75. zeeprom_fs_delete_by_name(filename);
  76. sectorHeaderInfo = sector_mgr_force_find_idle_sector();
  77. if (!sectorHeaderInfo) {
  78. ZLOGE("sector_mgr_force_find_idle_sector fail");
  79. filehandler_rlease(fileHander->fd);
  80. return -1;
  81. }
  82. memset(sectorHeaderInfo, 0, sizeof(zeeprom_sector_info_t));
  83. sectorHeaderInfo->usage = 1;
  84. sectorHeaderInfo->opened = 1;
  85. memcpy(sectorHeaderInfo->filename, filename, 8);
  86. sectorHeaderInfo->sector_index_in_file = 0;
  87. sectorHeaderInfo->datalen = 0;
  88. sectorHeaderInfo->fileuuid = m_eeprom_header.fileuuid++;
  89. fileHander->fileuuid = sectorHeaderInfo->fileuuid;
  90. fileHander->sector_header = sectorHeaderInfo;
  91. fileHander->file_offset = 0;
  92. fileHander->file_size = 0;
  93. return fileHander->fd;
  94. } else {
  95. /*******************************************************************************
  96. * ļ *
  97. *******************************************************************************/
  98. zeeprom_sector_info_t* sectorHeaderInfo = sector_mgr_find_fileheader_by_filename(filename);
  99. if (sectorHeaderInfo) {
  100. fileHander->fileuuid = sectorHeaderInfo->fileuuid;
  101. fileHander->file_offset = 0;
  102. fileHander->fd = fileHander->fd;
  103. fileHander->sector_header = sectorHeaderInfo;
  104. fileHander->file_size = sector_mgr_file_get_size(fileHander->fileuuid);
  105. memcpy(fileHander->filename, filename, 8);
  106. memcpy(fileHander->usrdata, sectorHeaderInfo->usrdata, sizeof(sectorHeaderInfo->usrdata));
  107. sector_mgr_open_sector(fileHander->fileuuid);
  108. return fileHander->fd;
  109. } else {
  110. filehandler_rlease(fileHander->fd);
  111. return -1;
  112. }
  113. }
  114. }
  115. int zeeprom_fs_write(int fileid, const uint8_t* data, int32_t size) {
  116. ZASSERT(m_is_init);
  117. filehandler_t* fileHander = NULL;
  118. zeeprom_sector_info_t* header_sinfo = NULL;
  119. zeeprom_sector_info_t* endsector = NULL;
  120. int32_t wadd = 0;
  121. ZASSERT(size == 256);
  122. fileHander = filehandler_find(fileid);
  123. if (!fileHander) {
  124. ZLOGE("fileHander_find fail");
  125. return -1;
  126. }
  127. header_sinfo = fileHander->sector_header;
  128. if (!header_sinfo) {
  129. ZLOGE("header_sinfo fail");
  130. return -1;
  131. }
  132. endsector = sector_mgr_find_end_sector(fileHander->fileuuid);
  133. if (!endsector) {
  134. ZLOGE("sector_mgr_find_end_sector fail");
  135. return -1;
  136. }
  137. if (endsector->datalen + size > EEPROM_SECTOR_SIZE) {
  138. ZLOGE("endsector->datalen + size > EEPROM_SECTOR_SIZE");
  139. return -1;
  140. }
  141. wadd = sector_mgr_get_sector_rom_add(endsector);
  142. if (wadd < 0) {
  143. ZLOGE("sector_mgr_get_sector_rom_add fail");
  144. return -1;
  145. }
  146. ZASSERT(wadd % 256 == 0);
  147. ZASSERT(wadd >= EEPROM_SECTOR_SIZE);
  148. zeeprom_write(wadd + endsector->datalen, data, size);
  149. endsector->datalen = endsector->datalen + size;
  150. fileHander->file_offset += size;
  151. fileHander->file_size += size;
  152. if (endsector->datalen == EEPROM_SECTOR_SIZE) {
  153. zeeprom_sector_info_t* newsector = sector_mgr_force_find_idle_sector();
  154. if (!newsector) {
  155. ZLOGE("sector_mgr_force_find_idle_sector fail");
  156. return -1;
  157. }
  158. memset(newsector, 0, sizeof(zeeprom_sector_info_t));
  159. newsector->usage = 1;
  160. newsector->opened = 1;
  161. memcpy(newsector->filename, header_sinfo->filename, 8);
  162. newsector->sector_index_in_file = endsector->sector_index_in_file + 1;
  163. newsector->datalen = 0;
  164. newsector->fileuuid = header_sinfo->fileuuid;
  165. }
  166. return size;
  167. }
  168. int zeeprom_fs_close(int fileid) {
  169. ZASSERT(m_is_init);
  170. filehandler_t* fileHander = filehandler_find(fileid);
  171. if (!fileHander) {
  172. ZLOGE("zeeprom_fs_close fileHander_find fail");
  173. return -1;
  174. }
  175. sector_mgr_close_sector(fileHander->fileuuid);
  176. int32_t checksum_val = compute_checksum((uint8_t*)&m_eeprom_header, sizeof(m_eeprom_header) - sizeof(m_eeprom_header.checksum));
  177. m_eeprom_header.checksum = checksum_val;
  178. // zeeprom_write(0, (uint8_t*)&m_eeprom_header, sizeof(m_eeprom_header));
  179. filehandler_rlease(fileid);
  180. return 0;
  181. }
  182. int zeeprom_fs_get_filesize_by_fd(int fd) {
  183. ZASSERT(m_is_init);
  184. filehandler_t* fileHander = filehandler_find(fd);
  185. if (!fileHander) return 0;
  186. return fileHander->file_size;
  187. }
  188. int zeeprom_fs_read(int fileid, uint8_t* data, int32_t size) {
  189. ZASSERT(m_is_init);
  190. /**
  191. * @brief
  192. * ҵǰ
  193. */
  194. ZASSERT(size == 256);
  195. filehandler_t* fileHander = filehandler_find(fileid);
  196. if (!fileHander) return -1;
  197. zeeprom_sector_info_t* header_sinfo = fileHander->sector_header;
  198. if (!header_sinfo) {
  199. return -1;
  200. }
  201. int32_t sector_idx = fileHander->file_offset / EEPROM_SECTOR_SIZE;
  202. int32_t sector_off = fileHander->file_offset % EEPROM_SECTOR_SIZE;
  203. zeeprom_sector_info_t* sector = sector_mgr_find_sector(fileHander->fileuuid, sector_idx);
  204. if (!sector) {
  205. return -1;
  206. }
  207. int32_t radd = sector_mgr_get_sector_rom_add(sector);
  208. ZASSERT(radd % 256 == 0);
  209. radd += sector_off;
  210. zeeprom_read(radd, data, size);
  211. fileHander->file_offset += size;
  212. return size;
  213. }
  214. int zeeprom_fs_delete(int32_t fileuuid) {
  215. ZASSERT(m_is_init);
  216. sector_mgr_free_sector(fileuuid);
  217. return 0;
  218. }
  219. int zeeprom_fs_delete_by_name(uint8_t* filename) {
  220. ZASSERT(m_is_init);
  221. zeeprom_sector_info_t* sectorHeaderInfo = sector_mgr_find_fileheader_by_filename(filename);
  222. if (sectorHeaderInfo) {
  223. sector_mgr_free_sector(sectorHeaderInfo->fileuuid);
  224. }
  225. return 0;
  226. }
  227. int zeeprom_fs_get_file_num() {
  228. ZASSERT(m_is_init);
  229. int count = 0;
  230. for (int i = 0; i < MAX_SECTOR_NUM; i++) {
  231. zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
  232. if (sinfo->usage == 1 && sinfo->sector_index_in_file == 0) {
  233. count++;
  234. }
  235. }
  236. return count;
  237. }
  238. int zeeprom_fs_delete_the_oldest_file() {
  239. ZASSERT(m_is_init);
  240. int32_t earliest_file_created_index = sector_mgr_find_earliest_file_created_index();
  241. sector_mgr_free_sector(earliest_file_created_index);
  242. return 0;
  243. }
  244. int zeeprom_fs_get_filesize_by_fileuuid(int32_t fileuuid) {
  245. ZASSERT(m_is_init);
  246. return sector_mgr_file_get_size(fileuuid);
  247. }
  248. static void zeeprom_read(int32_t add, uint8_t* data, uint16_t len) { //
  249. int wrsize = EEPROM_SECTOR_MIN_WR_SIZE;
  250. int readTimes = len / wrsize;
  251. int readRemain = len % wrsize;
  252. for (int i = 0; i < readTimes; i++) {
  253. SingleLeadECG_eeprom_read(add + i * wrsize, data + i * wrsize, wrsize);
  254. }
  255. if (readRemain > 0) {
  256. SingleLeadECG_eeprom_read(add + readTimes * wrsize, data + readTimes * wrsize, readRemain);
  257. }
  258. }
  259. static void zeeprom_write(int32_t add, const uint8_t* data, uint16_t len) {
  260. int wrsize = EEPROM_SECTOR_MIN_WR_SIZE;
  261. int writeTimes = len / wrsize;
  262. int writeRemain = len % wrsize;
  263. for (int i = 0; i < writeTimes; i++) {
  264. // int pageoff = add / wrsize + i;
  265. int32_t writeadd = add + i * wrsize;
  266. SingleLeadECG_eeprom_write(writeadd, data + i * wrsize, wrsize);
  267. }
  268. if (writeRemain > 0) {
  269. int32_t writeadd = add + writeTimes * wrsize;
  270. SingleLeadECG_eeprom_write(writeadd, data + writeTimes * wrsize, writeRemain);
  271. }
  272. }
  273. static int32_t compute_checksum(uint8_t* data, uint16_t len) {
  274. int32_t sum = 0;
  275. for (int i = 0; i < len; i++) {
  276. sum += data[i];
  277. }
  278. return sum;
  279. }
  280. /*******************************************************************************
  281. * filehandler *
  282. *******************************************************************************/
  283. static filehandler_t* filehandler_find(int fd) {
  284. for (int i = 0; i < ZARRAY_SIZE(m_filehandler); i++) {
  285. if (m_filehandler[i].fd == fd) {
  286. return &m_filehandler[i];
  287. }
  288. }
  289. return NULL;
  290. }
  291. static filehandler_t* filehandler_alloc() {
  292. for (int i = 0; i < ZARRAY_SIZE(m_filehandler); i++) {
  293. if (m_filehandler[i].fd == 0) {
  294. m_filehandler[i].fd = ++m_fd_off;
  295. return &m_filehandler[i];
  296. }
  297. }
  298. return NULL;
  299. }
  300. static void filehandler_rlease(int fd) {
  301. for (int i = 0; i < ZARRAY_SIZE(m_filehandler); i++) {
  302. if (m_filehandler[i].fd == fd) {
  303. m_filehandler[i].fd = 0;
  304. return;
  305. }
  306. }
  307. }
  308. /*******************************************************************************
  309. * sector_mgr *
  310. *******************************************************************************/
  311. // �������紴�����ļ���file_created_index
  312. static int32_t sector_mgr_find_earliest_file_created_index() {
  313. int32_t earliest_file_created_index = INT32_MAX;
  314. for (int i = 0; i < MAX_SECTOR_NUM; i++) {
  315. zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
  316. if (sinfo->usage == 1) {
  317. if (sinfo->fileuuid < earliest_file_created_index) {
  318. earliest_file_created_index = sinfo->fileuuid;
  319. }
  320. }
  321. }
  322. return earliest_file_created_index;
  323. }
  324. // ɾ���ļ�
  325. static int32_t sector_mgr_free_sector(int32_t fileuuid) {
  326. for (int i = 0; i < MAX_SECTOR_NUM; i++) {
  327. zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
  328. if (sinfo->usage == 1 && sinfo->fileuuid == fileuuid) {
  329. sinfo->usage = 0;
  330. }
  331. }
  332. return 0;
  333. }
  334. //
  335. static zeeprom_sector_info_t* sector_mgr_find_idle_sector() {
  336. for (int i = 0; i < MAX_SECTOR_NUM; i++) {
  337. zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
  338. if (sinfo->usage == 0) {
  339. return sinfo;
  340. }
  341. }
  342. return NULL;
  343. }
  344. static bool sector_mgr_sector_is_open(int32_t fileuuid) {
  345. for (int i = 0; i < MAX_SECTOR_NUM; i++) {
  346. zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
  347. if (sinfo->usage == 1 && sinfo->fileuuid == fileuuid) {
  348. return sinfo->opened;
  349. }
  350. }
  351. return false;
  352. }
  353. static zeeprom_sector_info_t* sector_mgr_force_find_idle_sector() {
  354. /**
  355. * @brief ҿ
  356. */
  357. zeeprom_sector_info_t* ret_sinfo = sector_mgr_find_idle_sector();
  358. if (ret_sinfo) return ret_sinfo;
  359. /**
  360. * @brief ļ
  361. */
  362. int32_t earliest_file_created_index = sector_mgr_find_earliest_file_created_index();
  363. if (sector_mgr_sector_is_open(earliest_file_created_index)) {
  364. return NULL;
  365. }
  366. /**
  367. * @brief ɾļ
  368. */
  369. sector_mgr_free_sector(earliest_file_created_index);
  370. /**
  371. * @brief ²ҿ
  372. */
  373. ret_sinfo = sector_mgr_find_idle_sector();
  374. if (ret_sinfo) return ret_sinfo;
  375. return NULL;
  376. }
  377. static void sector_mgr_open_sector(int32_t fileuuid) {
  378. for (int i = 0; i < MAX_SECTOR_NUM; i++) {
  379. zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
  380. if (sinfo->usage == 1 && sinfo->fileuuid == fileuuid) {
  381. sinfo->opened = true;
  382. }
  383. }
  384. }
  385. static void sector_mgr_close_sector(int32_t fileuuid) {
  386. for (int i = 0; i < MAX_SECTOR_NUM; i++) {
  387. zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
  388. if (sinfo->usage == 1 && sinfo->fileuuid == fileuuid) {
  389. sinfo->opened = false;
  390. }
  391. }
  392. }
  393. // static zeeprom_sector_info_t* sector_mgr_find_fileheader(int32_t fileuuid) {
  394. // for (int i = 0; i < MAX_SECTOR_NUM; i++) {
  395. // zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
  396. // if (sinfo->usage == 1 && sinfo->sector_index_in_file == 0 && sinfo->fileuuid == fileuuid) {
  397. // return sinfo;
  398. // }
  399. // }
  400. // return NULL;
  401. // }
  402. static zeeprom_sector_info_t* sector_mgr_find_sector(int32_t fileuuid, int32_t sector_index_in_file) {
  403. for (int i = 0; i < MAX_SECTOR_NUM; i++) {
  404. zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
  405. if (sinfo->usage == 1 && sinfo->sector_index_in_file == sector_index_in_file && sinfo->fileuuid == fileuuid) {
  406. return sinfo;
  407. }
  408. }
  409. return NULL;
  410. }
  411. static zeeprom_sector_info_t* sector_mgr_find_end_sector(int32_t fileuuid) {
  412. int32_t maxsectorindex = 0;
  413. for (int i = 0; i < MAX_SECTOR_NUM; i++) {
  414. zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
  415. if (sinfo->usage == 1 && sinfo->fileuuid == fileuuid) {
  416. if (sinfo->sector_index_in_file >= maxsectorindex) {
  417. maxsectorindex = sinfo->sector_index_in_file;
  418. }
  419. }
  420. }
  421. return sector_mgr_find_sector(fileuuid, maxsectorindex);
  422. }
  423. static zeeprom_sector_info_t* sector_mgr_find_fileheader_by_filename(uint8_t* fileid) {
  424. for (int i = 0; i < MAX_SECTOR_NUM; i++) {
  425. zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
  426. if (sinfo->usage == 1 && sinfo->sector_index_in_file == 0 && memcmp(sinfo->filename, fileid, 8) == 0) {
  427. return sinfo;
  428. }
  429. }
  430. return NULL;
  431. }
  432. static int32_t sector_mgr_get_sector_offset(zeeprom_sector_info_t* sector) {
  433. for (int i = 0; i < MAX_SECTOR_NUM; i++) {
  434. zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
  435. if (sinfo == sector) {
  436. return i;
  437. }
  438. }
  439. return -1;
  440. }
  441. static int32_t sector_mgr_get_sector_rom_add(zeeprom_sector_info_t* sector) {
  442. int32_t offset = sector_mgr_get_sector_offset(sector);
  443. if (offset < 0) return -1;
  444. return (offset + 1) * EEPROM_SECTOR_SIZE;
  445. }
  446. static int32_t sector_mgr_file_get_size(int32_t fileuuid) {
  447. int32_t filesize = 0;
  448. for (int i = 0; i < MAX_SECTOR_NUM; i++) {
  449. zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
  450. if (sinfo->usage == 1 && sinfo->fileuuid == fileuuid) {
  451. filesize += sinfo->datalen;
  452. }
  453. }
  454. return filesize;
  455. }
  456. static const char* filename2str(uint8_t* filename) {
  457. static char filename_str[32];
  458. sprintf(filename_str, "%02x%02x%02x%02x%02x%02x%02x%02x", filename[0], filename[1], filename[2], filename[3], filename[4], filename[5], filename[6], filename[7]);
  459. return filename_str;
  460. }
  461. int zeeprom_fs_dump_sector_state() {
  462. ZLOGI_BLOCK("zeeprom_fs_dump_sector_state\n");
  463. for (int i = 0; i < MAX_SECTOR_NUM; i++) {
  464. zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
  465. if (sinfo->usage == 1) {
  466. ZLOGI_BLOCK("[%d]: usage=%d opened=%d", i, sinfo->usage, sinfo->opened);
  467. ZLOGI_BLOCK(" fname=%s, index_in_file=%d, datalen=%d, fileuuid=%d", filename2str(sinfo->filename), sinfo->sector_index_in_file, sinfo->datalen, sinfo->fileuuid);
  468. } else {
  469. ZLOGI_BLOCK("[%d]: usage=%d", i, sinfo->usage);
  470. }
  471. }
  472. return 0;
  473. }