// 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; }
// allocates a new cache page and refers this to given fd - flushes an old cache // page if all cache is busy spiffs_cache_page *ICACHE_FLASH_ATTR spiffs_cache_page_allocate_by_fd(spiffs *fs, spiffs_fd *fd) { // before this function is called, it is ensured that there is no already existing // cache page with same object id spiffs_cache_page_remove_oldest(fs, SPIFFS_CACHE_FLAG_TYPE_WR, 0); spiffs_cache_page *cp = spiffs_cache_page_allocate(fs); if (cp == 0) { // could not get cache page return 0; } cp->flags = SPIFFS_CACHE_FLAG_TYPE_WR; cp->obj_id = fd->obj_id; fd->cache_page = cp; return cp; }
// 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; }