SPIFFS: From image creation to read & write through flashing

Bernard
Posts: 7
Joined: Tue Apr 17, 2018 10:49 pm
Location: France

SPIFFS: From image creation to read & write through flashing

Postby Bernard » Wed Jul 11, 2018 5:22 pm

As I fight a little bit to be able to use SPIFFS on RTOS SDK and did not find too many information on the web, here are my findings:

Compile mkspiffs (tool used to generate a SPIFFS image)
Use mkspiffs tool: https://github.com/igrr/mkspiffs
git clone --recurse-submodules git@github.com:igrr/mkspiffs.git to clone (with sub module)

Note: the sub module here is spiffs source. Unfortunately, these spiffs sources do not  match the ones from RTOS SDK. That's why you have to copy the following files:
/path/to/ESP8266_RTOS_SDK/third_party/spiffs/*.c (but not esp_spiffs.c) to /path/to/mkspiffs/spiffs/src/
/path/to/ESP8266_RTOS_SDK/include/spiffs/spiffs.h to /path/to/mkspiffs/spiffs/src/
/path/to/ESP8266_RTOS_SDK/include/spiffs/spiffs_nucleus.h to /path/to/mkspiffs/spiffs/src/

And you have to update the file /path/to/mkspiffs/include/spiffs_config.h with the values from /path/to/ESP8266_RTOS_SDK/include/spiffs/spiffs_config.h
You should keep anyway the value of SPIFFS_TEST_VISUALISATION to 1 in order to be able to compile.

Then compile with make dist
Normally you should not get any errors, but if you get some, you will have to fix them.

Create SPIFFS image
Now put all you files you want in your image in a folder called data/
Note: There should be no subfolder as SPIFFS only works with a flat hierarchy. Max lenght for a file name is 31 characters. When you want to open a file from esp8266, you should add a / before file name (see code)

Generate the image by typing:
/path/to/mkspiffs/mkspiffs –p 256 –b 8192 –s 0xfa000 –c /path/to/data/ spiffs-image.bin
Where:
-p 256 indicates the size of the page (should match what you will put in esp8266 code)
-b 8192 indicates the size of the block (should match what you will put in esp8266 code)
-s 0xfa000 ndicates the size of the image (should match what you will put in esp8266 code). Here our image will go from 0x300000 to 0x3fa000 as from 0x3fc000 we have other images (system param)

Flash SPIFFS image
esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash 0x300000 spiffs-image.bin
Image is flashed at adress 0x300000

Read SPIFFS image from ESP8266
Here is a code:

Code: Select all

/*
* user_spiffs.c
*
*/
 
#include "esp_common.h"
#include "spiffs.h"

#include <fcntl.h>
 
#define FS1_FLASH_SIZE      (1000*1024)                // Size of SPIFFS image 0xfa000
#define FS1_FLASH_ADDR      (3*1024*1024)            // Start of SPIFFS image in FLASH memory space 0x300000
#define SECTOR_SIZE         (8*1024)
#define LOG_BLOCK           (SECTOR_SIZE)            // Size of a logical block
#define LOG_PAGE            (256)                    // Size of a logical page
#define FD_BUF_SIZE         32*4
#define CACHE_BUF_SIZE      (LOG_PAGE + 32)*8
 
void spiffs_fs1_init(void)
{
    s32_t ret;
    struct esp_spiffs_config config;
 
    config.phys_size = FS1_FLASH_SIZE;
    config.phys_addr = FS1_FLASH_ADDR;
    config.phys_erase_block = SECTOR_SIZE;
    config.log_block_size = LOG_BLOCK;
    config.log_page_size = LOG_PAGE;
    config.fd_buf_size = FD_BUF_SIZE * 2;
    config.cache_buf_size = CACHE_BUF_SIZE;
 
    ret = esp_spiffs_init(&config);
    if (ret)
        os_printf("ERR: Can't init spiffs image!\n");
}

