Interrupt handlers aren't allowed to allocate any memory, which unfortunately means that even reporting an error is problematic.
The first thing I do is to add the call:
Code: Select all
import micropython
micropython.alloc_emergency_exception_buf(100)
into your code and hopefully get better error reporting.
As a general rule, you also shouldn't put delays in your interrupt handlers.
pyb.delay requires the SysTick interrupt to work, so it may not work in your interrupt handler. The pyb.udelay doesn't require interrupts to work (at least not on the stmhal port), but while you're delaying, other lower-priority interrupts will be delayed as well.
I tried adding those lines, and I still see the same thing, which is not what I was expecting. So I think you've uncovered a bug.
The bug in your routine is the line: pyb.Led(1).toggle which has 2 potential issues. I thought the first issue would be that pyb.Led(1) allocates a LED object, but it turns out that internally the LED module pre-allocates all of the LED objects. The second issue is that you're missing the parenthesis to call toggle().
If you rewrite your routine:
Code: Select all
import pyb
import micropython
micropython.alloc_emergency_exception_buf(200)
sw = pyb.Switch()
def BTN_callback():
pyb.LED(1).toggle()
sw.callback(BTN_callback)
I'll take a look into why no error is reported when the parenthesis are removed. I suspect that what's happening is that because pyb.LED(1).toggle is a function object and that the code is trying to allocate some memory to store that function object; which would be what's causing the MemoryError, but I would have expcected some traceback information.