Example #1
0
int ICACHE_FLASH_ATTR roffs_mount(uint32_t flashAddress)
{
    spiffs_config cfg;
    s32_t spiffs_hal_read(u32_t addr, u32_t size, u8_t *dst);
    s32_t spiffs_hal_write(u32_t addr, u32_t size, u8_t *src);
    s32_t spiffs_hal_erase(u32_t addr, u32_t size);
    cfg.hal_read_f = spiffs_hal_read;
    cfg.hal_write_f = spiffs_hal_write;
    cfg.hal_erase_f = spiffs_hal_erase;
    int res = SPIFFS_mount(&fs,
                           &cfg,
                           spiffs_work_buf,
                           spiffs_fds, sizeof(spiffs_fds),
                           NULL, 0,
                           NULL);
    if (res != SPIFFS_OK) {
        os_printf("Formatting flash filesystem\n");
        res = SPIFFS_format(&fs);
        if (res == SPIFFS_OK) {
            res = SPIFFS_mount(&fs,
                              &cfg,
                              spiffs_work_buf,
                              spiffs_fds, sizeof(spiffs_fds),
                              NULL, 0,
                              NULL);
        }
    }

    return res == SPIFFS_OK ? 0 : -1;
}
Example #2
0
void myspiffs_mount() {
  spiffs_config cfg;
#ifdef SPIFFS_FIXED_LOCATION
  cfg.phys_addr = SPIFFS_FIXED_LOCATION;
#else
  cfg.phys_addr = ( u32_t )platform_flash_get_first_free_block_address( NULL ); 
#endif
  cfg.phys_addr += 0x3000;
  cfg.phys_addr &= 0xFFFFC000;  // align to 4 sector.
  cfg.phys_size = INTERNAL_FLASH_SIZE - ( ( u32_t )cfg.phys_addr - INTERNAL_FLASH_START_ADDRESS );
  cfg.phys_erase_block = INTERNAL_FLASH_SECTOR_SIZE; // according to datasheet
  cfg.log_block_size = INTERNAL_FLASH_SECTOR_SIZE; // let us not complicate things
  cfg.log_page_size = LOG_PAGE_SIZE; // as we said
  NODE_DBG("fs.start:%x,max:%x\n",cfg.phys_addr,cfg.phys_size);

  cfg.hal_read_f = my_spiffs_read;
  cfg.hal_write_f = my_spiffs_write;
  cfg.hal_erase_f = my_spiffs_erase;
  
  int res = SPIFFS_mount(&fs,
    &cfg,
    spiffs_work_buf,
    spiffs_fds,
    sizeof(spiffs_fds),
#if SPIFFS_CACHE
    spiffs_cache,
    sizeof(spiffs_cache),
#else
    0, 0,
#endif
    // myspiffs_check_callback);
    0);
  NODE_DBG("mount res: %i\n", res);
}
Example #3
0
int RamSpiffs::mount()
{
    spiffs_config cfg;
    cfg.phys_size = FILESYSTEM_SIZE; // 1MB
    cfg.phys_addr = 0; // start spiffs at start of memory
    cfg.phys_erase_block = FLASH_BLOCK_SIZE; // according to datasheet
    cfg.log_block_size = FLASH_BLOCK_SIZE; // let us not complicate things
    cfg.log_page_size = LOG_PAGE_SIZE; // as we said

    cfg.hal_read_f = my_spi_read;
    cfg.hal_write_f = my_spi_write;
    cfg.hal_erase_f = my_spi_erase;
    int res = SPIFFS_mount(&m_fs,
                           &cfg,
                           spiffs_work_buf,
                           spiffs_fds,
                           sizeof(spiffs_fds),
                           spiffs_cache_buf,
                           sizeof(spiffs_cache_buf),
                           0);

    if(res != 0){
        std::cout << "error mounting, err=" << res << std::endl;
    }
    return res;
}
Example #4
0
void lua_spiffs_mount() {
    spiffs_config cfg;    
    cfg.phys_size = LUA_FLASH_SIZE;
    cfg.phys_addr = LUA_START_ADDRESS; // start spiffs at start of spi flash
    cfg.phys_erase_block = 65536/2; // according to datasheet
    cfg.log_block_size = 65536; // let us not complicate things
    cfg.log_page_size = LOG_PAGE_SIZE; // as we said */
    
    cfg.hal_read_f = lspiffs_read;
    cfg.hal_write_f = lspiffs_write;
    cfg.hal_erase_f = lspiffs_erase;
    
    MicoFlashInitialize(MICO_FLASH_FOR_LUA);
    
    if(SPIFFS_mounted(&fs)) return;
    
    int res = SPIFFS_mount(&fs,
      &cfg,
      spiffs_work_buf,
      spiffs_fds,
      sizeof(spiffs_fds),
      spiffs_cache_buf,
      sizeof(spiffs_cache_buf),
      0);
}
Example #5
0
//---------------
void _mount(void)
{
  mico_logic_partition_t* part;
  spiffs_config cfg;    

  part = MicoFlashGetInfo( MICO_PARTITION_LUA );
      
  cfg.phys_size = part->partition_length;
  cfg.phys_addr = 0;                        // start at beginning of the LUA partition
  cfg.log_block_size = LOG_BLOCK_SIZE;      // logical block size
  cfg.phys_erase_block = PHYS_ERASE_BLOCK;  // logical erase block size
  cfg.log_page_size = LOG_PAGE_SIZE;        // logical page size
  
  cfg.hal_read_f = lspiffs_read;
  cfg.hal_write_f = lspiffs_write;
  cfg.hal_erase_f = lspiffs_erase;

  int res = SPIFFS_mount(&fs,
    &cfg,
    spiffs_work_buf,
    spiffs_fds,
    sizeof(spiffs_fds),
    NULL,
    0,
    NULL);
}
Example #6
0
//-----------------------
void lua_spiffs_mount() {
    mico_logic_partition_t* part;
    spiffs_config cfg;    

    part = MicoFlashGetInfo( MICO_PARTITION_LUA );
	
    cfg.phys_size = part->partition_length;
    cfg.phys_addr = part->partition_start_addr; // start spiffs at start of spi flash
    cfg.phys_erase_block = 65536/2;             // according to datasheet
    cfg.log_block_size = 65536;                 // let us not complicate things
    cfg.log_page_size = LOG_PAGE_SIZE;          // as we said */
    
    cfg.hal_read_f = lspiffs_read;
    cfg.hal_write_f = lspiffs_write;
    cfg.hal_erase_f = lspiffs_erase;
    
    //if (part == NULL)
    //    goto exit;
    //MicoFlashInitialize(MICO_FLASH_FOR_LUA);
    
    if(SPIFFS_mounted(&fs)) return;
    
    int res = SPIFFS_mount(&fs,
      &cfg,
      spiffs_work_buf,
      spiffs_fds,
      sizeof(spiffs_fds),
      spiffs_cache_buf,
      sizeof(spiffs_cache_buf),
      0);
}
Example #7
0
File: fs.c Project: pellepl/wisleep
int32_t fs_mount(void) {
  int32_t res;
  const uint32_t fs_size =
      (sdk_flashchip.chip_size / 8 - SPI_FLASH_SEC_SIZE * FS_SLACK_END_SECTORS) & ~(FS_BLOCK_SZ-1);
  const uint32_t fs_addr =
      (sdk_flashchip.chip_size - fs_size - SPI_FLASH_SEC_SIZE * FS_SLACK_END_SECTORS)  & ~(FS_BLOCK_SZ-1);
  spiffs_config cfg = {
      .hal_read_f = _spiffs_hal_read,
      .hal_write_f = _spiffs_hal_write,
      .hal_erase_f = _spiffs_hal_erase,
      .phys_size = fs_size,
      .phys_addr = fs_addr,
      .phys_erase_block = SPI_FLASH_SEC_SIZE,
      .log_block_size = FS_BLOCK_SZ,
      .log_page_size = FS_PAGE_SZ,
      .fh_ix_offset = SPIFFS_FILEHDL_OFFSET_NUM
  };
  printf("mounting fs @ 0x%08x, %i kbytes\n", fs_addr, fs_size / 1024);
  res = SPIFFS_mount(FS,
      &cfg, (uint8_t *)_fs_work,
      (uint8_t *)_fs_desc, sizeof(_fs_desc),
      (uint8_t *)_fs_cache, sizeof(_fs_cache),
      _spiffs_check_cb_f);
  if (res != SPIFFS_OK && SPIFFS_errno(FS) == SPIFFS_ERR_NOT_A_FS) {
    printf("fs format\n");
    SPIFFS_clearerr(FS);
    res = SPIFFS_format(FS);
    if (res == SPIFFS_OK) {
      printf("remount\n");
      res = SPIFFS_mount(FS,
          &cfg, (uint8_t *)_fs_work,
          (uint8_t *)_fs_desc, sizeof(_fs_desc),
          (uint8_t *)_fs_cache, sizeof(_fs_cache),
          _spiffs_check_cb_f);
    }
  }
  if (res != SPIFFS_OK) {
    printf("err fs mount %i\n", res);
  } else {
    uint32_t total, used;
    SPIFFS_info(FS, &total, &used);
    printf("mounted fs: total %i kbytes, used %i kbytes\n", total / 1024, used / 1024);
  }
  printf("mount result:%i\n", SPIFFS_errno(FS));

  return res;
}
Example #8
0
static void spiffs_mount_internal(spiffs_config *cfg)
{
  if (cfg->phys_addr == 0)
  {
	  SYSTEM_ERROR("Can't start file system, wrong address");
	  return;
  }

  debugf("fs.start: size:%d Kb, offset:0x%X\n", cfg->phys_size / 1024, cfg->phys_addr - INTERNAL_FLASH_START_ADDRESS);

  cfg->hal_read_f = api_spiffs_read;
  cfg->hal_write_f = api_spiffs_write;
  cfg->hal_erase_f = api_spiffs_erase;
  
  uint32_t dat;
  bool writeFirst = false;
  flashmem_read(&dat, cfg->phys_addr, 4);
  //debugf("%X", dat);

  if (dat == UINT32_MAX)
  {
	  debugf("First init file system");
	  spiffs_format_internal(cfg);
	  writeFirst = true;
  }

  int res = SPIFFS_mount(&_filesystemStorageHandle,
    cfg,
    spiffs_work_buf,
    spiffs_fds,
    sizeof(spiffs_fds),
    spiffs_cache,
    sizeof(spiffs_cache),
    NULL);
  debugf("mount res: %d\n", res);

  if (writeFirst)
  {
	  file_t fd = SPIFFS_open(&_filesystemStorageHandle, "initialize_fs_header.dat", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0);
	  SPIFFS_write(&_filesystemStorageHandle, fd, (u8_t *)"1", 1);
	  SPIFFS_fremove(&_filesystemStorageHandle, fd);
	  SPIFFS_close(&_filesystemStorageHandle, fd);
  }

  //dat=0;
  //flashmem_read(&dat, cfg.phys_addr, 4);
  //debugf("%X", dat);
}
Example #9
0
bool spiffs_mount() {
    spiffs_config cfg = spiffs_get_storage_config();
    if (cfg.phys_addr == 0) {
        SYSTEM_ERROR("Can't start file system, wrong address");
        return false;
    }

    debugf("fs.start:%x, size:%d Kb\n", cfg.phys_addr, cfg.phys_size / 1024);

    cfg.hal_read_f = api_spiffs_read;
    cfg.hal_write_f = api_spiffs_write;
    cfg.hal_erase_f = api_spiffs_erase;

    uint32_t dat;
    bool writeFirst = false;
    flashmem_read(&dat, cfg.phys_addr, 4);

    if (dat == UINT32_MAX) {
        debugf("First init file system");
        if(!spiffs_format_internal()) {
            SYSTEM_ERROR("Can't format file system");
            return false;
        }
        writeFirst = true;
    }

    int res = SPIFFS_mount(&_filesystemStorageHandle,
                           &cfg,
                           spiffs_work_buf,
                           spiffs_fds,
                           sizeof(spiffs_fds),
                           spiffs_cache,
                           sizeof(spiffs_cache),
                           NULL);
    debugf("mount res: %d\n", res);

    if(res != 0) return false;

    if (writeFirst) {
        file_t fd = SPIFFS_open(&_filesystemStorageHandle, "initialize_fs_header.dat", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0);
        SPIFFS_write(&_filesystemStorageHandle, fd, (u8_t *)"1", 1);
        SPIFFS_fremove(&_filesystemStorageHandle, fd);
        SPIFFS_close(&_filesystemStorageHandle, fd);
    }
    return true;
}
Example #10
0
int32_t fs_mount_specific(uint32_t phys_addr, uint32_t phys_size,
    uint32_t phys_sector_size,
    uint32_t log_block_size, uint32_t log_page_size) {
  spiffs_config c;
  c.hal_erase_f = _erase;
  c.hal_read_f = _read;
  c.hal_write_f = _write;
  c.log_block_size = log_block_size;
  c.log_page_size = log_page_size;
  c.phys_addr = phys_addr;
  c.phys_erase_block = phys_sector_size;
  c.phys_size = phys_size;
#if SPIFFS_FILEHDL_OFFSET
  c.fh_ix_offset = TEST_SPIFFS_FILEHDL_OFFSET;
#endif
  return SPIFFS_mount(&__fs, &c, _work, _fds, sizeof(_fds), _cache, sizeof(_cache), spiffs_check_cb_f);
}
int mem_spiffs_mount(void) {
  spiffs_config cfg;

  cfg.phys_size = image_size;
  cfg.phys_addr = 0;

  cfg.phys_erase_block = FLASH_BLOCK_SIZE;
  cfg.log_block_size = FLASH_BLOCK_SIZE;
  cfg.log_page_size = LOG_PAGE_SIZE;

  cfg.hal_read_f = mem_spiffs_read;
  cfg.hal_write_f = mem_spiffs_write;
  cfg.hal_erase_f = mem_spiffs_erase;

  return SPIFFS_mount(&fs, &cfg, spiffs_work_buf, spiffs_fds,
                      sizeof(spiffs_fds), 0, 0, 0);
}
Example #12
0
s32_t spiffs_mount_manual(u32_t phys_addr, u32_t phys_size)
{
  spiffs_config cfg = {0};

  // Set Spiffs HAL functions
  cfg.hal_read_f = api_spiffs_read;
  cfg.hal_write_f = api_spiffs_write;
  cfg.hal_erase_f = api_spiffs_erase;

  // Set Spiffs physical layout
  cfg.phys_erase_block = INTERNAL_FLASH_SECTOR_SIZE; // according to datasheet
  cfg.log_block_size = INTERNAL_FLASH_SECTOR_SIZE * 2; // Important to make large
  cfg.log_page_size = LOG_PAGE_SIZE; // as we said

  // Set spiffs location
  cfg.phys_addr = phys_addr;
  cfg.phys_size = phys_size;

  if (cfg.phys_size == 0)
   {
	  s32_t probeSize = SPIFFS_probe_fs(&cfg);
	  if (probeSize < 0)
      {
 	  	  return probeSize;  // Requested automatic sizing but not possible to detect
      }
	  else
 	  {
 	  	  cfg.phys_size = probeSize;
 	  }
   }

  int spiffsResult = SPIFFS_mount(&_filesystemStorageHandle,
    &cfg,
    spiffs_work_buf,
    spiffs_fds,
    sizeof(spiffs_fds),
    spiffs_cache,
    sizeof(spiffs_cache),
    NULL);
  debugf("mount res: %d\n", spiffsResult);

  debugf("fs.start: address %X, size: %d Kb, result : %d \n", cfg.phys_addr, cfg.phys_size / 1024, spiffsResult );

  return spiffsResult;
}
Example #13
0
void mem_spiffs_mount() {
  spiffs_config cfg;

  cfg.phys_size = image_size;
  cfg.phys_addr = 0;

  cfg.phys_erase_block = FLASH_BLOCK_SIZE;
  cfg.log_block_size = FLASH_BLOCK_SIZE;
  cfg.log_page_size = LOG_PAGE_SIZE;

  cfg.hal_read_f = mem_spiffs_read;
  cfg.hal_write_f = mem_spiffs_write;
  cfg.hal_erase_f = mem_spiffs_erase;

  if (SPIFFS_mount(&fs, &cfg, spiffs_work_buf, spiffs_fds, sizeof(spiffs_fds),
                   0, 0, 0) == -1) {
    fprintf(stderr, "SPIFFS_mount failed: %d\n", SPIFFS_errno(&fs));
  }
}
Example #14
0
void ICACHE_FLASH_ATTR
test_spiffs() {
  spiffs_config cfg;
  cfg.phys_size = PHYS_FLASH_SIZE; // use all spi flash
  cfg.phys_addr = SPIFFS_FLASH_SIZE; // start spiffs at start of spi flash
  cfg.phys_erase_block = SECTOR_SIZE; // according to datasheet
  cfg.log_block_size = LOG_BLOCK; // let us not complicate things
  cfg.log_page_size = LOG_PAGE; // as we said
  
  cfg.hal_read_f = my_spiffs_read;
  cfg.hal_write_f = my_spiffs_write;
  cfg.hal_erase_f = my_spiffs_erase;
  
  int res = SPIFFS_mount(&fs,
    &cfg,
    spiffs_work_buf,
    spiffs_fds,
    sizeof(spiffs_fds),
    spiffs_cache_buf,
    sizeof(spiffs_cache_buf),
    0);
  os_printf("mount res: %d\n", res);

  char buf[12];
  // Surely, I've mounted spiffs before entering here
  spiffs_file fd = SPIFFS_open(&fs, "my_file", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0);
  os_printf("fd = %d\n", fd);
  if (SPIFFS_write(&fs, fd, (u8_t *)"Hello world", 12) < 0) {
    os_printf("errno %d\n", SPIFFS_errno(&fs));
    return;
  }
  SPIFFS_close(&fs, fd); 

  fd = SPIFFS_open(&fs, "my_file", SPIFFS_RDWR, 0);
  if (SPIFFS_read(&fs, fd, (u8_t *)buf, 12) < 0) {
    os_printf("errno %d\n", SPIFFS_errno(&fs));
    return;
  }
  SPIFFS_close(&fs, fd);

  os_printf("--> %s <--\n", buf);
}
Example #15
0
ICACHE_FLASH_ATTR int fs_init() {
  spiffs_config cfg;

#if !SPIFFS_SINGLETON
  /* FS_SIZE & FS_ADDR are provided via Makefile */
  cfg.phys_size = FS_SIZE;
  cfg.phys_addr = FS_ADDR;

  cfg.phys_erase_block = FLASH_BLOCK_SIZE;
  cfg.log_block_size = FLASH_BLOCK_SIZE;
  cfg.log_page_size = LOG_PAGE_SIZE;
#endif

  cfg.hal_read_f = esp_spiffs_read;
  cfg.hal_write_f = esp_spiffs_write;
  cfg.hal_erase_f = esp_spiffs_erase;

  return SPIFFS_mount(&fs, &cfg, spiffs_work_buf, spiffs_fds,
                      sizeof(spiffs_fds), 0, 0, 0);
}
Example #16
0
void fs_reset() {
  memset(area, 0xcc, sizeof(area));
  memset(&area[SPIFFS_PHYS_ADDR], 0xff, SPIFFS_FLASH_SIZE);
  spiffs_config c;
  c.hal_erase_f = _erase;
  c.hal_read_f = _read;
  c.hal_write_f = _write;
  c.log_block_size = LOG_BLOCK;
  c.log_page_size = LOG_PAGE;
  c.phys_addr = SPIFFS_PHYS_ADDR;
  c.phys_erase_block = SECTOR_SIZE;
  c.phys_size = SPIFFS_FLASH_SIZE;
  memset(erases,0,sizeof(erases));
  memset(_cache,0,sizeof(_cache));

  SPIFFS_mount(&__fs, &c, _work, _fds, sizeof(_fds), _cache, sizeof(_cache), spiffs_check_cb_f);

  clear_flash_ops_log();
  log_flash_ops = 1;
  fs_check_fixes = 0;
}
Example #17
0
int fs_mount(spiffs *spf, uint32_t addr, uint32_t size, uint8_t *workbuf,
             uint8_t *fds, size_t fds_size) {
    spiffs_config cfg;

    /* FS_SIZE & FS_ADDR are provided via Makefile */
    cfg.phys_addr = addr;
    cfg.phys_size = size;

    cfg.phys_erase_block = FLASH_BLOCK_SIZE;
    cfg.log_block_size = FLASH_BLOCK_SIZE;
    cfg.log_page_size = LOG_PAGE_SIZE;

    cfg.hal_read_f = esp_spiffs_read;
    cfg.hal_write_f = esp_spiffs_write;
    cfg.hal_erase_f = esp_spiffs_erase;

    if (SPIFFS_mount(spf, &cfg, workbuf, fds, fds_size, 0, 0, 0) != SPIFFS_OK) {
        return SPIFFS_errno(spf);
    }

    return 0;
}
Example #18
0
int fs_mount(spiffs *spf, uint32_t addr, uint32_t size, uint8_t *workbuf,
             uint8_t *fds, size_t fds_size) {
  LOG(LL_DEBUG, ("Mount %d@%X", size, addr));
  spiffs_config cfg;

  cfg.phys_addr = addr;
  cfg.phys_size = size;

  cfg.phys_erase_block = FLASH_BLOCK_SIZE;
  cfg.log_block_size = FLASH_BLOCK_SIZE;
  cfg.log_page_size = LOG_PAGE_SIZE;

  cfg.hal_read_f = esp_spiffs_read;
  cfg.hal_write_f = esp_spiffs_write;
  cfg.hal_erase_f = esp_spiffs_erase;

  if (SPIFFS_mount(spf, &cfg, workbuf, fds, fds_size, 0, 0, 0) != SPIFFS_OK) {
    return SPIFFS_errno(spf);
  }

  return 0;
}
static _i32 fs_mount_spiffs(struct mount_info *m, _u32 fs_size, _u32 block_size,
                            _u32 page_size) {
  int r;
  spiffs_config cfg;
  cfg.hal_read_f = failfs_read;
  cfg.hal_write_f = failfs_write;
  cfg.hal_erase_f = failfs_erase;
  cfg.phys_size = fs_size;
  cfg.phys_addr = 0;
  cfg.phys_erase_block = block_size;
  cfg.log_block_size = block_size;
  cfg.log_page_size = page_size;
  m->work = calloc(2, page_size);
  m->fds_size = MAX_OPEN_SPIFFS_FILES * sizeof(spiffs_fd);
  m->fds = calloc(1, m->fds_size);
  r = SPIFFS_mount(&m->fs, &cfg, m->work, m->fds, m->fds_size, NULL, 0, NULL);
  if (r != SPIFFS_OK) {
    free(m->work);
    free(m->fds);
    m->work = m->fds = NULL;
  }
  return r;
}
Example #20
0
static bool myspiffs_mount_internal(bool force_mount) {
  spiffs_config cfg;
  if (!myspiffs_find_cfg(&cfg, force_mount) && !force_mount) {
    return FALSE;
  }

  fs.err_code = 0;

  int res = SPIFFS_mount(&fs,
    &cfg,
    spiffs_work_buf,
    spiffs_fds,
    sizeof(spiffs_fds),
#if SPIFFS_CACHE
    spiffs_cache,
    sizeof(spiffs_cache),
#else
    0, 0,
#endif
    // myspiffs_check_callback);
    0);
  NODE_DBG("mount res: %d, %d\n", res, fs.err_code);
  return res == SPIFFS_OK;
}
Example #21
0
static esp_err_t esp_spiffs_init(const esp_vfs_spiffs_conf_t* conf)
{
    int index;
    //find if such partition is already mounted
    if (esp_spiffs_by_label(conf->partition_label, &index) == ESP_OK) {
        return ESP_ERR_INVALID_STATE;
    }

    if (esp_spiffs_get_empty(&index) != ESP_OK) {
        ESP_LOGE(TAG, "max mounted partitions reached");
        return ESP_ERR_INVALID_STATE;
    }

    esp_partition_subtype_t subtype = conf->partition_label ?
            ESP_PARTITION_SUBTYPE_ANY : ESP_PARTITION_SUBTYPE_DATA_SPIFFS;
    const esp_partition_t* partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, 
                                      subtype, conf->partition_label);
    if (!partition) {
        ESP_LOGE(TAG, "spiffs partition could not be found");
        return ESP_ERR_NOT_FOUND;
    }

    if (partition->encrypted) {
        ESP_LOGE(TAG, "spiffs can not run on encrypted partition");
        return ESP_ERR_INVALID_STATE;
    }

    esp_spiffs_t * efs = malloc(sizeof(esp_spiffs_t));
    if (efs == NULL) {
        ESP_LOGE(TAG, "esp_spiffs could not be malloced");
        return ESP_ERR_NO_MEM;
    }
    memset(efs, 0, sizeof(esp_spiffs_t));

    efs->cfg.hal_erase_f       = spiffs_api_erase;
    efs->cfg.hal_read_f        = spiffs_api_read;
    efs->cfg.hal_write_f       = spiffs_api_write;
    efs->cfg.log_block_size    = g_rom_flashchip.sector_size;
    efs->cfg.log_page_size     = g_rom_flashchip.page_size;
    efs->cfg.phys_addr         = 0;
    efs->cfg.phys_erase_block  = g_rom_flashchip.sector_size;
    efs->cfg.phys_size         = partition->size;

    efs->by_label = conf->partition_label != NULL;

    efs->lock = xSemaphoreCreateMutex();
    if (efs->lock == NULL) {
        ESP_LOGE(TAG, "mutex lock could not be created");
        esp_spiffs_free(&efs);
        return ESP_ERR_NO_MEM;
    }

    efs->fds_sz = conf->max_files * sizeof(spiffs_fd);
    efs->fds = malloc(efs->fds_sz);
    if (efs->fds == NULL) {
        ESP_LOGE(TAG, "fd buffer could not be malloced");
        esp_spiffs_free(&efs);
        return ESP_ERR_NO_MEM;
    }
    memset(efs->fds, 0, efs->fds_sz);

