110 #ifndef SPIFFS_NUCLEUS_H_ 111 #define SPIFFS_NUCLEUS_H_ 113 #define _SPIFFS_ERR_CHECK_FIRST (SPIFFS_ERR_INTERNAL - 1) 114 #define SPIFFS_ERR_CHECK_OBJ_ID_MISM (SPIFFS_ERR_INTERNAL - 1) 115 #define SPIFFS_ERR_CHECK_SPIX_MISM (SPIFFS_ERR_INTERNAL - 2) 116 #define SPIFFS_ERR_CHECK_FLAGS_BAD (SPIFFS_ERR_INTERNAL - 3) 117 #define _SPIFFS_ERR_CHECK_LAST (SPIFFS_ERR_INTERNAL - 4) 120 #define SPIFFS_VIS_COUNTINUE (SPIFFS_ERR_INTERNAL - 20) 122 #define SPIFFS_VIS_COUNTINUE_RELOAD (SPIFFS_ERR_INTERNAL - 21) 124 #define SPIFFS_VIS_END (SPIFFS_ERR_INTERNAL - 22) 127 #define SPIFFS_EV_IX_UPD (0) 129 #define SPIFFS_EV_IX_NEW (1) 131 #define SPIFFS_EV_IX_DEL (2) 133 #define SPIFFS_EV_IX_MOV (3) 135 #define SPIFFS_EV_IX_UPD_HDR (4) 137 #define SPIFFS_OBJ_ID_IX_FLAG ((spiffs_obj_id)(1<<(8*sizeof(spiffs_obj_id)-1))) 139 #define SPIFFS_UNDEFINED_LEN (u32_t)(-1) 141 #define SPIFFS_OBJ_ID_DELETED ((spiffs_obj_id)0) 142 #define SPIFFS_OBJ_ID_FREE ((spiffs_obj_id)-1) 146 #if defined(__GNUC__) || defined(__clang__) || defined(__TI_COMPILER_VERSION__) 148 #define SPIFFS_PACKED __attribute__((packed)) 149 #elif defined(__ICCARM__) || defined(__CC_ARM) 151 #define SPIFFS_PACKED 155 #define SPIFFS_PACKED 161 #if !SPIFFS_USE_MAGIC_LENGTH 162 #define SPIFFS_MAGIC(fs, bix) \ 163 ((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs))) 164 #else // SPIFFS_USE_MAGIC_LENGTH 165 #define SPIFFS_MAGIC(fs, bix) \ 166 ((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs) ^ ((fs)->block_count - (bix)))) 167 #endif // SPIFFS_USE_MAGIC_LENGTH 168 #endif // SPIFFS_USE_MAGIC 170 #define SPIFFS_CONFIG_MAGIC (0x20090315) 172 #if SPIFFS_SINGLETON == 0 173 #define SPIFFS_CFG_LOG_PAGE_SZ(fs) \ 174 ((fs)->cfg.log_page_size) 175 #define SPIFFS_CFG_LOG_BLOCK_SZ(fs) \ 176 ((fs)->cfg.log_block_size) 177 #define SPIFFS_CFG_PHYS_SZ(fs) \ 178 ((fs)->cfg.phys_size) 179 #define SPIFFS_CFG_PHYS_ERASE_SZ(fs) \ 180 ((fs)->cfg.phys_erase_block) 181 #define SPIFFS_CFG_PHYS_ADDR(fs) \ 182 ((fs)->cfg.phys_addr) 186 #define SPIFFS_MAX_PAGES(fs) \ 187 ( SPIFFS_CFG_PHYS_SZ(fs)/SPIFFS_CFG_LOG_PAGE_SZ(fs) ) 189 #define SPIFFS_PAGES_PER_BLOCK(fs) \ 190 ( SPIFFS_CFG_LOG_BLOCK_SZ(fs)/SPIFFS_CFG_LOG_PAGE_SZ(fs) ) 192 #define SPIFFS_OBJ_LOOKUP_PAGES(fs) \ 193 (MAX(1, (SPIFFS_PAGES_PER_BLOCK(fs) * sizeof(spiffs_obj_id)) / SPIFFS_CFG_LOG_PAGE_SZ(fs)) ) 195 #define SPIFFS_IS_LOOKUP_PAGE(fs,pix) \ 196 (((pix) % SPIFFS_PAGES_PER_BLOCK(fs)) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) 198 #define SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) \ 199 (SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs)) 201 #define SPIFFS_BLOCK_TO_PADDR(fs, block) \ 202 ( SPIFFS_CFG_PHYS_ADDR(fs) + (block)* SPIFFS_CFG_LOG_BLOCK_SZ(fs) ) 204 #define SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, block, entry) \ 205 ((block)*SPIFFS_PAGES_PER_BLOCK(fs) + (SPIFFS_OBJ_LOOKUP_PAGES(fs) + entry)) 207 #define SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, block, entry) \ 208 (SPIFFS_BLOCK_TO_PADDR(fs, block) + (SPIFFS_OBJ_LOOKUP_PAGES(fs) + entry) * SPIFFS_CFG_LOG_PAGE_SZ(fs) ) 210 #define SPIFFS_PAGE_TO_PADDR(fs, page) \ 211 ( SPIFFS_CFG_PHYS_ADDR(fs) + (page) * SPIFFS_CFG_LOG_PAGE_SZ(fs) ) 213 #define SPIFFS_PADDR_TO_PAGE(fs, addr) \ 214 ( ((addr) - SPIFFS_CFG_PHYS_ADDR(fs)) / SPIFFS_CFG_LOG_PAGE_SZ(fs) ) 216 #define SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr) \ 217 ( ((addr) - SPIFFS_CFG_PHYS_ADDR(fs)) % SPIFFS_CFG_LOG_PAGE_SZ(fs) ) 219 #define SPIFFS_BLOCK_FOR_PAGE(fs, page) \ 220 ( (page) / SPIFFS_PAGES_PER_BLOCK(fs) ) 222 #define SPIFFS_PAGE_FOR_BLOCK(fs, block) \ 223 ( (block) * SPIFFS_PAGES_PER_BLOCK(fs) ) 225 #define SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, page) \ 226 ( (page) % SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs) ) 228 #define SPIFFS_DATA_PAGE_SIZE(fs) \ 229 ( SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header) ) 232 #define SPIFFS_ERASE_COUNT_PADDR(fs, bix) \ 233 ( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id) ) 236 #define SPIFFS_MAGIC_PADDR(fs, bix) \ 237 ( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id)*2 ) 239 #define SPIFFS_CHECK_MAGIC_POSSIBLE(fs) \ 240 ( (SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) % (SPIFFS_CFG_LOG_PAGE_SZ(fs)/sizeof(spiffs_obj_id))) * sizeof(spiffs_obj_id) \ 241 <= (SPIFFS_CFG_LOG_PAGE_SZ(fs)-sizeof(spiffs_obj_id)*2) ) 246 #define SPIFFS_OBJ_HDR_IX_LEN(fs) \ 247 ((SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix_header))/sizeof(spiffs_page_ix)) 249 #define SPIFFS_OBJ_IX_LEN(fs) \ 250 ((SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix))/sizeof(spiffs_page_ix)) 252 #define SPIFFS_OBJ_IX_ENTRY(fs, spix) \ 253 ((spix) < SPIFFS_OBJ_HDR_IX_LEN(fs) ? (spix) : (((spix)-SPIFFS_OBJ_HDR_IX_LEN(fs))%SPIFFS_OBJ_IX_LEN(fs))) 255 #define SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, spix) \ 256 ((spix) < SPIFFS_OBJ_HDR_IX_LEN(fs) ? 0 : (1+((spix)-SPIFFS_OBJ_HDR_IX_LEN(fs))/SPIFFS_OBJ_IX_LEN(fs))) 258 #define SPIFFS_DATA_SPAN_IX_FOR_OBJ_IX_SPAN_IX(fs, spix) \ 259 ( (spix) == 0 ? 0 : (SPIFFS_OBJ_HDR_IX_LEN(fs) + (((spix)-1) * SPIFFS_OBJ_IX_LEN(fs))) ) 261 #if SPIFFS_FILEHDL_OFFSET 262 #define SPIFFS_FH_OFFS(fs, fh) ((fh) != 0 ? ((fh) + (fs)->cfg.fh_ix_offset) : 0) 263 #define SPIFFS_FH_UNOFFS(fs, fh) ((fh) != 0 ? ((fh) - (fs)->cfg.fh_ix_offset) : 0) 265 #define SPIFFS_FH_OFFS(fs, fh) (fh) 266 #define SPIFFS_FH_UNOFFS(fs, fh) (fh) 270 #define SPIFFS_OP_T_OBJ_LU (0<<0) 271 #define SPIFFS_OP_T_OBJ_LU2 (1<<0) 272 #define SPIFFS_OP_T_OBJ_IX (2<<0) 273 #define SPIFFS_OP_T_OBJ_DA (3<<0) 274 #define SPIFFS_OP_C_DELE (0<<2) 275 #define SPIFFS_OP_C_UPDT (1<<2) 276 #define SPIFFS_OP_C_MOVS (2<<2) 277 #define SPIFFS_OP_C_MOVD (3<<2) 278 #define SPIFFS_OP_C_FLSH (4<<2) 279 #define SPIFFS_OP_C_READ (5<<2) 280 #define SPIFFS_OP_C_WRTHRU (6<<2) 282 #define SPIFFS_OP_TYPE_MASK (3<<0) 283 #define SPIFFS_OP_COM_MASK (7<<2) 287 #define SPIFFS_PH_FLAG_USED (1<<0) 289 #define SPIFFS_PH_FLAG_FINAL (1<<1) 291 #define SPIFFS_PH_FLAG_INDEX (1<<2) 293 #define SPIFFS_PH_FLAG_DELET (1<<7) 295 #define SPIFFS_PH_FLAG_IXDELE (1<<6) 298 #define SPIFFS_CHECK_MOUNT(fs) \ 301 #define SPIFFS_CHECK_CFG(fs) \ 302 ((fs)->config_magic == SPIFFS_CONFIG_MAGIC) 304 #define SPIFFS_CHECK_RES(res) \ 306 if ((res) < SPIFFS_OK) return (res); \ 309 #define SPIFFS_API_CHECK_MOUNT(fs) \ 310 if (!SPIFFS_CHECK_MOUNT((fs))) { \ 311 (fs)->err_code = SPIFFS_ERR_NOT_MOUNTED; \ 312 return SPIFFS_ERR_NOT_MOUNTED; \ 315 #define SPIFFS_API_CHECK_CFG(fs) \ 316 if (!SPIFFS_CHECK_CFG((fs))) { \ 317 (fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED; \ 318 return SPIFFS_ERR_NOT_CONFIGURED; \ 321 #define SPIFFS_API_CHECK_RES(fs, res) \ 322 if ((res) < SPIFFS_OK) { \ 323 (fs)->err_code = (res); \ 327 #define SPIFFS_API_CHECK_RES_UNLOCK(fs, res) \ 328 if ((res) < SPIFFS_OK) { \ 329 (fs)->err_code = (res); \ 334 #define SPIFFS_VALIDATE_OBJIX(ph, objid, spix) \ 335 if (((ph).flags & SPIFFS_PH_FLAG_USED) != 0) return SPIFFS_ERR_IS_FREE; \ 336 if (((ph).flags & SPIFFS_PH_FLAG_DELET) == 0) return SPIFFS_ERR_DELETED; \ 337 if (((ph).flags & SPIFFS_PH_FLAG_FINAL) != 0) return SPIFFS_ERR_NOT_FINALIZED; \ 338 if (((ph).flags & SPIFFS_PH_FLAG_INDEX) != 0) return SPIFFS_ERR_NOT_INDEX; \ 339 if (((objid) & SPIFFS_OBJ_ID_IX_FLAG) == 0) return SPIFFS_ERR_NOT_INDEX; \ 340 if ((ph).span_ix != (spix)) return SPIFFS_ERR_INDEX_SPAN_MISMATCH; 343 #define SPIFFS_VALIDATE_DATA(ph, objid, spix) \ 344 if (((ph).flags & SPIFFS_PH_FLAG_USED) != 0) return SPIFFS_ERR_IS_FREE; \ 345 if (((ph).flags & SPIFFS_PH_FLAG_DELET) == 0) return SPIFFS_ERR_DELETED; \ 346 if (((ph).flags & SPIFFS_PH_FLAG_FINAL) != 0) return SPIFFS_ERR_NOT_FINALIZED; \ 347 if (((ph).flags & SPIFFS_PH_FLAG_INDEX) == 0) return SPIFFS_ERR_IS_INDEX; \ 348 if ((objid) & SPIFFS_OBJ_ID_IX_FLAG) return SPIFFS_ERR_IS_INDEX; \ 349 if ((ph).span_ix != (spix)) return SPIFFS_ERR_DATA_SPAN_MISMATCH; 353 #define SPIFFS_VIS_CHECK_ID (1<<0) 355 #define SPIFFS_VIS_CHECK_PH (1<<1) 357 #define SPIFFS_VIS_NO_WRAP (1<<2) 359 #if SPIFFS_HAL_CALLBACK_EXTRA 361 #define SPIFFS_HAL_WRITE(_fs, _paddr, _len, _src) \ 362 (_fs)->cfg.hal_write_f((_fs), (_paddr), (_len), (_src)) 363 #define SPIFFS_HAL_READ(_fs, _paddr, _len, _dst) \ 364 (_fs)->cfg.hal_read_f((_fs), (_paddr), (_len), (_dst)) 365 #define SPIFFS_HAL_ERASE(_fs, _paddr, _len) \ 366 (_fs)->cfg.hal_erase_f((_fs), (_paddr), (_len)) 368 #else // SPIFFS_HAL_CALLBACK_EXTRA 370 #define SPIFFS_HAL_WRITE(_fs, _paddr, _len, _src) \ 371 (_fs)->cfg.hal_write_f((_paddr), (_len), (_src)) 372 #define SPIFFS_HAL_READ(_fs, _paddr, _len, _dst) \ 373 (_fs)->cfg.hal_read_f((_paddr), (_len), (_dst)) 374 #define SPIFFS_HAL_ERASE(_fs, _paddr, _len) \ 375 (_fs)->cfg.hal_erase_f((_paddr), (_len)) 377 #endif // SPIFFS_HAL_CALLBACK_EXTRA 381 #define SPIFFS_CACHE_FLAG_DIRTY (1<<0) 382 #define SPIFFS_CACHE_FLAG_WRTHRU (1<<1) 383 #define SPIFFS_CACHE_FLAG_OBJLU (1<<2) 384 #define SPIFFS_CACHE_FLAG_OBJIX (1<<3) 385 #define SPIFFS_CACHE_FLAG_DATA (1<<4) 386 #define SPIFFS_CACHE_FLAG_TYPE_WR (1<<7) 388 #define SPIFFS_CACHE_PAGE_SIZE(fs) \ 389 (sizeof(spiffs_cache_page) + SPIFFS_CFG_LOG_PAGE_SZ(fs)) 391 #define spiffs_get_cache(fs) \ 392 ((spiffs_cache *)((fs)->cache)) 394 #define spiffs_get_cache_page_hdr(fs, c, ix) \ 395 ((spiffs_cache_page *)(&((c)->cpages[(ix) * SPIFFS_CACHE_PAGE_SIZE(fs)]))) 397 #define spiffs_get_cache_page(fs, c, ix) \ 398 ((u8_t *)(&((c)->cpages[(ix) * SPIFFS_CACHE_PAGE_SIZE(fs)])) + sizeof(spiffs_cache_page)) 418 spiffs_obj_id obj_id;
433 u32_t cpage_use_mask;
445 spiffs_file file_nbr;
447 spiffs_obj_id obj_id;
451 spiffs_page_ix objix_hdr_pix;
453 spiffs_page_ix cursor_objix_pix;
455 spiffs_span_ix cursor_objix_spix;
463 spiffs_cache_page *cache_page;
465 #if SPIFFS_TEMPORAL_FD_CACHE 485 spiffs_obj_id obj_id;
487 spiffs_span_ix span_ix;
494 #if SPIFFS_ALIGNED_OBJECT_INDEX_TABLES
495 __attribute(( aligned(sizeof(spiffs_page_ix)) ))
505 spiffs_obj_type type;
507 u8_t name[SPIFFS_OBJ_NAME_LEN];
508 #if SPIFFS_OBJ_META_LEN 510 u8_t meta[SPIFFS_OBJ_META_LEN];
521 typedef s32_t (*spiffs_visitor_f)(
spiffs *fs, spiffs_obj_id id, spiffs_block_ix bix,
int ix_entry,
522 const void *user_const_p,
void *user_var_p);
526 #define _spiffs_rd(fs, op, fh, addr, len, dst) \ 527 spiffs_phys_rd((fs), (op), (fh), (addr), (len), (dst)) 528 #define _spiffs_wr(fs, op, fh, addr, len, src) \ 529 spiffs_phys_wr((fs), (op), (fh), (addr), (len), (src)) 531 #define _spiffs_rd(fs, op, fh, addr, len, dst) \ 532 spiffs_phys_rd((fs), (addr), (len), (dst)) 533 #define _spiffs_wr(fs, op, fh, addr, len, src) \ 534 spiffs_phys_wr((fs), (addr), (len), (src)) 538 #define MIN(a,b) ((a) < (b) ? (a) : (b)) 541 #define MAX(a,b) ((a) > (b) ? (a) : (b)) 546 s32_t spiffs_phys_rd(
556 s32_t spiffs_phys_wr(
566 s32_t spiffs_phys_cpy(
573 s32_t spiffs_phys_count_free_blocks(
576 s32_t spiffs_obj_lu_find_entry_visitor(
578 spiffs_block_ix starting_block,
579 int starting_lu_entry,
581 spiffs_obj_id obj_id,
583 const void *user_const_p,
585 spiffs_block_ix *block_ix,
588 s32_t spiffs_erase_block(
590 spiffs_block_ix bix);
592 #if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH 595 #endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH 599 s32_t spiffs_obj_lu_scan(
602 s32_t spiffs_obj_lu_find_free_obj_id(
604 spiffs_obj_id *obj_id,
605 const u8_t *conflicting_name);
607 s32_t spiffs_obj_lu_find_free(
609 spiffs_block_ix starting_block,
610 int starting_lu_entry,
611 spiffs_block_ix *block_ix,
614 s32_t spiffs_obj_lu_find_id(
616 spiffs_block_ix starting_block,
617 int starting_lu_entry,
618 spiffs_obj_id obj_id,
619 spiffs_block_ix *block_ix,
622 s32_t spiffs_obj_lu_find_id_and_span(
624 spiffs_obj_id obj_id,
626 spiffs_page_ix exclusion_pix,
627 spiffs_page_ix *pix);
629 s32_t spiffs_obj_lu_find_id_and_span_by_phdr(
631 spiffs_obj_id obj_id,
633 spiffs_page_ix exclusion_pix,
634 spiffs_page_ix *pix);
638 s32_t spiffs_page_allocate_data(
640 spiffs_obj_id obj_id,
646 spiffs_page_ix *pix);
648 s32_t spiffs_page_move(
652 spiffs_obj_id obj_id,
654 spiffs_page_ix src_pix,
655 spiffs_page_ix *dst_pix);
657 s32_t spiffs_page_delete(
663 s32_t spiffs_object_create(
665 spiffs_obj_id obj_id,
668 spiffs_obj_type type,
669 spiffs_page_ix *objix_hdr_pix);
671 s32_t spiffs_object_update_index_hdr(
674 spiffs_obj_id obj_id,
675 spiffs_page_ix objix_hdr_pix,
676 u8_t *new_objix_hdr_data,
680 spiffs_page_ix *new_pix);
684 s32_t spiffs_populate_ix_map(
687 u32_t vec_entry_start,
688 u32_t vec_entry_end);
692 void spiffs_cb_object_event(
696 spiffs_obj_id obj_id,
698 spiffs_page_ix new_pix,
701 s32_t spiffs_object_open_by_id(
703 spiffs_obj_id obj_id,
708 s32_t spiffs_object_open_by_page(
715 s32_t spiffs_object_append(
721 s32_t spiffs_object_modify(
727 s32_t spiffs_object_read(
733 s32_t spiffs_object_truncate(
738 s32_t spiffs_object_find_object_index_header_by_name(
740 const u8_t name[SPIFFS_OBJ_NAME_LEN],
741 spiffs_page_ix *pix);
745 s32_t spiffs_gc_check(
749 s32_t spiffs_gc_erase_page_stats(
751 spiffs_block_ix bix);
753 s32_t spiffs_gc_find_candidate(
755 spiffs_block_ix **block_candidate,
756 int *candidate_count,
759 s32_t spiffs_gc_clean(
761 spiffs_block_ix bix);
763 s32_t spiffs_gc_quick(
764 spiffs *fs, u16_t max_free_pages);
768 s32_t spiffs_fd_find_new(
773 s32_t spiffs_fd_return(
782 #if SPIFFS_TEMPORAL_FD_CACHE 783 void spiffs_fd_temporal_cache_rehash(
785 const char *old_path,
786 const char *new_path);
790 void spiffs_cache_init(
793 void spiffs_cache_drop_page(
798 spiffs_cache_page *spiffs_cache_page_allocate_by_fd(
802 void spiffs_cache_fd_release(
804 spiffs_cache_page *cp);
806 spiffs_cache_page *spiffs_cache_page_get_by_fd(
812 s32_t spiffs_lookup_consistency_check(
814 u8_t check_all_objects);
816 s32_t spiffs_page_consistency_check(
819 s32_t spiffs_object_index_consistency_check(
825 #define _SPIFFS_MEMCPY(__d, __s, __l) do { \ 826 intptr_t __a1 = (intptr_t)((u8_t*)(__s)); \ 827 intptr_t __a2 = (intptr_t)((u8_t*)(__s)+(__l)); \ 828 intptr_t __b1 = (intptr_t)((u8_t*)(__d)); \ 829 intptr_t __b2 = (intptr_t)((u8_t*)(__d)+(__l)); \ 830 if (__a1 <= __b2 && __b1 <= __a2) { \ 831 printf("FATAL OVERLAP: memcpy from %lx..%lx to %lx..%lx\n", __a1, __a2, __b1, __b2); \ 834 memcpy((__d),(__s),(__l)); \ 837 #ifndef _SPIFFS_MEMCPY 838 #define _SPIFFS_MEMCPY(__d, __s, __l) do{memcpy((__d),(__s),(__l));}while(0) 840 #endif //_SPIFFS_TEST
Definition: spiffs_nucleus.h:483
Definition: spiffs_nucleus.h:441