Sharing variable updates to a read-only ISR

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
jim
Posts: 20
Joined: Tue Feb 23, 2021 10:22 pm

Sharing variable updates to a read-only ISR

Post by jim » Wed Jun 30, 2021 4:10 pm

We have a real-time control loop that runs in a time-based ISR at 500Hz. It uses feedback from a number of sensors that are read in the same ISR.

An additional sensor whose data is less time-critical reports at regular intervals (also roughly 500Hz), and notifies the system when it has updates by setting an I/O line. We have this line tied to a separate ISR to read the data. The ISR then uses micropython.schedule() to do a bit of signal conditioning before writing to a handful of variables (roughly 20 bytes total) that need to be shared with the timer-based ISR.

I've read the docs on implementing assembler-based mutexes, but I'm wondering if we can get by with something simpler, as write operations are performed outside an ISR and the timer-based ISR only needs read access. I just want to avoid a situation where a write operation is interrupted by the timer-based ISR resulting in data corruption.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Sharing variable updates to a read-only ISR

Post by dhylands » Wed Jun 30, 2021 7:17 pm

When you say "write operation" can you be more specific? Are you talking about updating the contents of variable in memory? If so, then an ISR reading the same variable shouldn't cause any corruption.

If you're talking about something like "write some values to an I2C sensor)" then you definitely have a valid concern and need to ensure that you don't try to perform any "read a value using I2C" while you're in the middle of writing a value using I2C.

If you're concerned about writing to multiple variables and having the update of these multiple variable be atomic, then you pretty much need to disable interrupts, do your write updates, and then re-enable interrupts. Then when your ISR runs it will read a consistent set of values.

jim
Posts: 20
Joined: Tue Feb 23, 2021 10:22 pm

Re: Sharing variable updates to a read-only ISR

Post by jim » Wed Jun 30, 2021 7:30 pm

Yes, I'm talking about simple variable updates. I'm okay if only some of the variables are updated. However, values will probably be updated in an array of floats and my concern is that—in rare circumstances—the ISR might kick in when a single value is partially written.

Thanks for your help.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Sharing variable updates to a read-only ISR

Post by dhylands » Thu Jul 01, 2021 2:52 am

If you're using 32-bit floats, then I'm pretty sure that the writes will be atomic.

Anything done during micropython.schedule will be fine.

A hard ISR can't use floats since floats require memory allocations.

A function run using micropython.schedule can allocate memory so using floats in there is fine.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Implication of garbage collection

Post by pythoncoder » Fri Jul 02, 2021 11:38 am

I'd be wary of running micropython.schedule at a 500Hz rate: if it is called by a hard ISR while a garbage collect is running, it will be delayed until GC is complete. The duration of this delay depends on a lot of factors but can be well over 2ms. The worst case is probably an ESP32 with SPIRAM where GC can take 100ms. On the other hand if you're running a Pyboard and your code performs GC regularly, you might be able to keep it below 1ms.
Peter Hinch
Index to my micropython libraries.

Post Reply