cancel
Showing results for 
Search instead for 
Did you mean: 

Write several files "simultaneously" on SD card with freeRTOS fails.

JulienD
Senior

Hello,

I built a test app that writes data in files on SD cards in a freeRTOS enviromnent in order to test

Cube (and cubeMx) librairies 'integration.

I wrote a task that write data on one file, then another and so on, the file prefix is the (data) of the task:

void taskCreateFiles(void const* data) {
    for (uint32_t i = 0; i < 256; i++) {
        char i_[10];
        itoa(i, i_, 10);
        char filename[255];
        strcpy(filename, (char*) data);
        strcat(filename, i_);
        strcat(filename, ".txt");
        newFile(filename);    // creates a file a add some data in it by calling f_write several times
        RED_LED_TOGGLE;
    }
    while (1)
        osDelay(1000);
}

The task is instantiated twice with a different prefix.

A third task is a simple blinking led.

FatFS is defined as FS_REENTRANT.

It works until... it stops working because of invalid return values in f_write or f_close or f_open.

As cubeMx generates a sd_disk_io.c file "based on sd_diskio_dma_rtos_template.c v2.0.2 as FreeRTOS is enabled" (in the text) , I thought my app should work "as it".

Am I wrong to think like this? Did I miss something in my implementation?

To overcome my issue, I see several choicies :

  • implement a single SD task with a queue which will be feed with a struct containing an operation (read/write/...) and relevant data ( nothing / fileId and data / ...). Feedback may be provided by a messaging system.
  • protecting BSP read/write/erase functions with a mutex.
  • protecting sd_diskio.c functions with a mutex.

Solution 1 might be a bit heavy to code.

Solution 2 might not work if a high level operation needs several access to SD module to complete

Solution 3 not really cool because there is no user tag to write data in source code. It will be erased by CubeMx.

What do you think about it?

Thanks

Julien

3 REPLIES 3
Danish1
Lead II

You miss out quite a lot. Probably because you don't think it is important but without it, how do we know.

I don't know FreeRTOS. But I use another microcontroller RTOS so my thoughts should be relevant.

1) Your taskCreateFiles uses quite a lot of stack since filename can be 255 characters long. How much stack space have you allocated to each instantiation of the task?

2) What about the memory usage in newFile()? Is that on the stack?

3) If you don't cleanly close files in newFile it's possible FreeRTOS is "doing its best" in reallocating file-handles but the time could come when both threads use the same handle.

Posting more of your code, including newFile(), might answer some of this.

Hope this helps,

Danish

You'd definitely need to serialize access to the SDIO/SDMMC layer (depending on OS a semaphore/mutex), do FILE IO in one thread using a state machine, or make DISKIO queue IO requests and have a thread manage dispatch to the SDIO/SDMMC layer.

Hours of fun.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
JulienD
Senior

@Danish​ 

Thanks.

1/ 1024, Same value as in the example provided by ST.

2/ Did not checked (I will) but if it works for one call and if the memory is correctly released, it should work for the other calls no? Is it on the stack ? I must

say that I don't know, it is fully packaged/parametered lib/instantiation. I'll have a look.

3/ I did :

void newFile(const char* filename) {
    FRESULT res; /* FatFs function common result code */
    uint32_t byteswritten; /* File write/read counts */
    uint8_t wtext[] = "This is SdTM32 working with FatFs uSeD + FreeRTOS\r\n"; /* File write buffer */
 
    FIL file;
    res = f_open(&file, filename, FA_CREATE_ALWAYS | FA_WRITE);
	assert(res == FR_OK);
	for (uint32_t t = 0; t < 600; t++) {
		res = f_write(&file, wtext, sizeof(wtext)-1, (void *) &byteswritten);
		assert(res == FR_OK);
	}
	res = f_close(&file);
	assert(res == FR_OK);
}

@Community member​ 

Thanks.

Yes ! hours of fun and hours of sad discussion to explain PC developpers and managers why it takes hours of fun! :D