void spiffs_main()
{
    char out[20] = { 0 };
    int pfd;
    int res;

    // Mount SPIFFS image
    spiffs_fs1_init();
 
    // Create a new file
    char *buf = "hello world";

    pfd = open("myfile", O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    if (pfd <= 3) {
        printf("open file error\n");
    }
     
    // Write to new file
    int write_byte = write(pfd, buf, strlen(buf));
    if (write_byte <= 0) {
        printf("write file error\n");
    }
    close(pfd);
 
    // Read previous created file
    pfd = open("myfile", O_RDWR);
    if (pfd < 3)
        os_printf("ERR: Can't open file! %d\n", pfd);
    else {
        if (read(pfd, out, 20) < 0)
            os_printf("ERR: Can't read file!\n");
        close(pfd);
        printf("--> %s <--\n", out);
    }
 
    // Read file from generated image with mkspiffs tool
    pfd = open("/readme.txt", O_RDWR);            // !! Don't forget to add the / before the name of the file
    if (pfd < 3)
        os_printf("ERR: Can't open file! %d\n", pfd);
    else {
        if (read(pfd, out, 20) < 0)
            os_printf("ERR: Can't read file!\n");
        close(pfd);
        printf("--> %s <--\n", out);
    }
}

Note on page, block, address and size parameters
These parameters depend heavily on the memory you are using.
In my case I am using a 4MB flash (Winbond W25Q32FV).
Page size and block size (256 and 8192) are fine for this memory but other values may work also.
For a 4MB flash, address range is from 0x000000 to 0x400000. I decided to put my SPIFFS image at address 0x300000, but you can put it somewhere else if you prefer (0x100000, 0x200000).
I decided to used a size of 1MB (0x100000) for SPIFFS image but as I am flashing sytem parameter (esp_init_data_default.bin) and blank.bin at resp. 0x3fc000 and 0x3fe000 I need to reduce the size to 0xfa000 (size has to be a multiple of block size)


Hope it will be helpful for people.
Last edited by Bernard on Wed Apr 24, 2019 6:17 pm, edited 2 times in total.
Regards, Bernard

Website: https://www.ochrin.com

razuel

Re: SPIFFS: From image creation to read & write through flashing

Postby razuel » Fri Mar 15, 2019 7:54 pm

thanks for your sample

i try build using RTOSSDK IDFstyle , and using esp826612E 4MB Flash (1MB SPIFFS)

ets Jan 8 2013,rst cause:2, boot mode:(3,6)

load 0x40100000, len 7196, room 16
0x40100000: _stext at ??:?

tail 12
chksum 0x51
ho 0 tail 12 room 4
load 0x3ffe8408, len 24, room 12
tail 12
chksum 0xd8
ho 0 tail 12 room 4
load 0x3ffe8420, len 3548, room 12
tail 0
chksum 0xa2
I (51) boot: ESP-IDF v3.2-dev-137-g93e3a3f5 2nd stage bootloader
I (51) boot: compile time 08:31:07
I (51) qio_mode: Enabling default flash chip QIO
I (59) boot: SPI Speed : 40MHz
I (66) boot: SPI Mode : QIO
I (72) boot: SPI Flash Size : 2MB
I (78) boot: Partition Table:
I (84) boot: ## Label Usage Type ST Offset Length
I (95) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (106) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (118) boot: 2 factory factory app 00 00 00010000 000f0000
I (130) boot: End of partition table
I (136) esp_image: segment 0: paddr=0x00010010 vaddr=0x40210010 size=0x35ae0 (219872) map
I (223) esp_image: segment 1: paddr=0x00045af8 vaddr=0x3ffe8000 size=0x00548 ( 1352) load
I (224) esp_image: segment 2: paddr=0x00046048 vaddr=0x3ffe8548 size=0x0011c ( 284) load
I (235) esp_image: segment 3: paddr=0x0004616c vaddr=0x40100000 size=0x06004 ( 24580) load
0x40100000: _stext at ??:?

I (256) boot: Loaded app from partition at offset 0x10000
I (277) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (287) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (487) reset_reason: RTC reset 2 wakeup 0 store 0, reason is 2
open file error
write file error
ERR: Can't open file! 0
ERR: Can't open file! 0


and this is my code



/*
* user_spiffs.c
*
*/
#include "esp_spiffs.h"
#include "spiffs.h"

#include <fcntl.h>

#define FS1_FLASH_SIZE (1000*1024) // Size of SPIFFS image 0xfa000
#define FS1_FLASH_ADDR (3*1024*1024) // Start of SPIFFS image in FLASH memory space 0x300000
#define SECTOR_SIZE (8*1024)
#define LOG_BLOCK (SECTOR_SIZE) // Size of a logical block
#define LOG_PAGE (256) // Size of a logical page
#define FD_BUF_SIZE 32*4
#define CACHE_BUF_SIZE (LOG_PAGE + 32)*8

void spiffs_fs1_init(void)
{
s32_t ret;
struct esp_spiffs_config config;

config.phys_size = FS1_FLASH_SIZE;
config.phys_addr = FS1_FLASH_ADDR;
config.phys_erase_block = SECTOR_SIZE;
config.log_block_size = LOG_BLOCK;
config.log_page_size = LOG_PAGE;
config.fd_buf_size = FD_BUF_SIZE * 2;
config.cache_buf_size = CACHE_BUF_SIZE;

ret = esp_spiffs_init(&config);
if (ret)
os_printf("ERR: Can't init spiffs image!\n");
}

void spiffs_main()
{
char out[20] = { 0 };
int pfd;
//int res;

// Mount SPIFFS image
spiffs_fs1_init();

// Create a new file
char *buf = "hello world";

pfd = open("myfile", O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (pfd <= 3) {
printf("open file error\n");
}

// Write to new file
int write_byte = write(pfd, buf, strlen(buf));
if (write_byte <= 0) {
printf("write file error\n");
}
close(pfd);

// Read previous created file
pfd = open("myfile", O_RDWR);
if (pfd < 3)
os_printf("ERR: Can't open file! %d\n", pfd);
else {
if (read(pfd, out, 20) < 0)
os_printf("ERR: Can't read file!\n");
close(pfd);
printf("--> %s <--\n", out);
}

// Read file from generated image with mkspiffs tool
pfd = open("/readme.txt", O_RDWR); // !! Don't forget to add the / before the name of the file
if (pfd < 3)
os_printf("ERR: Can't open file! %d\n", pfd);
else {
if (read(pfd, out, 20) < 0)
os_printf("ERR: Can't read file!\n");
close(pfd);
printf("--> %s <--\n", out);
}
}

void app_main(){
spiffs_main();
}

Bernard
Posts: 7
Joined: Tue Apr 17, 2018 10:49 pm
Location: France

Re: SPIFFS: From image creation to read & write through flashing

Postby Bernard » Mon Mar 18, 2019 12:50 am

Unfortunately I did test only with version 2.x.x of esp8266_rtos_sdk. I did not try with version 3.x.
So I can't tell you what is wrong.
If I have time, I will give it a try and let you know my result.
Regards, Bernard

Website: https://www.ochrin.com

Bernard
Posts: 7
Joined: Tue Apr 17, 2018 10:49 pm
Location: France

Re: SPIFFS: From image creation to read & write through flashing

Postby Bernard » Wed Apr 24, 2019 6:13 pm

I retried my tutorial and found out that there was a mistake: the spiffs_config.h file which should be modified is not the one in default folder but the one in /path/to/mkspiffs/include.
And even more it is better to update value in the file than do a direct copy of this file from RTOS_SDK.
You should also keep SPIFFS_TEST_VISUALISATION to 1 in order to be able to compile.
I have updated my first post.

Anyway, I don't think this fix will solve your problem.
Regards, Bernard

Website: https://www.ochrin.com

Who is online

Users browsing this forum: No registered users and 0 guests