Page 1 of 1

Heap and interrupt handlers

Posted: Sat Feb 17, 2018 1:53 pm
by tuupola
I am bit confused about heap and interrupt handlers. Documentation says in several places that ISR cannot allocate memory from heap. For example:
ISR’s cannot create instances of Python objects. This is because MicroPython needs to allocate memory for the object from a store of free memory block called the heap. This is not permitted in an interrupt handler because heap allocation is not re-entrant. In other words the interrupt might occur when the main program is part way through performing an allocation - to maintain the integrity of the heap the interpreter disallows memory allocations in ISR code.
I am however able to run the following code. Am I missing something obvious?

Code: Select all

from machine import Timer

class Hello:
    def __init__(self, name):
        self._name = name

    def greet(self):
        print("Hello " + self._name)

def timer_greet(timer):
    hello = Hello(name="world!")
    hello.greet()

timer_0 = Timer(0)
timer_0.init(period=2000, mode=Timer.PERIODIC, callback=timer_greet)

Re: Heap and interrupt handlers

Posted: Sun Feb 18, 2018 9:01 am
by pythoncoder
I adapted this to run on the Pyboard, where interrupts are true hardware interrupts:

Code: Select all

from pyb import Timer
import micropython
micropython.alloc_emergency_exception_buf(100)

class Hello:
    def __init__(self, name):
        self._name = name

    def greet(self):
        print("Hello " + self._name)

def timer_greet(timer):
    hello = Hello(name="world!")
    hello.greet()

timer_0 = Timer(1)
timer_0.init(freq=1, callback=timer_greet)
with the following outcome

Code: Select all

>>> uncaught exception in Timer(1) interrupt handler
Traceback (most recent call last):
  File "<stdin>", line 12, in timer_greet
MemoryError: memory allocation failed, heap is locked

>>> 
The general statement in the docs is correct. However on ESP* platforms interrupts aren't necessarily true hardware interrupts. My understanding is that, even though no error is thrown, it's still inadvisable to allocate memory in ISR's because garbage collection is not re-entrant. If an ISR interrupts GC, attempts to allocate RAM and that attempt fails due to heap fragmentation, a re-entrant GC will be triggered. The outcome of this is likely to be some later crash which will be hard to diagnose.

Re: Heap and interrupt handlers

Posted: Sun Feb 18, 2018 5:41 pm
by tuupola
Makes sense, thanks. Guess I need to purchase some other boards than ESP32 for development to make sure code is portable.

Re: Heap and interrupt handlers

Posted: Mon Feb 19, 2018 7:20 am
by pythoncoder
I thoroughly recommend getting a Pyboard as reference hardware.