// removes the oldest accessed cached page static s32_t ICACHE_FLASH_ATTR spiffs_cache_page_remove_oldest(spiffs *fs, u8_t flag_mask, u8_t flags) { s32_t res = SPIFFS_OK; spiffs_cache *cache = spiffs_get_cache(fs); if ((cache->cpage_use_map & cache->cpage_use_mask) != cache->cpage_use_mask) { // at least one free cpage return SPIFFS_OK; } // all busy, scan thru all to find the cpage which has oldest access int i; int cand_ix = -1; u32_t oldest_val = 0; for (i = 0; i < cache->cpage_count; i++) { spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); if ((cache->last_access - cp->last_access) > oldest_val && (cp->flags & flag_mask) == flags) { oldest_val = cache->last_access - cp->last_access; cand_ix = i; } } if (cand_ix >= 0) { res = spiffs_cache_page_free(fs, cand_ix, 1); } return res; }
// drops the cache page for give page index void ICACHE_FLASH_ATTR spiffs_cache_drop_page(spiffs *fs, spiffs_page_ix pix) { spiffs_cache_page *cp = spiffs_cache_page_get(fs, pix); if (cp) { spiffs_cache_page_free(fs, cp->ix, 0); } }
// unrefers all fds that this cache page refers to and releases the cache page void ICACHE_FLASH_ATTR spiffs_cache_fd_release(spiffs *fs, spiffs_cache_page *cp) { if (cp == 0) return; int i; spiffs_fd *fds = (spiffs_fd *)fs->fd_space; for (i = 0; i < fs->fd_count; i++) { spiffs_fd *cur_fd = &fds[i]; if (cur_fd->file_nbr != 0 && cur_fd->cache_page == cp) { cur_fd->cache_page = 0; } } spiffs_cache_page_free(fs, cp->ix, 0); cp->obj_id = 0; }
// writes to spi flash and/or the cache s32_t ICACHE_FLASH_ATTR spiffs_phys_wr( spiffs *fs, u8_t op, spiffs_file fh, u32_t addr, u32_t len, u8_t *src) { (void)fh; spiffs_page_ix pix = SPIFFS_PADDR_TO_PAGE(fs, addr); spiffs_cache *cache = spiffs_get_cache(fs); spiffs_cache_page *cp = spiffs_cache_page_get(fs, pix); if (cp && (op & SPIFFS_OP_COM_MASK) != SPIFFS_OP_C_WRTHRU) { // have a cache page // copy in data to cache page if ((op & SPIFFS_OP_COM_MASK) == SPIFFS_OP_C_DELE && (op & SPIFFS_OP_TYPE_MASK) != SPIFFS_OP_T_OBJ_LU) { // page is being deleted, wipe from cache - unless it is a lookup page spiffs_cache_page_free(fs, cp->ix, 0); return fs->cfg.hal_write_f(addr, len, src); } u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); memcpy(&mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], src, len); cache->last_access++; cp->last_access = cache->last_access; if (cp->flags && SPIFFS_CACHE_FLAG_WRTHRU) { // page is being updated, no write-cache, just pass thru return fs->cfg.hal_write_f(addr, len, src); } else { return SPIFFS_OK; } } else { // no cache page, no write cache - just write thru return fs->cfg.hal_write_f(addr, len, src); } }
// drops the cache page for give page index void spiffs_cache_drop_page(spiffs *fs, spiffs_page_ix pix) { spiffs_cache_page *cp = spiffs_cache_page_get(fs, pix); if (cp) { spiffs_cache_page_free(fs, cp->ix, 0); } }