// reads from spi flash or the cache s32_t spiffs_phys_rd( spiffs *fs, u8_t op, spiffs_file fh, u32_t addr, u32_t len, u8_t *dst) { (void)fh; s32_t res = SPIFFS_OK; spiffs_cache *cache = spiffs_get_cache(fs); spiffs_cache_page *cp = spiffs_cache_page_get(fs, SPIFFS_PADDR_TO_PAGE(fs, addr)); cache->last_access++; if (cp) { // we've already got one, you see #if SPIFFS_CACHE_STATS fs->cache_hits++; #endif cp->last_access = cache->last_access; u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); memcpy(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len); } else { if ((op & SPIFFS_OP_TYPE_MASK) == SPIFFS_OP_T_OBJ_LU2) { // for second layer lookup functions, we do not cache in order to prevent shredding return SPIFFS_HAL_READ(fs, addr, len, dst); } #if SPIFFS_CACHE_STATS fs->cache_misses++; #endif // this operation will always free one cache page (unless all already free), // the result code stems from the write operation of the possibly freed cache page res = spiffs_cache_page_remove_oldest(fs, SPIFFS_CACHE_FLAG_TYPE_WR, 0); cp = spiffs_cache_page_allocate(fs); if (cp) { cp->flags = SPIFFS_CACHE_FLAG_WRTHRU; cp->pix = SPIFFS_PADDR_TO_PAGE(fs, addr); s32_t res2 = SPIFFS_HAL_READ(fs, addr - SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr), SPIFFS_CFG_LOG_PAGE_SZ(fs), spiffs_get_cache_page(fs, cache, cp->ix)); if (res2 != SPIFFS_OK) { // honor read failure before possible write failure (bad idea?) res = res2; } u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); memcpy(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len); } else { // this will never happen, last resort for sake of symmetry s32_t res2 = SPIFFS_HAL_READ(fs, addr, len, dst); if (res2 != SPIFFS_OK) { // honor read failure before possible write failure (bad idea?) res = res2; } } } return res; }
// reads from spi flash or the cache s32_t ICACHE_FLASH_ATTR spiffs_phys_rd( spiffs *fs, u8_t op, spiffs_file fh, u32_t addr, u32_t len, u8_t *dst) { (void)fh; s32_t res = SPIFFS_OK; spiffs_cache *cache = spiffs_get_cache(fs); spiffs_cache_page *cp = spiffs_cache_page_get(fs, SPIFFS_PADDR_TO_PAGE(fs, addr)); cache->last_access++; if (cp) { #if SPIFFS_CACHE_STATS fs->cache_hits++; #endif cp->last_access = cache->last_access; } else { if ((op & SPIFFS_OP_TYPE_MASK) == SPIFFS_OP_T_OBJ_LU2) { // for second layer lookup functions, we do not cache in order to prevent shredding return fs->cfg.hal_read_f( addr , len, dst); } #if SPIFFS_CACHE_STATS fs->cache_misses++; #endif res = spiffs_cache_page_remove_oldest(fs, SPIFFS_CACHE_FLAG_TYPE_WR, 0); cp = spiffs_cache_page_allocate(fs); if (cp) { cp->flags = SPIFFS_CACHE_FLAG_WRTHRU; cp->pix = SPIFFS_PADDR_TO_PAGE(fs, addr); } s32_t res2 = fs->cfg.hal_read_f( addr - SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr), SPIFFS_CFG_LOG_PAGE_SZ(fs), spiffs_get_cache_page(fs, cache, cp->ix)); if (res2 != SPIFFS_OK) { res = res2; } } u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); memcpy(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len); return res; }
// 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); } }