int64_t sj_get_storage_free_space() { struct mount_info *m = &s_fsm; uint32_t total, used; if (!m->valid) return set_errno(EBADF); SPIFFS_info(&m->fs, &total, &used); return total - used; }
esp_err_t esp_spiffs_info(const char* partition_label, size_t *total_bytes, size_t *used_bytes) { int index; if (esp_spiffs_by_label(partition_label, &index) != ESP_OK) { return ESP_ERR_INVALID_STATE; } SPIFFS_info(_efs[index]->fs, total_bytes, used_bytes); return ESP_OK; }
} TEST_END TEST(spiffs_12) { fs_reset_specific(0x4024c000, 0x4024c000 + 0, 192*1024, 4096, 4096*2, 256); int res; spiffs_file fd; int j = 1; while (1) { char fname[32]; sprintf(fname, "file%i.txt", j); fd = SPIFFS_open(FS, fname, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_DIRECT, 0); if (fd <=0) break; int i; res = SPIFFS_OK; for (i = 1; i <= 100; i++) { char *buf = "0123456789ABCDE\n"; res = SPIFFS_write(FS, fd, buf, strlen(buf)); if (res < 0) break; } SPIFFS_close(FS, fd); j++; } int errno = SPIFFS_errno(FS); TEST_CHECK(errno == SPIFFS_ERR_FULL); u32_t total; u32_t used; SPIFFS_info(FS, &total, &used); printf("total:%i (%iK)\nused:%i (%iK)\nremain:%i (%iK)\nerrno:%i\n", total, total/1024, used, used/1024, total-used, (total-used)/1024, errno); spiffs_DIR d; struct spiffs_dirent e; struct spiffs_dirent *pe = &e; SPIFFS_opendir(FS, "/", &d); while ((pe = SPIFFS_readdir(&d, pe))) { printf("%s [%04x] size:%i\n", pe->name, pe->obj_id, pe->size); } SPIFFS_closedir(&d); //SPIFFS_vis(FS); //dump_page(FS, 0); //dump_page(FS, 1); return TEST_RES_OK; } TEST_END
} TEST_END TEST(nodemcu_309) { fs_reset_specific(0, 0, 4096*20, 4096, 4096, 256); int res; spiffs_file fd; int j; for (j = 1; j <= 3; j++) { char fname[32]; sprintf(fname, "20K%i.txt", j); fd = SPIFFS_open(FS, fname, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_DIRECT, 0); TEST_CHECK(fd > 0); int i; spiffs_stat s; res = SPIFFS_OK; u8_t err = 0; for (i = 1; i <= 1280; i++) { char *buf = "0123456789ABCDE\n"; res = SPIFFS_write(FS, fd, buf, strlen(buf)); if (!err && res < 0) { printf("err @ %i,%i\n", i, j); err = 1; } } } int errno = SPIFFS_errno(FS); TEST_CHECK(errno == SPIFFS_ERR_FULL); u32_t total; u32_t used; SPIFFS_info(FS, &total, &used); printf("total:%i\nused:%i\nremain:%i\nerrno:%i\n", total, used, total-used, errno); //TEST_CHECK(total-used < 11000); // disabled, depends on too many variables spiffs_DIR d; struct spiffs_dirent e; struct spiffs_dirent *pe = &e; SPIFFS_opendir(FS, "/", &d); int spoon_guard = 0; while ((pe = SPIFFS_readdir(&d, pe))) { printf("%s [%04x] size:%i\n", pe->name, pe->obj_id, pe->size); TEST_CHECK(spoon_guard++ < 3); } TEST_CHECK(spoon_guard == 3); SPIFFS_closedir(&d); return TEST_RES_OK; } TEST_END
//file.info() //================================== static int file_info( lua_State* L ) { uint32_t total, used; SPIFFS_info(&fs, &total, &used); if(total>2000000 || used>2000000 || used > total) { return luaL_error(L, "file system error");; } lua_pushinteger(L, total-used); lua_pushinteger(L, used); lua_pushinteger(L, total); return 3; }
// Lua: fsinfo() static int file_fsinfo( lua_State* L ) { uint32_t total, used; SPIFFS_info(&fs, &total, &used); NODE_DBG("total: %d, used:%d\n", total, used); if(total>0x7FFFFFFF || used>0x7FFFFFFF || used > total) { return luaL_error(L, "file system error");; } lua_pushinteger(L, total-used); lua_pushinteger(L, used); lua_pushinteger(L, total); return 3; }
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; }
int main(int argc, char **argv) { const char *root_dir; DIR *dir; if (argc < 3) { fprintf(stderr, "usage: %s <size> <root_dir>\n", argv[0]); return 1; } image_size = atoi(argv[1]); if (image_size == 0) { fprintf(stderr, "invalid size '%s'\n", argv[1]); return 1; } root_dir = argv[2]; image = malloc(image_size); if (image == NULL) { fprintf(stderr, "cannot allocate %lu bytes\n", image_size); return 1; } mem_spiffs_erase(0, image_size); mem_spiffs_mount(); // Will fail but is required. SPIFFS_format(&fs); if (mem_spiffs_mount() != SPIFFS_OK) { fprintf(stderr, "SPIFFS_mount failed: %d\n", SPIFFS_errno(&fs)); return 1; } fprintf(stderr, "adding files in directory %s\n", root_dir); if ((dir = opendir(root_dir)) == NULL) { fprintf(stderr, "unable to open directory %s\n", root_dir); return 1; } else { read_dir(dir, root_dir); } fwrite(image, image_size, 1, stdout); u32_t total, used; SPIFFS_info(&fs, &total, &used); fprintf(stderr, "Image stats: size=%u, space: total=%u, used=%u, free=%u\n", (unsigned int) image_size, total, used, total - used); return 0; }
//================================== static int file_recv( lua_State* L ) { int32_t fsize = 0; uint8_t c, gnm; char fnm[SPIFFS_OBJ_NAME_LEN]; char buff[LUAL_BUFFERSIZE]; spiffs_DIR d; struct spiffs_dirent e; struct spiffs_dirent *pe = &e; uint32_t total, used; SPIFFS_info(&fs, &total, &used); if(total>2000000 || used>2000000 || used > total) { return luaL_error(L, "file system error");; } gnm = 0; if (lua_gettop(L) == 1 && lua_type( L, 1 ) == LUA_TSTRING) { size_t len; const char *fname = luaL_checklstring( L, 1, &len ); if (len > 0 && len < SPIFFS_OBJ_NAME_LEN) { // use given file name for (c=0; c<len; c++) { fnm[c] = fname[c]; } fnm[len] = '\0'; gnm = 1; } } if (FILE_NOT_OPENED != file_fd) { SPIFFS_close(&fs,file_fd); file_fd = FILE_NOT_OPENED; } l_message(NULL,"Start Ymodem file transfer..."); while (MicoUartRecv( MICO_UART_1, &c, 1, 10 ) == kNoErr) {} fsize = Ymodem_Receive(fnm, total-used-10000, gnm); luaWdgReload(); mico_thread_msleep(500); while (MicoUartRecv( MICO_UART_1, &c, 1, 10 ) == kNoErr) {} if (FILE_NOT_OPENED != file_fd) { SPIFFS_fflush(&fs,file_fd); SPIFFS_close(&fs,file_fd); file_fd = FILE_NOT_OPENED; } mico_thread_msleep(500); if (fsize > 0) { sprintf(buff,"\r\nReceived successfully, %d\r\n",fsize); l_message(NULL,buff); } else if (fsize == -1) { l_message(NULL,"\r\nFile write error!\r\n"); } else if (fsize == -2) { l_message(NULL,"\r\nFile open error!\r\n"); } else if (fsize == -3) { l_message(NULL,"\r\nAborted.\r\n"); } else if (fsize == -4) { l_message(NULL,"\r\nFile size too big, aborted.\r\n"); } else { l_message(NULL,"\r\nReceive failed!"); } if (fsize > 0) { SPIFFS_opendir(&fs, "/", &d); while ((pe = SPIFFS_readdir(&d, pe))) { sprintf(buff," %-32s size: %i", pe->name, pe->size); l_message(NULL,buff); } SPIFFS_closedir(&d); } return 0; }
s32_t SPIFFS_vis(spiffs *fs) { s32_t res = SPIFFS_OK; SPIFFS_API_CHECK_CFG(fs); SPIFFS_API_CHECK_MOUNT(fs); SPIFFS_LOCK(fs); int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; spiffs_block_ix bix = 0; while (bix < fs->block_count) { // check each object lookup page int obj_lookup_page = 0; int cur_entry = 0; while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { int entry_offset = obj_lookup_page * entries_per_page; res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); // check each entry while (res == SPIFFS_OK && cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; if (cur_entry == 0) { spiffs_printf("%4i ", bix); } else if ((cur_entry & 0x3f) == 0) { spiffs_printf(" "); } if (obj_id == SPIFFS_OBJ_ID_FREE) { spiffs_printf(SPIFFS_TEST_VIS_FREE_STR); } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { spiffs_printf(SPIFFS_TEST_VIS_DELE_STR); } else if (obj_id & SPIFFS_OBJ_ID_IX_FLAG){ spiffs_printf(SPIFFS_TEST_VIS_INDX_STR(obj_id)); } else { spiffs_printf(SPIFFS_TEST_VIS_DATA_STR(obj_id)); } cur_entry++; if ((cur_entry & 0x3f) == 0) { spiffs_printf("\n"); } } // per entry obj_lookup_page++; } // per object lookup page spiffs_obj_id erase_count; res = _spiffs_rd(fs, SPIFFS_OP_C_READ | SPIFFS_OP_T_OBJ_LU2, 0, SPIFFS_ERASE_COUNT_PADDR(fs, bix), sizeof(spiffs_obj_id), (u8_t *)&erase_count); SPIFFS_CHECK_RES(res); if (erase_count != (spiffs_obj_id)-1) { spiffs_printf("\tera_cnt: %i\n", erase_count); } else { spiffs_printf("\tera_cnt: N/A\n"); } bix++; } // per block spiffs_printf("era_cnt_max: %i\n", fs->max_erase_count); spiffs_printf("last_errno: %i\n", fs->err_code); spiffs_printf("blocks: %i\n", fs->block_count); spiffs_printf("free_blocks: %i\n", fs->free_blocks); spiffs_printf("page_alloc: %i\n", fs->stats_p_allocated); spiffs_printf("page_delet: %i\n", fs->stats_p_deleted); u32_t total, used; SPIFFS_info(fs, &total, &used); spiffs_printf("used: %i of %i\n", used, total); SPIFFS_UNLOCK(fs); return res; }