Please tell me about ff_fclose error

Hello

I use FreeRTOS + FAT with Renesas RA6M3.

Error on ff_fclose after ff_fwrite. ff_errorno = 89
What is the cause of this error?


Best Regards

Hi ,
The errorno(89) you mention is returned when there is an FF_ERR_DIR_END_OF_DIR error. See here
For debugging, can you check that the file handle is not in use by another task, and that the handle has not been closed before?

Thank you for reply

What is the reason for the FF_ERR_DIR_END_OF_DIR error?
Please let me know how to check.

I think the file handle is not in use by another task, and that the handle has not been closed before.

Thank you

This error means that an entry was not found in a directory. Would you please step through the FF_Close function and see which line is generating this error.

Thank you for Reply.

Error on FF_Traverse.
I attach a screenshot.

FF_Close - FF_GetEntry - FF_FetchEntryWithContext - FF_Traverse

Thank you

Can you please check the value of ulClusterNum and pxContext in the debugger, along with the input parameter values pxIOManager and ulEntry. We need to see the values held by these pointer variables , to root cause the issue .

ulClusterNum=0 , pxContext->ulChainLength = 0

I attach a screenshot.

Please let me know if you find out anything.

Thank you for attaching the screenshot with the values.
pxContext->ulChainLength=0 is the issue for the error, since it does not depend on the value of ulClusterNum, the condition for error will always be achieved.

Checking the code flow, this chain length is populated in FF_GetChainLength
FF_FClose → FF_GetEntry → FF_InitEntryFetch → FF_GetChainLength

In this function, there are 2 ways in which the length of the chain could be 0:

  1. The while loop does not execute here - which would suggest FF_isEndOfChain returns pdTRUE.

  2. An error occurs in FF_getFATEntry here which breaks the loop and exits. This is not possible, since the error code would have been different in this scenario.

To verify option 1 is the root cause, we can put a breakpoint here and step inside the function FF_isEndOfChain to check where it returns pdTRUE.

FF_isEndOfChain pdTRUE was hit once each in ff_fopen and ff_fclose
Screenshots of each are attached.


Is there any abnormality?
If there are other things to check, please let me know

The value of ulFATEntry seems a bit suspicious for FF_FClose.

Can you help in keeping breakpoints in these places :-

  1. FF_FClose
  2. FF_GetChainLength at line 1281 at beginning of the while loop - check the value of ulStartCluster here.
  3. Step into FF_GetChainLength from step 2 and see where it returns pdTRUE.

Please remove all other breakpoints, so we know FF_GetChainLength is called from FF_FClose

Thank you for your reply.

I can’t work on it right now so I’ll check on Monday.

Sorry, I think I looked at the wrong part in my previous reply.

ff_fclose → F_GetChainLength
uIStartCluster = 2 , and no return pdTRUE

ulStartCluster=2 and the function FF_isEndOfChain returning pdFALSE would indicate that ulLength would have been incremented. But pxContext->ulChainLength=0 , from our previous conversation. We need to step into this function FF_GetChainLength and see the return value of ulLength . If it is 0, then see the line, where it is being set to 0 and exiting the function.

ulLength=0 in the following
FF_Close->FF_GetEntry->FF_InitEntryFetch->
FF_GetChainLength → ulLength=0

xError not 0 in the following
FF_GetChainLength->FF_getFATEntry->prvGetFromFATBuffers

This changes the direction we were looking for the issue.
If you see this function FF_GetEntry


FF_GetEntry → FF_InitEntryFetch → FF_GetChainLength → FF_getFATEntry
→ prvGetFromFATBuffers givex xError = 0x80000005

So, ideally it should not enter FF_FetchEntryWithContext and hence it should not go to FF_Traverse . Can you verify by keeping stepping into FF_Close and see the entire code flow :-

  1. FF_Close
  2. FF_GetEntry
  3. FF_InitEntryFetch
  4. FF_GetChainLength
  5. FF_getFATEntry
  6. prvGetFromFATBuffers

    We need to see what other APIs are called before reaching ff_errno = prvFFErrorToErrno( xError );

And double confirm, if ff_errno is still 89, when we reach this statement after stepping in

prvGetFromFATBuffers → xError = 0x80000004
FF_getFATEntry → xError = 0x84010004
FF_ReleaseFATBuffers → xError = 0

FF_InitEntryFetch → xError = 0

enter to FF_FetchEntryWithContext

Is there anything unusual?

So the issue is narrowed down to prvGetFromFATBuffers giving error code 0x80000004.
This is happening because FF_GetBuffer fails to allocate an available cache buffer.
FF_GetBuffer() is the only function issuing caching buffers.

So, it might be the case that all available cache buffers are occupied , when the task calls FF_Close

You should check now 2 things to make sure you are providing sufficient cache memory.

  1. The recommended size for cache memory size = 9 X 512 bytes

  2. Look at how many files are open at the same time and how many tasks are accessing the same volumes (RAM-disk, SD-card). It should not get locked-up; task waiting for either tasks.

    There is a time-out when waiting for a free cache buffer: grep for
    FF_GETBUFFER_WAIT_TIME_MS, by default 20 seconds.

You can refer to this issue for more detailed explanation on optimal FreeRTOS + FAT Cache memory.

I changed the cache size. 1024 → 4608
The error has disappeared
Thank you for your help