cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4+SD+Interrupt Problem

vicfer89
Associate II
Posted on November 10, 2016 at 11:59

Hi all, 

I'm trying to write a code of a data logger with the following characteristics:

  • A string is captured using interruptions by a uart at 921600 bauds: The information is stored byte by byte, and the whole string is storaged at a queue (dynamically allowcated) which is processed at the main loop.
  • When the system is in the main loop, depending on the input string some tasks may be executed, the main one is to store a string (about 310 characters) into a SD card (more than 4 Gb class 10).

I'm employing HAL libs and CubeMx initialization for processor, peripherals, etc. My SDK is Eclipse Kepler with AC6.

The system collapses sometimes and sometimes not, and I don't know why. I've been reading at this forum, and I've found some similar cases, where the system collapses due to interrupts. Other ones (Clive) says that more than 4GB SD cards may causes problems. I don't know why it collapses, and another code without the Queue works properly (but it cannot storage information at the rates I will need). I'm desperate, and the solution is not clear. If someome can help me I will be grateful.

Feel free to request code extracts and everyting you want. 

Thanks and best regards.

#problem #stm32 #interrupt #sd
4 REPLIES 4
Posted on November 10, 2016 at 13:34

My issue with >4GB is that you can't use a 32-bit BYTE offset to describe the address. The block device isn't byte addressable, with 512 byte blocks a 32-bit BLOCK address can describe 2TB. ST has an annoying habit of converting back and forth between BYTE and BLOCK values, they fixed the 32-bit limit by using 64-bit offsets, but the conversions are both unnecessary, and if the math is compiled wrong, prone to break.

To get any speed from SD cards you need to write in multiples of 512 bytes, aligned on 512 byte boundaries. Ideally you'd want to write 8KB or 32KB, etc as a single operation, otherwise the command overhead dominates. The erase block size of most current SD cards is the order of 128KB, operations spanning this alignment will be slower.

Writing 310 bytes at a time is going to be pretty slow, and compounded if done repetitively.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
vicfer89
Associate II
Posted on November 10, 2016 at 15:03

Hi clive,

First of all, thanks for your reply.

I've been trying to change HAL bsp SD functions (HAL_SD_WriteBlocks and HAL_SD_ReadBlocks), and if I change them, the code stops working. So if the problem were fixed, I will not follow that ''debug'' line anymore.

As an actualization, I were using a synchronization after each string, so my process was as follows:

  1. Parsed data were sent to SD using f_printf.
  2. File was synchronized using f_sync.

Now, synchronization has been removed, and the system works properly. Is it possible that it has been any kind of overflow?. Syncronization is a slow process, so I think that could be a probable issue.

Another test that I will try is to migrate to DMA writing process, so... in your opinion; Could it improve the behavour of the system?.

Lots of thanks.

Posted on November 10, 2016 at 18:49

I'm not a HAL user, I'm using the F4 with SDIO+DMA under the SPL, get multi MBps performance there.

f_sync() will kill performance, shouldn't crash the driver though. Decide a MB or time threshold to do this.

Don't use f_printf(). Use sprintf() advancing in a buffer, say 8KB+400 bytes, whenever you hit over 8KB, write the 8KB and then copy any excess to the beginning of the buffer, and start filling again. Remember printf() returns the number of bytes output. So think s += sprintf(s, ''%d\n'', number++);

If you have 32KB free, a buffer of that size would be better.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
vicfer89
Associate II
Posted on November 10, 2016 at 20:17

Thanks again.

I will try to implement a buffer into my code. I hope it gets better performances.