2020-10-14 12:09 AM
I'm working on my first large-ish C++ embedded program running on a STM32F413. Bare metal, no RTOS at least so far. The program reads data from a dozen or so UART and I2C sensors. All the UART sensors currently use DMA for TX and RX. When a complete message is received from any sensor, it needs to get time stamped. Based on advice from other forums, I'm investigating putting the RTC driver in a) a singleton, b) using extern "C" or c) using a static class. In all three options, I think I'll still need a way to lock the few lines of my code that actually read the RTC.
If one sensor's ISR is in the process of getting a time stamp from the RTC, will HAL_LOCK prevent another sensor from interrupting ?
If the interrupt priority of every sensor is set to the same value, will that prevent them from interrupting each other? This doesn't seem like a great solution since data from some sensors is more important than others.
I'm sure I'm not the first one to have to deal with this issue so how do experienced programmers handle RTC access?
Thanks
2020-10-14 12:21 AM
> If the interrupt priority of every sensor is set to the same value, will that prevent them from interrupting each other?
Yes, it will postpone arriving requests, until the current one is finished.
This can (and within Cube/HAL surely will) lead to overrun problems, were you loose transmissions.
Priorizing interrupts or globally disabling them might have the same result.
An interrupt handler should do as little as possible.
You could instead read the RTC just once in a while (every few seconds or so), and use a second counter for an offset.
A systick set to a decadic fraction (1ms, 10ms) would be a good candidate.
2020-10-14 12:51 AM
Or disable the interrupts globally before reading the RTC and reenable after. Or use any of the possible mechanisms involving priorities to prevent interrupts from nesting (i.e. simply have all interrupts using RTC at the same priority level).
Nonetheless, I don't quite see, why would it be a problem at all. The hardware locking mechanism is broken, as per errata, so if you need consistent data from multiple RTC registers, you have to perform the "two reading and repeat if not match" procedure anyway.
JW
2020-10-14 08:52 AM
Darn, I was hoping there was some magic bullet answer. When it's time to sample the sensors, I send the read commands one right after another with no blocking. Luckily I only have to read my sensors every couple of seconds. Responses from the sensors are completely asynchronous. If I set all the sensor interrupts to the same level, and assuming all the sensors can be queried and respond before the next round of queries, should make sure I don't lose any data. Does that sound right? It seems like this a random process that I don't know how to test deterministcally but I'll set up a test and let it run for a couple of days to see what happens.
@Community member - Thanks for pointing out the importance of reading the errata docs. I checked the errata doc for the STM413 and it doesn't seem to mention the "two reading and repeat" issue. Should I assume it isn't a problem on the 413 or assume it is and just isn't documented?
2020-10-14 01:37 PM
Check this erratum in the 'F407 errata, compare it's timestamp in changelog with the age of the 'F413 errata.
Nonetheless, I still don't quite understand what is your problem, can you please describe a scenario of failure.
JW
2020-10-14 10:09 PM
@Community member Here's the scenario I'm trying to address. I send a non-blocking "sensor1::getData()" command immediately followed by a non-blocking "sensor2::getData() command and my app keeps doing other non-blocking tasks. Eventually (10s to 100s of milliseconds depending on the sensor) All of sensor1's data arrives and its HAL_UART_RxCpltCallback fires. I'd like to timestamp the data as close to its arrival time as possible so the Callback sends a getTimestamp() request to the RTC. But if I don't do things correctly and sensor2's HAL_UART_TxCpltCallback fires and sends it own getTimestamp request before sensor1's getTimestamp() completes, things could get messy.
Based on the help you and @Ozone provided, if I set both sensor1 and sensor2 IRQs to the same level, sensor 2 won't interrupt sensor1's Callback at all. If I understand correctly, sensor 2's DMA RX transfer will keep running while sensor 1's callback completes but sensor 2's Callback won't run until sensor1s' completes.
Hope that makes sense and thanks again for the help. If that's close to correct, I think you guys have given me what I need to move forward.