SuperHouse / esp-open-rtos

Open source FreeRTOS-based ESP8266 software framework
BSD 3-Clause "New" or "Revised" License
1.52k stars 491 forks source link

SPIFFS does not work outside of example #593

Closed morcillo closed 6 years ago

morcillo commented 6 years ago

Hello,

I have an application loosely based on the esphttpd example and now I want to add SPIFFS functionality to it in a manner that is completely unrelated to the libeshttpd library, I just want it there for storing and modifying some information and then using it accordingly.

Firstly I simply run the spiffs example and it worked perfectly, I even modified its start address to see if everything was ok and it was, so after that I copied the example's source code into my project, I included the necessary headers, I modified my makefile and added extras/spiffs, flash size, startd address of spiffs and spiffs size, just as the readme says and then I run execute my project and it is unable to mount the file system, giving me -10025 error (SPIFFS not a file system error).

When I saw that I immediately went to the generated file system by mkspiffs to see what was written. Fortunately I saw that it created my file in the file system (I used a hex to ascii converter), but when I compare it to the file system binary generated by the example I see a completely different beginning to the file .. making me believe that the file system generated by my project is incorrect, which makes perfect sense to me ... since the header sent to the esp is not the one expected (magic number and all that)

I have no idea what could be wrong, I am literally using the same configurations in the makefiles but somehow they both give me different file systems. I'm certain the problem is on my end but I have no idea where to go from here

nochkin commented 6 years ago

It may not be a big help for you, but here is my own experience using SPIFFS. I had some weird issues serving files over http using SPIFFS (I think it was related to some large files like jQuery, etc). So I did not want to spend much time and I just changed my design to use the bundled espfs for libesphttpd while serving non-static data as CGI. Additionally I gained some extra speed due to gzip compression on static files (the most of my stuff was static anyway). Just an idea.

morcillo commented 6 years ago

Thank you for your reply and your advise, but I want it to retain the data that's why I needed spiffs.

The strange thing is that I moved all my code to the spiffs example and it worked .... and to tell you the truth it doesn't me any sense, at least to me

Zaltora commented 6 years ago

I can help you, my application using spiffs work well. I got a hex/ascii converter and i already do test with my own "cmd protocol" to write and read file (ascii or binary). Everything work. The filesystem is correctly flashed too. (i do already the check) Here, my makefile settings:

# spiffs configuration
SPIFFS_BASE_ADDR = 0x200000
SPIFFS_SIZE = 0x030000

include ${PATH_OPEN_RTOS}/common.mk

$(eval $(call make_spiffs_image,filesystem))

In my initialization setup:

    esp_spiffs_init();
    if (esp_spiffs_mount() != SPIFFS_OK)
    {
        debug("Error mount SPIFFS");
    }

Warning: SPIFFS_BASE_ADDR address need be superior to program size. that maybe because of this you got a mounting problem. Warning: Verify flash size, you can't mount a filesytem larger than the flash.

You got problem with hex/ascii converter ? Here my code to read file (depend on extension name) (thread safe/ flexible buffer output)

typedef struct
{
    const char* pcName;
    int iMode;
    FILE* pxFile;
} FileDataReent_s;

/**
 * @brief Read the file content. This function must be in a loop to read until NULL.
 * @warning If you don't finish to read the file, the system will not close it.
 * @param pcName File name
 * @param pcBuffer Buffer to store result
 * @param xLen Buffer size
 * @param pxReent Reentrant structure to store information about read process (FILE*,...)
 * @return NULL if error or EOF if end
 */
char* pcFileRead(const char* pcName, char* pcBuffer, size_t xLen, FileDataReent_s* pxReent)
{
    if(!pxReent->pxFile )
    {
        char* pcExtension = strrchr((char*)pcName, '.'); // search last dot
        if(!pcExtension) 
        {
            return NULL; //no dot, can't check file type
        }
        pxReent->iMode = _iFileModeSelection(pcExtension); // binary or ascii ? (e.g: .bin, .txt)
        pxReent->pcName = pcName;
        //Open File
        switch (pxReent->iMode)
        {
        case FILE_MODE_BIN:
            debug("binary read mode");
            pxReent->pxFile = fopen( pxReent->pcName, "rb" );
            break;
        case FILE_MODE_TXT:
            debug("text read mode");
            pxReent->pxFile = fopen( pxReent->pcName, "r" );
            break;
        default:
            break;
        }
        debug("File name: %s",pxReent->pcName);
        if (!pxReent->pxFile )
        {
            debug("Error opening file");
            pxReent->pcName = NULL;
            pxReent->iMode = -1;
            return NULL;
        }
    }
    uint16_t usIndex = 0;
    char pcReadBuff[2] = { 0 };
    while(1)
    {
        int iChar = fgetc(pxReent->pxFile); //read char

        if ((iChar == EOF) && usIndex)
        {
            pcBuffer[usIndex] = '\0';
            break; //End of file, send current data
        }
        else if ((iChar == EOF) && !usIndex)
        {
            //End of file, all data was send
            if(pxReent->pxFile)
            {
                fclose(pxReent->pxFile);
            }
            pxReent->pxFile = NULL;
            pxReent->pcName = NULL;
            debug("END of FILE");
            return NULL;
        }
        else if(pxReent->iMode == FILE_MODE_BIN)
        {
            //len-3 : HB char, len-2 : LB char, len-1: terminaison
            sprintf(pcReadBuff,"%02X",(uint8_t)iChar);
            pcBuffer[usIndex++] = pcReadBuff[0];
            pcBuffer[usIndex++] = pcReadBuff[1];
            if (usIndex >= (xLen-2))
            {
                pcBuffer[usIndex] = '\0';
                break;
            }
        }
        else
        {
            //(len-2 : last character, len-1: terminaison
            pcBuffer[usIndex++] = (char)iChar;
            if (usIndex == (xLen-1))
            {
                pcBuffer[usIndex] = '\0';
                break;
            }

        }
    }
    return pcBuffer;
}

void vReadFile(void)
{
            FileDataReent_s reent = { 0 } ;
            char acBuffer[BUFFER_ANSWER_SIZE] = { 0 };
            while(pcFileRead(pcFileName, acBuffer,sizeof(acBuffer), &reent))
            {
                printf("%s", acBuffer);
            }
}
Zaltora commented 6 years ago

output when i use my program: ( wifi.wif is a custom extension to tell at the system that it is wifi configuration. It is a binary file)


CMD> file read -N "wifi.wif"    
43536D65325F444334463232303244394636000000000000000000000000000043536D65325F4443344632323032443946
3600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AC10
000100000000FFFF000000000000

CMD> file read -N "default.txt"
calib.cal
motor.mot
sensor.sen
compute.com
debug.dbg
wifi.wif
meter.met
morcillo commented 6 years ago

yes ... thank you ... I got it working now .... very detailed help you gave me there

my problem was the base address s you imagined .... I had the great idea of putting he file sys

my problem was the base address s you imagined .... I had the great idea of putting he file system right after my source code ended in the first aligned address (I used the map file, got the start address of irom0.text added the size and then found the next aligned memory address after the source)

I changed the base address to a good address ajd everything started working