123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751 |
- /*
- * spiffs_nucleus.h
- *
- * Created on: Jun 15, 2013
- * Author: petera
- */
- /* SPIFFS layout
- *
- * spiffs is designed for following spi flash characteristics:
- * - only big areas of data (blocks) can be erased
- * - erasing resets all bits in a block to ones
- * - writing pulls ones to zeroes
- * - zeroes cannot be pulled to ones, without erase
- * - wear leveling
- *
- * spiffs is also meant to be run on embedded, memory constraint devices.
- *
- * Entire area is divided in blocks. Entire area is also divided in pages.
- * Each block contains same number of pages. A page cannot be erased, but a
- * block can be erased.
- *
- * Entire area must be block_size * x
- * page_size must be block_size / (2^y) where y > 2
- *
- * ex: area = 1024*1024 bytes, block size = 65536 bytes, page size = 256 bytes
- *
- * BLOCK 0 PAGE 0 object lookup 1
- * PAGE 1 object lookup 2
- * ...
- * PAGE n-1 object lookup n
- * PAGE n object data 1
- * PAGE n+1 object data 2
- * ...
- * PAGE n+m-1 object data m
- *
- * BLOCK 1 PAGE n+m object lookup 1
- * PAGE n+m+1 object lookup 2
- * ...
- * PAGE 2n+m-1 object lookup n
- * PAGE 2n+m object data 1
- * PAGE 2n+m object data 2
- * ...
- * PAGE 2n+2m-1 object data m
- * ...
- *
- * n is number of object lookup pages, which is number of pages needed to index all pages
- * in a block by object id
- * : block_size / page_size * sizeof(obj_id) / page_size
- * m is number data pages, which is number of pages in block minus number of lookup pages
- * : block_size / page_size - block_size / page_size * sizeof(obj_id) / page_size
- * thus, n+m is total number of pages in a block
- * : block_size / page_size
- *
- * ex: n = 65536/256*2/256 = 2, m = 65536/256 - 2 = 254 => n+m = 65536/256 = 256
- *
- * Object lookup pages contain object id entries. Each entry represent the corresponding
- * data page.
- * Assuming a 16 bit object id, an object id being 0xffff represents a free page.
- * An object id being 0x0000 represents a deleted page.
- *
- * ex: page 0 : lookup : 0008 0001 0aaa ffff ffff ffff ffff ffff ..
- * page 1 : lookup : ffff ffff ffff ffff ffff ffff ffff ffff ..
- * page 2 : data : data for object id 0008
- * page 3 : data : data for object id 0001
- * page 4 : data : data for object id 0aaa
- * ...
- *
- *
- * Object data pages can be either object index pages or object content.
- * All object data pages contains a data page header, containing object id and span index.
- * The span index denotes the object page ordering amongst data pages with same object id.
- * This applies to both object index pages (when index spans more than one page of entries),
- * and object data pages.
- * An object index page contains page entries pointing to object content page. The entry index
- * in a object index page correlates to the span index in the actual object data page.
- * The first object index page (span index 0) is called object index header page, and also
- * contains object flags (directory/file), size, object name etc.
- *
- * ex:
- * BLOCK 1
- * PAGE 256: objectl lookup page 1
- * [*123] [ 123] [ 123] [ 123]
- * [ 123] [*123] [ 123] [ 123]
- * [free] [free] [free] [free] ...
- * PAGE 257: objectl lookup page 2
- * [free] [free] [free] [free] ...
- * PAGE 258: object index page (header)
- * obj.id:0123 span.ix:0000 flags:INDEX
- * size:1600 name:ex.txt type:file
- * [259] [260] [261] [262]
- * PAGE 259: object data page
- * obj.id:0123 span.ix:0000 flags:DATA
- * PAGE 260: object data page
- * obj.id:0123 span.ix:0001 flags:DATA
- * PAGE 261: object data page
- * obj.id:0123 span.ix:0002 flags:DATA
- * PAGE 262: object data page
- * obj.id:0123 span.ix:0003 flags:DATA
- * PAGE 263: object index page
- * obj.id:0123 span.ix:0001 flags:INDEX
- * [264] [265] [fre] [fre]
- * [fre] [fre] [fre] [fre]
- * PAGE 264: object data page
- * obj.id:0123 span.ix:0004 flags:DATA
- * PAGE 265: object data page
- * obj.id:0123 span.ix:0005 flags:DATA
- *
- */
- #ifndef SPIFFS_NUCLEUS_H_
- #define SPIFFS_NUCLEUS_H_
- #define _SPIFFS_ERR_CHECK_FIRST (SPIFFS_ERR_INTERNAL - 1)
- #define SPIFFS_ERR_CHECK_OBJ_ID_MISM (SPIFFS_ERR_INTERNAL - 1)
- #define SPIFFS_ERR_CHECK_SPIX_MISM (SPIFFS_ERR_INTERNAL - 2)
- #define SPIFFS_ERR_CHECK_FLAGS_BAD (SPIFFS_ERR_INTERNAL - 3)
- #define _SPIFFS_ERR_CHECK_LAST (SPIFFS_ERR_INTERNAL - 4)
- #define SPIFFS_VIS_COUNTINUE (SPIFFS_ERR_INTERNAL - 20)
- #define SPIFFS_VIS_COUNTINUE_RELOAD (SPIFFS_ERR_INTERNAL - 21)
- #define SPIFFS_VIS_END (SPIFFS_ERR_INTERNAL - 22)
- #define SPIFFS_EV_IX_UPD 0
- #define SPIFFS_EV_IX_NEW 1
- #define SPIFFS_EV_IX_DEL 2
- #define SPIFFS_OBJ_ID_IX_FLAG ((spiffs_obj_id)(1<<(8*sizeof(spiffs_obj_id)-1)))
- #define SPIFFS_UNDEFINED_LEN (u32_t)(-1)
- #define SPIFFS_OBJ_ID_DELETED ((spiffs_obj_id)0)
- #define SPIFFS_OBJ_ID_FREE ((spiffs_obj_id)-1)
- #if SPIFFS_USE_MAGIC
- #if !SPIFFS_USE_MAGIC_LENGTH
- #define SPIFFS_MAGIC(fs, bix) \
- ((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs)))
- #else // SPIFFS_USE_MAGIC_LENGTH
- #define SPIFFS_MAGIC(fs, bix) \
- ((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs) ^ ((fs)->block_count - ((bix) < 3 ? (1<<(bix)) - 1 : (bix)<<2))))
- #endif // SPIFFS_USE_MAGIC_LENGTH
- #endif // SPIFFS_USE_MAGIC
- #define SPIFFS_CONFIG_MAGIC (0x20090315)
- #if SPIFFS_SINGLETON == 0
- #define SPIFFS_CFG_LOG_PAGE_SZ(fs) \
- ((fs)->cfg.log_page_size)
- #define SPIFFS_CFG_LOG_BLOCK_SZ(fs) \
- ((fs)->cfg.log_block_size)
- #define SPIFFS_CFG_PHYS_SZ(fs) \
- ((fs)->cfg.phys_size)
- #define SPIFFS_CFG_PHYS_ERASE_SZ(fs) \
- ((fs)->cfg.phys_erase_block)
- #define SPIFFS_CFG_PHYS_ADDR(fs) \
- ((fs)->cfg.phys_addr)
- #endif
- // total number of pages
- #define SPIFFS_MAX_PAGES(fs) \
- ( SPIFFS_CFG_PHYS_SZ(fs)/SPIFFS_CFG_LOG_PAGE_SZ(fs) )
- // total number of pages per block, including object lookup pages
- #define SPIFFS_PAGES_PER_BLOCK(fs) \
- ( SPIFFS_CFG_LOG_BLOCK_SZ(fs)/SPIFFS_CFG_LOG_PAGE_SZ(fs) )
- // number of object lookup pages per block
- #define SPIFFS_OBJ_LOOKUP_PAGES(fs) \
- (MAX(1, (SPIFFS_PAGES_PER_BLOCK(fs) * sizeof(spiffs_obj_id)) / SPIFFS_CFG_LOG_PAGE_SZ(fs)) )
- // checks if page index belongs to object lookup
- #define SPIFFS_IS_LOOKUP_PAGE(fs,pix) \
- (((pix) % SPIFFS_PAGES_PER_BLOCK(fs)) < SPIFFS_OBJ_LOOKUP_PAGES(fs))
- // number of object lookup entries in all object lookup pages
- #define SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) \
- (SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))
- // converts a block to physical address
- #define SPIFFS_BLOCK_TO_PADDR(fs, block) \
- ( SPIFFS_CFG_PHYS_ADDR(fs) + (block)* SPIFFS_CFG_LOG_BLOCK_SZ(fs) )
- // converts a object lookup entry to page index
- #define SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, block, entry) \
- ((block)*SPIFFS_PAGES_PER_BLOCK(fs) + (SPIFFS_OBJ_LOOKUP_PAGES(fs) + entry))
- // converts a object lookup entry to physical address of corresponding page
- #define SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, block, entry) \
- (SPIFFS_BLOCK_TO_PADDR(fs, block) + (SPIFFS_OBJ_LOOKUP_PAGES(fs) + entry) * SPIFFS_CFG_LOG_PAGE_SZ(fs) )
- // converts a page to physical address
- #define SPIFFS_PAGE_TO_PADDR(fs, page) \
- ( SPIFFS_CFG_PHYS_ADDR(fs) + (page) * SPIFFS_CFG_LOG_PAGE_SZ(fs) )
- // converts a physical address to page
- #define SPIFFS_PADDR_TO_PAGE(fs, addr) \
- ( ((addr) - SPIFFS_CFG_PHYS_ADDR(fs)) / SPIFFS_CFG_LOG_PAGE_SZ(fs) )
- // gives index in page for a physical address
- #define SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr) \
- ( ((addr) - SPIFFS_CFG_PHYS_ADDR(fs)) % SPIFFS_CFG_LOG_PAGE_SZ(fs) )
- // returns containing block for given page
- #define SPIFFS_BLOCK_FOR_PAGE(fs, page) \
- ( (page) / SPIFFS_PAGES_PER_BLOCK(fs) )
- // returns starting page for block
- #define SPIFFS_PAGE_FOR_BLOCK(fs, block) \
- ( (block) * SPIFFS_PAGES_PER_BLOCK(fs) )
- // converts page to entry in object lookup page
- #define SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, page) \
- ( (page) % SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs) )
- // returns data size in a data page
- #define SPIFFS_DATA_PAGE_SIZE(fs) \
- ( SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header) )
- // returns physical address for block's erase count,
- // always in the physical last entry of the last object lookup page
- #define SPIFFS_ERASE_COUNT_PADDR(fs, bix) \
- ( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id) )
- // returns physical address for block's magic,
- // always in the physical second last entry of the last object lookup page
- #define SPIFFS_MAGIC_PADDR(fs, bix) \
- ( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id)*2 )
- // checks if there is any room for magic in the object luts
- #define SPIFFS_CHECK_MAGIC_POSSIBLE(fs) \
- ( (SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) % (SPIFFS_CFG_LOG_PAGE_SZ(fs)/sizeof(spiffs_obj_id))) * sizeof(spiffs_obj_id) \
- <= (SPIFFS_CFG_LOG_PAGE_SZ(fs)-sizeof(spiffs_obj_id)*2) )
- // define helpers object
- // entries in an object header page index
- #define SPIFFS_OBJ_HDR_IX_LEN(fs) \
- ((SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix_header))/sizeof(spiffs_page_ix))
- // entries in an object page index
- #define SPIFFS_OBJ_IX_LEN(fs) \
- ((SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix))/sizeof(spiffs_page_ix))
- // object index entry for given data span index
- #define SPIFFS_OBJ_IX_ENTRY(fs, spix) \
- ((spix) < SPIFFS_OBJ_HDR_IX_LEN(fs) ? (spix) : (((spix)-SPIFFS_OBJ_HDR_IX_LEN(fs))%SPIFFS_OBJ_IX_LEN(fs)))
- // object index span index number for given data span index or entry
- #define SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, spix) \
- ((spix) < SPIFFS_OBJ_HDR_IX_LEN(fs) ? 0 : (1+((spix)-SPIFFS_OBJ_HDR_IX_LEN(fs))/SPIFFS_OBJ_IX_LEN(fs)))
- #define SPIFFS_OP_T_OBJ_LU (0<<0)
- #define SPIFFS_OP_T_OBJ_LU2 (1<<0)
- #define SPIFFS_OP_T_OBJ_IX (2<<0)
- #define SPIFFS_OP_T_OBJ_DA (3<<0)
- #define SPIFFS_OP_C_DELE (0<<2)
- #define SPIFFS_OP_C_UPDT (1<<2)
- #define SPIFFS_OP_C_MOVS (2<<2)
- #define SPIFFS_OP_C_MOVD (3<<2)
- #define SPIFFS_OP_C_FLSH (4<<2)
- #define SPIFFS_OP_C_READ (5<<2)
- #define SPIFFS_OP_C_WRTHRU (6<<2)
- #define SPIFFS_OP_TYPE_MASK (3<<0)
- #define SPIFFS_OP_COM_MASK (7<<2)
- // if 0, this page is written to, else clean
- #define SPIFFS_PH_FLAG_USED (1<<0)
- // if 0, writing is finalized, else under modification
- #define SPIFFS_PH_FLAG_FINAL (1<<1)
- // if 0, this is an index page, else a data page
- #define SPIFFS_PH_FLAG_INDEX (1<<2)
- // if 0, page is deleted, else valid
- #define SPIFFS_PH_FLAG_DELET (1<<7)
- // if 0, this index header is being deleted
- #define SPIFFS_PH_FLAG_IXDELE (1<<6)
- #define SPIFFS_CHECK_MOUNT(fs) \
- ((fs)->mounted != 0)
- #define SPIFFS_CHECK_CFG(fs) \
- ((fs)->config_magic == SPIFFS_CONFIG_MAGIC)
- #define SPIFFS_CHECK_RES(res) \
- do { \
- if ((res) < SPIFFS_OK) return (res); \
- } while (0);
- #define SPIFFS_API_CHECK_MOUNT(fs) \
- if (!SPIFFS_CHECK_MOUNT((fs))) { \
- (fs)->err_code = SPIFFS_ERR_NOT_MOUNTED; \
- return SPIFFS_ERR_NOT_MOUNTED; \
- }
- #define SPIFFS_API_CHECK_CFG(fs) \
- if (!SPIFFS_CHECK_CFG((fs))) { \
- (fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED; \
- return SPIFFS_ERR_NOT_CONFIGURED; \
- }
- #define SPIFFS_API_CHECK_RES(fs, res) \
- if ((res) < SPIFFS_OK) { \
- (fs)->err_code = (res); \
- return (res); \
- }
- #define SPIFFS_API_CHECK_RES_UNLOCK(fs, res) \
- if ((res) < SPIFFS_OK) { \
- (fs)->err_code = (res); \
- SPIFFS_UNLOCK(fs); \
- return (res); \
- }
- #define SPIFFS_VALIDATE_OBJIX(ph, objid, spix) \
- if (((ph).flags & SPIFFS_PH_FLAG_USED) != 0) return SPIFFS_ERR_IS_FREE; \
- if (((ph).flags & SPIFFS_PH_FLAG_DELET) == 0) return SPIFFS_ERR_DELETED; \
- if (((ph).flags & SPIFFS_PH_FLAG_FINAL) != 0) return SPIFFS_ERR_NOT_FINALIZED; \
- if (((ph).flags & SPIFFS_PH_FLAG_INDEX) != 0) return SPIFFS_ERR_NOT_INDEX; \
- if (((objid) & SPIFFS_OBJ_ID_IX_FLAG) == 0) return SPIFFS_ERR_NOT_INDEX; \
- if ((ph).span_ix != (spix)) return SPIFFS_ERR_INDEX_SPAN_MISMATCH;
- //if ((spix) == 0 && ((ph).flags & SPIFFS_PH_FLAG_IXDELE) == 0) return SPIFFS_ERR_DELETED;
- #define SPIFFS_VALIDATE_DATA(ph, objid, spix) \
- if (((ph).flags & SPIFFS_PH_FLAG_USED) != 0) return SPIFFS_ERR_IS_FREE; \
- if (((ph).flags & SPIFFS_PH_FLAG_DELET) == 0) return SPIFFS_ERR_DELETED; \
- if (((ph).flags & SPIFFS_PH_FLAG_FINAL) != 0) return SPIFFS_ERR_NOT_FINALIZED; \
- if (((ph).flags & SPIFFS_PH_FLAG_INDEX) == 0) return SPIFFS_ERR_IS_INDEX; \
- if ((objid) & SPIFFS_OBJ_ID_IX_FLAG) return SPIFFS_ERR_IS_INDEX; \
- if ((ph).span_ix != (spix)) return SPIFFS_ERR_DATA_SPAN_MISMATCH;
- // check id
- #define SPIFFS_VIS_CHECK_ID (1<<0)
- // report argument object id to visitor - else object lookup id is reported
- #define SPIFFS_VIS_CHECK_PH (1<<1)
- // stop searching at end of all look up pages
- #define SPIFFS_VIS_NO_WRAP (1<<2)
- #if SPIFFS_HAL_CALLBACK_EXTRA
- #define SPIFFS_HAL_WRITE(_fs, _paddr, _len, _src) \
- (_fs)->cfg.hal_write_f((_fs), (_paddr), (_len), (_src))
- #define SPIFFS_HAL_READ(_fs, _paddr, _len, _dst) \
- (_fs)->cfg.hal_read_f((_fs), (_paddr), (_len), (_dst))
- #define SPIFFS_HAL_ERASE(_fs, _paddr, _len) \
- (_fs)->cfg.hal_erase_f((_fs), (_paddr), (_len))
- #else // SPIFFS_HAL_CALLBACK_EXTRA
- #define SPIFFS_HAL_WRITE(_fs, _paddr, _len, _src) \
- (_fs)->cfg.hal_write_f((_paddr), (_len), (_src))
- #define SPIFFS_HAL_READ(_fs, _paddr, _len, _dst) \
- (_fs)->cfg.hal_read_f((_paddr), (_len), (_dst))
- #define SPIFFS_HAL_ERASE(_fs, _paddr, _len) \
- (_fs)->cfg.hal_erase_f((_paddr), (_len))
- #endif // SPIFFS_HAL_CALLBACK_EXTRA
- #if SPIFFS_CACHE
- #define SPIFFS_CACHE_FLAG_DIRTY (1<<0)
- #define SPIFFS_CACHE_FLAG_WRTHRU (1<<1)
- #define SPIFFS_CACHE_FLAG_OBJLU (1<<2)
- #define SPIFFS_CACHE_FLAG_OBJIX (1<<3)
- #define SPIFFS_CACHE_FLAG_DATA (1<<4)
- #define SPIFFS_CACHE_FLAG_TYPE_WR (1<<7)
- #define SPIFFS_CACHE_PAGE_SIZE(fs) \
- (sizeof(spiffs_cache_page) + SPIFFS_CFG_LOG_PAGE_SZ(fs))
- #define spiffs_get_cache(fs) \
- ((spiffs_cache *)((fs)->cache))
- #define spiffs_get_cache_page_hdr(fs, c, ix) \
- ((spiffs_cache_page *)(&((c)->cpages[(ix) * SPIFFS_CACHE_PAGE_SIZE(fs)])))
- #define spiffs_get_cache_page(fs, c, ix) \
- ((u8_t *)(&((c)->cpages[(ix) * SPIFFS_CACHE_PAGE_SIZE(fs)])) + sizeof(spiffs_cache_page))
- // cache page struct
- typedef struct {
- // cache flags
- u8_t flags;
- // cache page index
- u8_t ix;
- // last access of this cache page
- u32_t last_access;
- union {
- // type read cache
- struct {
- // read cache page index
- spiffs_page_ix pix;
- };
- #if SPIFFS_CACHE_WR
- // type write cache
- struct {
- // write cache
- spiffs_obj_id obj_id;
- // offset in cache page
- u32_t offset;
- // size of cache page
- u16_t size;
- };
- #endif
- };
- } spiffs_cache_page;
- // cache struct
- typedef struct {
- u8_t cpage_count;
- u32_t last_access;
- u32_t cpage_use_map;
- u32_t cpage_use_mask;
- u8_t *cpages;
- } spiffs_cache;
- #endif
- // spiffs nucleus file descriptor
- typedef struct {
- // the filesystem of this descriptor
- spiffs *fs;
- // number of file descriptor - if 0, the file descriptor is closed
- spiffs_file file_nbr;
- // object id - if SPIFFS_OBJ_ID_ERASED, the file was deleted
- spiffs_obj_id obj_id;
- // size of the file
- u32_t size;
- // cached object index header page index
- spiffs_page_ix objix_hdr_pix;
- // cached offset object index page index
- spiffs_page_ix cursor_objix_pix;
- // cached offset object index span index
- spiffs_span_ix cursor_objix_spix;
- // current absolute offset
- u32_t offset;
- // current file descriptor offset
- u32_t fdoffset;
- // fd flags
- spiffs_flags flags;
- #if SPIFFS_CACHE_WR
- spiffs_cache_page *cache_page;
- #endif
- } spiffs_fd;
- // object structs
- // page header, part of each page except object lookup pages
- // NB: this is always aligned when the data page is an object index,
- // as in this case struct spiffs_page_object_ix is used
- typedef struct __attribute(( packed )) {
- // object id
- spiffs_obj_id obj_id;
- // object span index
- spiffs_span_ix span_ix;
- // flags
- u8_t flags;
- } spiffs_page_header;
- // object index header page header
- typedef struct __attribute(( packed ))
- #if SPIFFS_ALIGNED_OBJECT_INDEX_TABLES
- __attribute(( aligned(sizeof(spiffs_page_ix)) ))
- #endif
- {
- // common page header
- spiffs_page_header p_hdr;
- // alignment
- u8_t _align[4 - ((sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3))];
- // size of object
- u32_t size;
- // type of object
- spiffs_obj_type type;
- // name of object
- u8_t name[SPIFFS_OBJ_NAME_LEN];
- } spiffs_page_object_ix_header;
- // object index page header
- typedef struct __attribute(( packed )) {
- spiffs_page_header p_hdr;
- u8_t _align[4 - ((sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3))];
- } spiffs_page_object_ix;
- // callback func for object lookup visitor
- typedef s32_t (*spiffs_visitor_f)(spiffs *fs, spiffs_obj_id id, spiffs_block_ix bix, int ix_entry,
- const void *user_const_p, void *user_var_p);
- #if SPIFFS_CACHE
- #define _spiffs_rd(fs, op, fh, addr, len, dst) \
- spiffs_phys_rd((fs), (op), (fh), (addr), (len), (dst))
- #define _spiffs_wr(fs, op, fh, addr, len, src) \
- spiffs_phys_wr((fs), (op), (fh), (addr), (len), (src))
- #else
- #define _spiffs_rd(fs, op, fh, addr, len, dst) \
- spiffs_phys_rd((fs), (addr), (len), (dst))
- #define _spiffs_wr(fs, op, fh, addr, len, src) \
- spiffs_phys_wr((fs), (addr), (len), (src))
- #endif
- #ifndef MIN
- #define MIN(a,b) ((a) < (b) ? (a) : (b))
- #endif
- #ifndef MAX
- #define MAX(a,b) ((a) > (b) ? (a) : (b))
- #endif
- // ---------------
- s32_t spiffs_phys_rd(
- spiffs *fs,
- #if SPIFFS_CACHE
- u8_t op,
- spiffs_file fh,
- #endif
- u32_t addr,
- u32_t len,
- u8_t *dst);
- s32_t spiffs_phys_wr(
- spiffs *fs,
- #if SPIFFS_CACHE
- u8_t op,
- spiffs_file fh,
- #endif
- u32_t addr,
- u32_t len,
- u8_t *src);
- s32_t spiffs_phys_cpy(
- spiffs *fs,
- spiffs_file fh,
- u32_t dst,
- u32_t src,
- u32_t len);
- s32_t spiffs_phys_count_free_blocks(
- spiffs *fs);
- s32_t spiffs_obj_lu_find_entry_visitor(
- spiffs *fs,
- spiffs_block_ix starting_block,
- int starting_lu_entry,
- u8_t flags,
- spiffs_obj_id obj_id,
- spiffs_visitor_f v,
- const void *user_const_p,
- void *user_var_p,
- spiffs_block_ix *block_ix,
- int *lu_entry);
- s32_t spiffs_erase_block(
- spiffs *fs,
- spiffs_block_ix bix);
- #if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH
- s32_t spiffs_probe(
- spiffs_config *cfg);
- #endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH
- // ---------------
- s32_t spiffs_obj_lu_scan(
- spiffs *fs);
- s32_t spiffs_obj_lu_find_free_obj_id(
- spiffs *fs,
- spiffs_obj_id *obj_id,
- const u8_t *conflicting_name);
- s32_t spiffs_obj_lu_find_free(
- spiffs *fs,
- spiffs_block_ix starting_block,
- int starting_lu_entry,
- spiffs_block_ix *block_ix,
- int *lu_entry);
- s32_t spiffs_obj_lu_find_id(
- spiffs *fs,
- spiffs_block_ix starting_block,
- int starting_lu_entry,
- spiffs_obj_id obj_id,
- spiffs_block_ix *block_ix,
- int *lu_entry);
- s32_t spiffs_obj_lu_find_id_and_span(
- spiffs *fs,
- spiffs_obj_id obj_id,
- spiffs_span_ix spix,
- spiffs_page_ix exclusion_pix,
- spiffs_page_ix *pix);
- s32_t spiffs_obj_lu_find_id_and_span_by_phdr(
- spiffs *fs,
- spiffs_obj_id obj_id,
- spiffs_span_ix spix,
- spiffs_page_ix exclusion_pix,
- spiffs_page_ix *pix);
- // ---------------
- s32_t spiffs_page_allocate_data(
- spiffs *fs,
- spiffs_obj_id obj_id,
- spiffs_page_header *ph,
- u8_t *data,
- u32_t len,
- u32_t page_offs,
- u8_t finalize,
- spiffs_page_ix *pix);
- s32_t spiffs_page_move(
- spiffs *fs,
- spiffs_file fh,
- u8_t *page_data,
- spiffs_obj_id obj_id,
- spiffs_page_header *page_hdr,
- spiffs_page_ix src_pix,
- spiffs_page_ix *dst_pix);
- s32_t spiffs_page_delete(
- spiffs *fs,
- spiffs_page_ix pix);
- // ---------------
- s32_t spiffs_object_create(
- spiffs *fs,
- spiffs_obj_id obj_id,
- const u8_t name[SPIFFS_OBJ_NAME_LEN],
- spiffs_obj_type type,
- spiffs_page_ix *objix_hdr_pix);
- s32_t spiffs_object_update_index_hdr(
- spiffs *fs,
- spiffs_fd *fd,
- spiffs_obj_id obj_id,
- spiffs_page_ix objix_hdr_pix,
- u8_t *new_objix_hdr_data,
- const u8_t name[SPIFFS_OBJ_NAME_LEN],
- u32_t size,
- spiffs_page_ix *new_pix);
- void spiffs_cb_object_event(
- spiffs *fs,
- spiffs_fd *fd,
- int ev,
- spiffs_obj_id obj_id,
- spiffs_span_ix spix,
- spiffs_page_ix new_pix,
- u32_t new_size);
- s32_t spiffs_object_open_by_id(
- spiffs *fs,
- spiffs_obj_id obj_id,
- spiffs_fd *f,
- spiffs_flags flags,
- spiffs_mode mode);
- s32_t spiffs_object_open_by_page(
- spiffs *fs,
- spiffs_page_ix pix,
- spiffs_fd *f,
- spiffs_flags flags,
- spiffs_mode mode);
- s32_t spiffs_object_append(
- spiffs_fd *fd,
- u32_t offset,
- u8_t *data,
- u32_t len);
- s32_t spiffs_object_modify(
- spiffs_fd *fd,
- u32_t offset,
- u8_t *data,
- u32_t len);
- s32_t spiffs_object_read(
- spiffs_fd *fd,
- u32_t offset,
- u32_t len,
- u8_t *dst);
- s32_t spiffs_object_truncate(
- spiffs_fd *fd,
- u32_t new_len,
- u8_t remove_object);
- s32_t spiffs_object_find_object_index_header_by_name(
- spiffs *fs,
- const u8_t name[SPIFFS_OBJ_NAME_LEN],
- spiffs_page_ix *pix);
- // ---------------
- s32_t spiffs_gc_check(
- spiffs *fs,
- u32_t len);
- s32_t spiffs_gc_erase_page_stats(
- spiffs *fs,
- spiffs_block_ix bix);
- s32_t spiffs_gc_find_candidate(
- spiffs *fs,
- spiffs_block_ix **block_candidate,
- int *candidate_count,
- char fs_crammed);
- s32_t spiffs_gc_clean(
- spiffs *fs,
- spiffs_block_ix bix);
- s32_t spiffs_gc_quick(
- spiffs *fs, u16_t max_free_pages);
- // ---------------
- s32_t spiffs_fd_find_new(
- spiffs *fs,
- spiffs_fd **fd);
- s32_t spiffs_fd_return(
- spiffs *fs,
- spiffs_file f);
- s32_t spiffs_fd_get(
- spiffs *fs,
- spiffs_file f,
- spiffs_fd **fd);
- #if SPIFFS_CACHE
- void spiffs_cache_init(
- spiffs *fs);
- void spiffs_cache_drop_page(
- spiffs *fs,
- spiffs_page_ix pix);
- #if SPIFFS_CACHE_WR
- spiffs_cache_page *spiffs_cache_page_allocate_by_fd(
- spiffs *fs,
- spiffs_fd *fd);
- void spiffs_cache_fd_release(
- spiffs *fs,
- spiffs_cache_page *cp);
- spiffs_cache_page *spiffs_cache_page_get_by_fd(
- spiffs *fs,
- spiffs_fd *fd);
- #endif
- #endif
- s32_t spiffs_lookup_consistency_check(
- spiffs *fs,
- u8_t check_all_objects);
- s32_t spiffs_page_consistency_check(
- spiffs *fs);
- s32_t spiffs_object_index_consistency_check(
- spiffs *fs);
- #endif /* SPIFFS_NUCLEUS_H_ */
|