You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
030 DEVICE_HEAP_ERROR codal error on long-running code using neopixel and display #228
neopixel-thirty-bug-repro-7.py is likely to eventually produce a 030 (DEVICE_HEAP_ERROR) on a micro:bit v2 perhap after 4-50 hours of running. It will do this without any WS2812 RGB LEDs attached, as expected.
This is on MicroPython v1.18 on 2023-10-30; micro:bit v2.1.2 with nRF52833.
Worth a second check but I don't think it has any memory leaks in the python code.
It's not very likely, but I wonder if the pattern list being constantly popped and appended into could be creating some memory fragmentation. If possible, would you mind converting that into a list of constant length and maybe using an index variable instead?
Could you also try commenting out the Neopixel code and see if that still triggers it? If it still happens there it points at maybe the leak being in the neopixel CODAL layer.
If there was a failure to allocate memory wouldn't that create a MemoryError exception? What expected cases are there for an 030 to be produced?
I may be out of touch for how GC works in MicroPython/CircuitPython. I thought it didn't have compaction but I'm wondering if it has segregated areas for small and large objects or heuristics/hints for short and long lived objects?
I was able to replicate this with the original code and the current MicroPython in the micro:bit Python Editor.
Creating a Neopixel stub that doesn't send anything to the PWM pin (and removing the built-in MicroPython import), and I can confirm the program doesn't crash after running all night.
This does point at the issue being in the CODAL neopixel implementation.
If there was a failure to allocate memory wouldn't that create a MemoryError exception? What expected cases are there for an 030 to be produced?
Yeah, I think you are right, that should have raised a MicroPython memory error instead.
I may be out of touch for how GC works in MicroPython/CircuitPython. I thought it didn't have compaction but I'm wondering if it has segregated areas for small and large objects or heuristics/hints for short and long lived objects?
I know CircuitPython did this a few years ago, I'm not sure if MicroPython has done the same or something similar.
It's not very likely, but I wonder if the pattern list being constantly popped and appended into could be creating some memory fragmentation. If possible, would you mind converting that into a list of constant length and maybe using an index variable instead?
@microbit-carlos That's actually how my real application code evolved. When I was doing a lot of list growing and shrinking I got MemoryErrors like this so I switched to a flattened array.array. I didn't think much about it at the time but the %u is weird.
Traceback (most recent call last):
File "main.py", line 52, in <module>
File "zc_bg_digitalrain.py", line 19, in render
MemoryError: memory allocation failed, allocating %u bytes
One cause of this is buggy WS2812B code and a check in the RefCounted code which throws an 030 under certain (reasonable) circumstances, example in lancaster-university/codal-microbit-v2#475 (comment) . There might be more, of course.
I've moved another 030 I got to lancaster-university/codal-microbit-v2#475 (comment) as I'm suspecting it's an interrupt firiing for PWM2 when they are not expected or not supposed to and not a general issue.
i think i saw 030 like that in case of a stack overflow. an unfortunate coincidence eventually grows the stack too large while the heap is also busy at the top and the corruption happens.
@attila-lendvai It's been a while since I looked at this. Your addition sounds useful in general but I don't think the ones I saw were stack related.
As per #228 (comment) there's an explicit target_panic(DEVICE_HEAP_ERROR) in the code and I think a bug was triggered that. I fixed a lot of bugs back in the Summer of 2025, perhaps all the PWM/NeoPixel related ones in, here are the pending PRs:
Activity
microbit-carlos commentedon Apr 1, 2025
It's not very likely, but I wonder if the
patternlist being constantly popped and appended into could be creating some memory fragmentation. If possible, would you mind converting that into a list of constant length and maybe using an index variable instead?Could you also try commenting out the Neopixel code and see if that still triggers it? If it still happens there it points at maybe the leak being in the neopixel CODAL layer.
kevinjwalters commentedon Apr 2, 2025
If there was a failure to allocate memory wouldn't that create a
MemoryErrorexception? What expected cases are there for an030to be produced?I may be out of touch for how GC works in MicroPython/CircuitPython. I thought it didn't have compaction but I'm wondering if it has segregated areas for small and large objects or heuristics/hints for short and long lived objects?
microbit-carlos commentedon Apr 2, 2025
I was able to replicate this with the original code and the current MicroPython in the micro:bit Python Editor.
Creating a Neopixel stub that doesn't send anything to the PWM pin (and removing the built-in MicroPython import), and I can confirm the program doesn't crash after running all night.
This does point at the issue being in the CODAL neopixel implementation.
Yeah, I think you are right, that should have raised a MicroPython memory error instead.
I know CircuitPython did this a few years ago, I'm not sure if MicroPython has done the same or something similar.
kevinjwalters commentedon Apr 13, 2025
@microbit-carlos That's actually how my real application code evolved. When I was doing a lot of list growing and shrinking I got
MemoryErrors like this so I switched to a flattenedarray.array. I didn't think much about it at the time but the%uis weird.kevinjwalters commentedon Jul 22, 2025
One cause of this is buggy WS2812B code and a check in the
RefCountedcode which throws an030under certain (reasonable) circumstances, example in lancaster-university/codal-microbit-v2#475 (comment) . There might be more, of course.https://github.com/lancaster-university/codal-core/blob/caee1151f0fdfb3a6678f9c269e7b33c9163bfea/source/types/RefCounted.cpp#L52
kevinjwalters commentedon Jul 24, 2025
I've moved another 030 I got to lancaster-university/codal-microbit-v2#475 (comment) as I'm suspecting it's an interrupt firiing for PWM2 when they are not expected or not supposed to and not a general issue.
kevinjwalters commentedon Aug 11, 2025
I've not seen any of these errors in my recent testing. I think these could all be due to the bugs described in lancaster-university/codal-microbit-v2#475 and fixed in lancaster-university/codal-nrf52#59. I did a four day test with no crashes in lancaster-university/codal-nrf52#59 (comment). More testing ongoing. I'll close this ticket if all is okay.
attila-lendvai commentedon Aug 26, 2026
i think i saw 030 like that in case of a stack overflow. an unfortunate coincidence eventually grows the stack too large while the heap is also busy at the top and the corruption happens.
i've added an explicit guard for stack overflow: lancaster-university/codal-core#197
you may try to run with that and see if you get the new error code.
kevinjwalters commentedon Aug 26, 2026
@attila-lendvai It's been a while since I looked at this. Your addition sounds useful in general but I don't think the ones I saw were stack related.
As per #228 (comment) there's an explicit
target_panic(DEVICE_HEAP_ERROR)in the code and I think a bug was triggered that. I fixed a lot of bugs back in the Summer of 2025, perhaps all the PWM/NeoPixel related ones in, here are the pending PRs:attila-lendvai commentedon Aug 26, 2026
@kevinjwalters oh! i have just realized that your PR's are a year+ old. that's somewhat discouraging... :/
i have clicked around, and it has many commits that seem sane and useful.
were none of these at least cherry-picked into master, even if the entire PR wasn't merged as-is?
kevinjwalters commentedon Sep 25, 2026
@attila-lendvai All of the fixes are needed, the statistics code which is
ifdef'ed could be dropped. None has been merged in AFAICT... :( yet...