#if SPIFFS_CACHE
    efs->cache_sz = sizeof(spiffs_cache) + conf->max_files * (sizeof(spiffs_cache_page)
                          + efs->cfg.log_page_size);
    efs->cache = malloc(efs->cache_sz);
    if (efs->cache == NULL) {
        ESP_LOGE(TAG, "cache buffer could not be malloced");
        esp_spiffs_free(&efs);
        return ESP_ERR_NO_MEM;
    }
    memset(efs->cache, 0, efs->cache_sz);
#endif

    const uint32_t work_sz = efs->cfg.log_page_size * 2;
    efs->work = malloc(work_sz);
    if (efs->work == NULL) {
        ESP_LOGE(TAG, "work buffer could not be malloced");
        esp_spiffs_free(&efs);
        return ESP_ERR_NO_MEM;
    }
    memset(efs->work, 0, work_sz);

    efs->fs = malloc(sizeof(spiffs));
    if (efs->fs == NULL) {
        ESP_LOGE(TAG, "spiffs could not be malloced");
        esp_spiffs_free(&efs);
        return ESP_ERR_NO_MEM;
    }
    memset(efs->fs, 0, sizeof(spiffs));

    efs->fs->user_data = (void *)efs;
    efs->partition = partition;

    s32_t res = SPIFFS_mount(efs->fs, &efs->cfg, efs->work, efs->fds, efs->fds_sz, 
                            efs->cache, efs->cache_sz, spiffs_api_check);

    if (conf->format_if_mount_failed && res != SPIFFS_OK) {
        ESP_LOGW(TAG, "mount failed, %i. formatting...", SPIFFS_errno(efs->fs));
        SPIFFS_clearerr(efs->fs);
        res = SPIFFS_format(efs->fs);
        if (res != SPIFFS_OK) {
            ESP_LOGE(TAG, "format failed, %i", SPIFFS_errno(efs->fs));
            SPIFFS_clearerr(efs->fs);
            esp_spiffs_free(&efs);
            return ESP_FAIL;
        }
        res = SPIFFS_mount(efs->fs, &efs->cfg, efs->work, efs->fds, efs->fds_sz, 
                            efs->cache, efs->cache_sz, spiffs_api_check);
    }
    if (res != SPIFFS_OK) {
        ESP_LOGE(TAG, "mount failed, %i", SPIFFS_errno(efs->fs));
        SPIFFS_clearerr(efs->fs);
        esp_spiffs_free(&efs);
        return ESP_FAIL;
    }
    _efs[index] = efs;
    return ESP_OK;
}