stm32duino/STM32SD

Using STM32SD with STM32L4R9xx (sensortile box) BLE, and an ISR service for an accelerometer

Closed this issue · 3 comments

I am using the STM32duino. I'm using STM32 MCU based boards package 2.6.0 and STM32SD library 1.3.1 so I think I have the latest and greatest dev environment, as far as I know.

I am using only a handful of the basic SD functions. I start the SD card with SD.begin(SD_PIN_DETECT) and I use only basic capabilities such as SD.exists, SD.open, SD.mkdir, SD.remove and basic i/o commands such as file.available(), file.print(), file.println(), file.read(), file.peek() and when I open a directory, I use file.openNextFile() to traverse it.

I also have a BLE connection, a CDC U(S)ART service which is sometimes connected, and I have an accelerometer generating interrupts at some rate such as 25Hz, 50Hz, etc.

What I found: The SD service sometimes fails to start, sometimes it does start and seems to work intermittently, such as not traversing all of the files in the directory, or sometimes not writing to a file when SD.print() or SD.println() are called (it just skips it).

How I fixed it: Around each SD operation I put an interrupts disable wrapper. For example:

noInterrupts();
myFile = SD.open("myfilename.txt");
interrupts();

and

noInterrupts();
myFile.print("This is what I want in the file\n");
interrupts();

After doing that (I just went ahead and did it everywhere my code isn't that but) everything stabilized and works perfectly, with no errors and I'm sure hundreds-of-thousands if not millions of read/write operations. Before I did that, I would see errors quite often.

Any suggestions? I don't know if this is a bug or just a nuisance.

Thanks,
Glenn

fpistm commented

Hard to help without the full code.
Anyway, you have to ensure not interrupt services by calling another one. As several works with IT, you have to add delay or ensure it is ok to use another service.

Since I have a workaround, this isn't urgent for me right now. If necessary, I can probably build a small example code which has the same issue and send it, but as I'm currently focused on this project for my work, it might be a few weeks before I can produce a clean example that I can send.

Meanwhile, this is an outline of what I'm doing (all written in C of course, but I'm using words to describe the program below). Sprinkled throughout the code are lots of checks to see if the Serial device started, and if so, print messages to the console to show progress through the loop i.e. when a file starts or stops sending, when a BLE message is received, etc. If the console does not start in setup, it doesn't try to send these messages. The issue with the STM32SD calls persists whether or not the console messages are being sent:

setup():

start the IWatchdog
start the console CDC U(S)ART
start the accelerometer device
set up the acc_ISR
start the BLE
start the SD

acc_ISR:

read the accelerometer
store in accelerometer ring buffer

loop:

poll the BLE
if BLE characteristic is written (we receive a command over BLE):
    add to the BLE outbound queue the additional messages based upon the command
    for example: put directory contents in outbound BLE queue in response to a "list directory contents" command
    another example might be to save 2 seconds of accelerometer data to a file or to send a file
    another example command might be to get the last 2 seconds of accelerometer data which will be queued

if there are entries in the outbound BLE queue:

  send the next BLE queue message over BLE (one message per pass through the loop)

reset the watchdog

I have some logic in the main program to check if the BLE queue is getting close to full, and if so it will hold off populating it until BLE messages are sent and released from the queue, but that's never been tripped in my code thus far (there just isn't that much being queued).

So that's pretty much an outline of the code. In the example above, whenever I do any actions described above which require the STM32SD library, that's where I had to bracket the function calls with "noInterrupts()" and "interrupts()" calls. Without sending a full listing, this might help you understand the nature of the code structure.

PS: Sorry for the awkward formatting I couldn't figure out how to get the indentation to stick with just text.

I close it as no feedback since a while and can't reproduce.