vTaskDelay() -> Hard fault. Because struct initialized with {0}

I’ve met the problem with my task which does nothing but blink led. Program falls into HardFault while executing vTaskDelay. I found out fault spawned when struct FIL (from FatFS by Chan) initialized with {0}. Seems here is memory corruption.
Can you explain why? And why FreeRTOS doesn’t call any configAssert? But Tracealizer says: Warning: Recoder reported error: "TRACE_ASSERT: vTraceStoreTaskswitch: invalid value for task handle"
static void empty_task( void* pvParams )
    FRESULT ferr = FR_OK;
    DIR dir;
    FILINFO fno = {0};   // No problem with it, but I am not sure it will not apper in feature or on other system/compilier
    //FIL fil = {0};    // Uncomment to achive my problem

        bsp_LedToggle(LED_White);  // will pass once. Next time met PC at HardFault_IRQHandler()
Compilier MDK-ARM v5.05 u2 b169. uC STM32F407.

vTaskDelay() -> Hard fault. Because struct initialized with {0}

I will try and explain, but first need to understand your post better. Are you saying something in Chan’s FatFS is corrupting something in FreeRTOS? If so it must be corrupting something used in vTaskDelay(), but you don’t say what. Where inside vTaskDelay() does the hard fault occur? Regards.

vTaskDelay() -> Hard fault. Because struct initialized with {0}

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) */
    DWORD   dir_sect;       /* Sector number containing the directory entry */
    BYTE*   dir_ptr;        /* Pointer to the directory entry in the win[] */
    DWORD*  cltbl;          /* Pointer to the cluster link map table (Nulled on file open) */
#if _FS_LOCK
    UINT    lockid;         /* File lock ID origin from 1 (index of file semaphore table Files[]) */
#if !_FS_TINY
    BYTE    buf[_MAX_SS];   /* File private data read/write window */
} 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.


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("nrStack overflow!nr");

// === trcHardwarePort.h ===
#define vTraceConsoleMessage  // do nothing, do not compile
That was my mistake. Hook was rewritten
void vApplicationStackOverflowHook( TaskHandle_t *pxTask, signed char *pcTaskName )  
    debugf("!!! STACK OVERFLOW in task %s, handler 0x%08xn", pcTaskName, (unsigned)pxTask);
    configASSERT( 0 );
#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.


Stacks and stack overflow checking