2017-06-21 05:26 AM
Hi community!
To replicate my setup you need:
- discovery (F407)- Discover - M0 expansion 'shield'- Sd Card- download my test project under atollic here (cube mx project included):
https://uloz.to/!mbYhN53eRdyf/cubemx-sdio-fat-sdkarta-rar
In one of my projects i am trying to achieve to save data from mems microphone to .wav on sd card using FAT. It worked, but unfortunately, from time to time, when i try to write new chunk of data into the file, f_write() return me an error (FR_DISK_ERR).
To find the source of the issue i have made a new project, where i only setup sdio, FAT, push button and a timer that triggers writing of a new chung of dummy data into the sd card (file). (that simulates the stream of data from microphone). The issue occure sometimes on the 3rd write batch (button push), sometimes on 5th, ... It varies. With each new batch i open a new file with incremented number in its name so i can later observe with what number of file did the issie occured.
The procedure goes like this:
Program waits for blue button to be pushed
then program mouts the SD card (f_mount)if(f_mount(&SDFatFs, (TCHAR const*)SD_Path, 0) != FR_OK)
then open a new filef_open(&MyFile, FilName, FA_CREATE_ALWAYS|FA_WRITE) != FR_OK) new file
then comes the write while loop where i write new chunk of data every 2 ms or so
f_write(&MyFile, u8WriteBuffer, WR_BUFF_SIZE,(void *)&byteswritten);
and after the write of whole batch (2500 chunks of 176 B) is done, program waits for another button push ...
Can somebody give me some feedback on that? Where could be the problem? Do anyone faced same problem?
Thank you very much
best regards
Jan #issue #sdio #stm32f4 #sdcard #fat-fs #sdio-write-data-problem2017-06-22 12:33 AM
When i made chunks to be written smaller in size, it now perform better, but i will need higher writing speed in the future.
I conclude, that i should probably use DMA for transferring of a data. Please can anyone of you reccomend how to setup the DMA?2017-06-22 08:20 AM
The read/write should ideally be done a large multiples of 512 bytes, and aligned on the same with respect to file offset. Better something the size of a cluster (power of two, 4K, 8K .. 32K).
Doing odd sizes and alignments will result in a lot of unnecessary reading/writing, and block erasing on the card.
The CubeMX/HAL implementation seems to be very fragile, can't help you with that.
Speed is highly variable, the performance/quality of the cards is very important. Cheap ones tend to have very slow writes, despite whatever 'Class' they claim to be.
2017-06-23 03:10 AM
Thanks for your reply Clive!
Your advice on write chunk size noted! I will experiment with sizes like that.'The CubeMX/HAL implementation seems to be very fragile' You mean implementation of sdio drivers?
2017-06-27 07:08 AM
Hello everyone!
I am investigating my SDIO FATfs case further more. Here are some observations i have made so far:1) When i test sending the batches of dummy data (2500 chunks of 64 bytes with 2ms interval, then 1s pause and start over again) using only HAL_Delay for timing the application works reasonably well. I am able to open close hundreds of files writing one batch of dummy data into it.I have printed few digital analyser scopes made using ''HAL_Delay'' triggering method so you can observe signals. In my program i set/reset PD14 before/after every f_write() function. I have noticed, that only every 9th data chunk f_write() will cause SDIO lines to move and also it takes much longer time (looking at SD14 pin toggle told me). previous 8 writes only do only something with cmd line and it takes much less time inside f_write function (PD14 toggle).
2) When i go back to using my timer TIM6 PeriodElapsedCallback() for triggering of sending of 64B chunks soon enough (after few batches <each batch is written into separate file with incremented index name>) the f_write returns FR_DISK_ERR.
My theory is that somehow timer interrupt interfere with the 9th long writes? Is it that f_write function should not be interrupted? But if i am not mystaken, systick interrupt is also used for HAL_Delay() so what is the difference?
Tomorrow i will add my observations from ''TIM6 triggering failing'' case.
2017-06-27 10:16 AM
Hey
Slavot_nek.Jan
,I had the same problem. Actually it seems that it happens when writing fast to SD card simultaneously. For me, decreasing the SDIO clock speed worked, but I strongly recommend you to change your code to DMA based. It is really faster and you can sure that you never face this problem.
Regards,
Misagh
2017-06-27 10:18 AM
>>
But if i am not mistaken, systick interrupt is also used for HAL_Delay() so what is the difference?
Most likely preemption level and run-time. Callback functions occur in interrupt context, and thus block other tasks.
The SDIO has hard time line expectations for the data transfers, the driver isn't thread-safe/reentrant. Back-to-back operations with a write were problematic if the FIFO (on the SDIO side, not DMA) was not left to vacate properly, ie DMA TC interrupt occurs way before data gets to card successfully for command completion.
2017-06-27 10:21 AM
The SDIO in this context, but the whole thing embodies a lot of flawed implementation and lack of rigour.
2017-06-28 01:56 AM
Hi
Salmanzadeh.Misagh
Thank you very much for your answer. I was googling for how to guide how to implement DMA method of SDIO FAT instead of polling (i guess i am using polling when I chose in CubeMX only sdio and then fatfs and thats all ... didnt allow interrupt nor didnt set DMA's).Salmanzadeh.Misagh
an you please give me some kind of guide or refference on some material on how to set up DMA for SDIO +fatfs? I would be very grateful to you!2017-06-29 06:15 AM
Actually there is a simple example on STM32CubeF4 in this path: ST\STM32Cube_FW_F4_V1.14.0\Projects\STM324xG_EVAL\Applications\FatFs\FatFs_uSD
you just need to change
BSP_SD_WriteBlocks
andBSP_SD_ReadBlocks
toBSP_SD_WriteBlocks_DMA
andBSP_SD_ReadBlocks_DMA
in 'sd_diskio.c' file and compile the project to run the project with DMA.If you have a question about it, I'll be happy to answer.
Good luck,
Misagh