예제 #1
0
// 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;
}
예제 #2
0
// 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);
  }
}
예제 #3
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;
}
예제 #4
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);
  }
}
예제 #5
0
// 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);
  }
}