qyw wrote on Sunday, September 06, 2015:
Looking at FIL struct code
/* File object structure (FIL) */
typedef struct {
FATFS* fs; /* Pointer to the related file system object (**do not change order**) */
WORD id; /* Owner file system mount ID (**do not change order**) */
BYTE flag; /* Status flags */
BYTE err; /* Abort flag (error code) */
DWORD fptr; /* File read/write pointer (Zeroed on file open) */
DWORD fsize; /* File size */
DWORD sclust; /* File start cluster (0:no cluster chain, always 0 when fsize is 0) */
DWORD clust; /* Current cluster of fpter (not valid when fprt is 0) */
DWORD dsect; /* Sector number appearing in buf[] (0:invalid) */
#if !_FS_READONLY
DWORD dir_sect; /* Sector number containing the directory entry */
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */
#endif
#if _USE_FASTSEEK
DWORD* cltbl; /* Pointer to the cluster link map table (Nulled on file open) */
#endif
#if _FS_LOCK
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
#endif
#if !_FS_TINY
BYTE buf[_MAX_SS]; /* File private data read/write window */
#endif
} FIL;
I understood what is my problem. STACK OVERFLOW. FIL.buf is very big. The size of stack was 2KB and it worked fine with or without any initialization. Then I changed _MAX_SS to 4KB. And app still worked fine without initialization to {0}, because FATFS did not use full 4KB of buff, but only 512b (it depends on drive type). Finally I added initialization of FIL and “hit my had agains a wall” again, and again, and again…
This story lasts about two weeks, I did not associate changes together. It was complicated story.
Assuming
1 Don’t declare large variables on the stack. Use malloc, static, or declare as public (out of function).
2 A long time ago my FreeRTOS became FreeRTOS+Trace. And hook function looked like
// === FreeRTOS_hooks.c ===
void vApplicationStackOverflowHook( TaskHandle_t *pxTask, signed char *pcTaskName )
{
(void)pxTask; (void)pcTaskName;
vTraceConsoleMessage("\n\rStack overflow!\n\r");
}
// === trcHardwarePort.h ===
#define vTraceConsoleMessage // do nothing, do not compile
That was my mistake. Hook was rewritten
#if configCHECK_FOR_STACK_OVERFLOW
void vApplicationStackOverflowHook( TaskHandle_t *pxTask, signed char *pcTaskName )
{
debugf("!!! STACK OVERFLOW in task %s, handler 0x%08x\n", pcTaskName, (unsigned)pxTask);
configASSERT( 0 );
}
#endif
#define vTraceConsoleMessage(x) debugf(x)
And now we will receive the message, and never fall to HW fault. Note configASSERT must be defined properly, debugf is synonim to printf.
Links
Stacks and stack overflow checking
[1]: http://www.freertos.org/Stacks-and-stack-overflow-checking.html “Stacks and stack overflow checking”