This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC3200MODLAUNCHXL: Filesystem error : SL_FS_FILE_HAS_NOT_BEEN_CLOSE_CORRECTLY

Part Number: CC3200MODLAUNCHXL

Hi,

CCS version : 6.1.3.00034, TI CC3200 SDK : V1.3, CC3100_CC3200_ServicePack_1.0.1.6-2.7.0.0

I am using internal flash memory to store log files when CC3200 Wifi connection or server connection is lost. Below is the sequence of steps I am following

1. when the wifi connection is lost offline1.txt file is created and its handle is obtained
2. offline data is stored
3. when the wifi connection is restored the file handle is closed
4. after that I am opening, reading and closing one packet data from offline1.txt
5. now I have new data available to transmit and before sending data I am again disconnecting wifi
6. now new file offline2.txt is created and data is stored in it
7. again I turn on wifi
8. offline2.txt is closed
9. now trying to read offline1.txt file and its throwing error SL_FS_FILE_HAS_NOT_BEEN_CLOSE_CORRECTLY

The above steps are to take care of log files when there are multiple interruptions. I have searched in forums but couldnt find much info

Any help appreciated

James

  • Hi James,

    I suppose that you not close file properly after write. I think that you call sl_Stop() when your file is not closed after write.

    Jan
  • Hi Hnz,
    I have checked the code again there are no sl_Stop in the code when a file handle is open.
  • Hi James,

    Can you try use latest service pack?

    Jan
  • Hi Jan,
    I tried the latest service pack but still get the same error. I am posting part of my code for your reference.

    function store offline. This function is called for writing and also for closing the file(action variable handles that)
    long StoreOfflineData(char* writeFileName, unsigned long *ulToken, long *lFileHandle, _u32 *offset,uint64_t timestamp,float* sensorData, int action)
    {
    long lRetVal = -1;

    char tempwriteFileName[OFFLINE_FILENAME_SIZE];
    memset(tempwriteFileName,0,OFFLINE_FILENAME_SIZE);
    //static int datacount = 0;
    //static _u32 Offset = 0;
    //
    // open a user file for writing
    //
    if(action == 0) {
    if(*lFileHandle == 0) {
    //choose a file name that doesnt exist
    int i = 1;
    for(i = 1; i <= MAXFILECOUNT; i++) {
    sprintf(tempwriteFileName,OFFLINE_FILE_NAME,i);
    unsigned long ulTokenTemp; long lFileHandleTemp;
    lRetVal = sl_FsOpen((unsigned char *)tempwriteFileName,
    FS_MODE_OPEN_READ,
    &ulTokenTemp,
    &lFileHandleTemp);
    if(lRetVal < 0)
    {
    memcpy(writeFileName,tempwriteFileName,OFFLINE_FILENAME_SIZE);
    sl_FsClose(lFileHandleTemp, 0, 0, 0);
    CreateOfflineFile(writeFileName);
    break;
    }

    }

    lRetVal = sl_FsOpen((unsigned char *)writeFileName,
    FS_MODE_OPEN_WRITE,
    ulToken,
    lFileHandle);
    if(lRetVal < 0)
    {
    lRetVal = sl_FsClose(*lFileHandle, 0, 0, 0);
    *offset = 0;
    *lFileHandle = 0;
    ASSERT_ON_ERROR(FILE_OPEN_WRITE_FAILED);
    }
    *offset = 0;
    }

    int len = 0;
    char buf[100];//for debugging to be removed later
    memset(buf,0,100);
    memcpy(buf,&timestamp,sizeof(timestamp));
    len = len + sizeof(timestamp);
    memcpy(buf+len,sensorData,DP_SIZE*4);
    len = len + (DP_SIZE*4);
    lRetVal = sl_FsWrite(*lFileHandle,*offset,(unsigned char*)buf,len);
    *offset = *offset + OFFLINE_PACKET_SIZE;
    if (lRetVal < 0)
    {
    lRetVal = sl_FsClose(*lFileHandle, 0, 0, 0);
    ASSERT_ON_ERROR(FILE_WRITE_FAILED);
    }
    } else {
    if(*lFileHandle) {
    lRetVal = sl_FsClose(*lFileHandle, 0, 0, 0);
    if (SL_RET_CODE_OK != lRetVal)
    {
    ASSERT_ON_ERROR(FILE_CLOSE_ERROR);
    }
    *offset = 0;
    *lFileHandle = 0;
    }
    }
    return SUCCESS;
    }


    function to read the file
    long ReadOffline(char* readFileName, _u32 *offset,uint64_t *timestamp,float* sensorData)
    {
    long lRetVal = -1;
    const int BUF_SIZE = 100;
    long Result = 0;
    unsigned long ulToken;
    long lFileHandle;


    //
    // open a user file for reading
    //
    lRetVal = sl_FsOpen((unsigned char *)readFileName,
    FS_MODE_OPEN_READ,
    &ulToken,
    &lFileHandle);
    if(lRetVal < 0)
    {
    lRetVal = sl_FsClose(lFileHandle, 0, 0, 0);
    ASSERT_ON_ERROR(FILE_OPEN_READ_FAILED);
    }

    //
    // read the data and compare with the stored buffer
    //
    _u8 buf[100];
    memset(buf,0,BUF_SIZE);

    lRetVal = sl_FsRead(lFileHandle, *offset,buf, OFFLINE_PACKET_SIZE);
    *offset = *offset + OFFLINE_PACKET_SIZE;
    if (lRetVal < 0)
    {
    lRetVal = sl_FsClose(lFileHandle, 0, 0, 0);
    sl_FsDel((unsigned char *)readFileName,ulToken);
    *offset = 0;
    memset(readFileName,0,OFFLINE_FILENAME_SIZE);
    return -1;
    }
    memcpy(timestamp,buf,sizeof(uint64_t));
    memcpy(sensorData,buf+sizeof(uint64_t),80);
    Result = 1;
    //
    // close the user file
    //
    lRetVal = sl_FsClose(lFileHandle, 0, 0, 0);
    if (SL_RET_CODE_OK != lRetVal)
    {
    ASSERT_ON_ERROR(FILE_CLOSE_ERROR);
    }

    return Result;
    }
  • Hi James,

    Sorry, you code is very complex, although I tried understand it, I was lost. From my point of view is your code that complex that you have good chance for mistake in code and unexpected behaviour.

    Few thing I don't understand inside your code:

    - Why you not use API sl_FsGetInfo() for detection if file exists?

    - Why you deleting and creating files? I think much better way is to have one file and store information into this file content. In this case you don't need create and delete this file again and again. Also this is much better for serial flash lifetime. But maybe I am wrong in this point, because I don't understand your code correctly.

    - How often you write into serial flash? Are sure that you not exceed lifetime of serial flash?

    - Why do you use security tokens which are not supported?


    BTW ... if you need insert code, please use code-highlighter in rich editor.

    Jan

  • Hi Jan,

    Thanks for your reply.

    Sorry for not using the highlighter will do so in future.

    Yes I will use sl_FsGetInfo. I have used it in other places haven't changed here.

    The following is the functionality I am trying to implement:
    1. When wifi connection to the AP or server connection is broken I am using the serial flash to hold the data
    2. New data of size 80 bytes is available every 20 seconds
    3. The filesystem doesn't support append mode so once a file handle is opened for write I keep it open and store the information every 20 seconds
    4. once the connection is established I close the write handle and open the file for reading
    5. till now it works fine no issues
    6. if the connection is again broken while transmitting the data from file, I have to store the new data somewhere
    7. For this I am opening a new file and storing the data.
    8. Once the connection is established again I close the second file handle and try to send the content again
    9. it goes on in this fashion...
    10 Once all the content in the file is transmitted to the server I delete the file

    is there any way I can simplify/improve the above steps

    Thanks again,

    James
  • Hi James,

    This is my personal opinion according my experiences with CC3200.

    Filesystem in CC3200 is not designed for this type of usage. When you open file for write you should write required data and close file as soon as possible. Is not good idea to have open file for write for longer time, because it increase probability of data lost from your open file. In case of reset NWP (due to power lost or from some other reason) you lost your data in non closed file(s).

    Although it is unlikely in your use case but at some special conditions you can exceed guaranteed number of write cycles. In this case your serial flash can be damaged permanently. Your approach is not good in long time horizon.

    I think you should consider to use independent storage for your logging data. Usage of EEPROM or FRAM memory looks as ideal way in your case. For example biggest EEPROM memory on market from ST is M24M02/M95M02 have 256 kBytes (=2Mbit) and cost less then 3 USD.

    Jan
  • Hi Jan,

    I am working with James on this issue. Thank you for your response.

    We agree with you. We are planning to add external memory in our main production second version. For now we have already finalized the production of first version. The 100k read/write limitation should be OK for now.

    Is it possible to fix the error I get or should I try a different way to get the functionality working? Still not sure why the file would not be closing properly.
  • Hi James,

    I think that reason of your issue is a bug inside your code. Unfortunately I am not able determine this it. Maybe someone from TI support will be able do that.

    There is one unusual way how use independent storage without dedicated chip. If you populate your board by bigger flash memory and you format filesystem by Uniflash to lower size. Let's say you populate board by 2MByte flash but you format this chip for only 1MB. First 1MB will be used by NWP filesystem, but second part will be accessible by your code using direct access to SPI flash. But there is one big problem. Direct access to this memory is possible only when NWP is stopped.

    Jan
  • Hi James,

    We are not familiar with any issue in regards to (successful) closing and opening files.

    Please provide logs that shows the problem.

    Br,

    Kobi

  • To close this out, this issue has been resolved. We are not 100% sure of the resolution, but it seemed to be linked to variable/file names and a pointer going awry.

    Thank you for the support.