Maybe this happens when an exception is thrown.
This can happen if lv_task_handler
calls some callback which raises an exception without catching it. In such case I believe lv_task_handler
won’t return.
A general question is whether LVGL always keeps its state consistent in cases of callback functions that don’t always return. This could also happen on other bindings such as C++.
Another option is that the Micropython thread being blocked, but I doubt this is the case because I would expect the scheduler to be blocked and apparently it’s not.
Are you using the _thread
module? Maybe one thread is blocked and others still run?
I’m not sure catching Python exceptions on C code is the best idea.
But catching exceptions in Python is straightforward, so here are some ideas:
- Try this with
lv_async
. Since ILI9341 imports lvesp32 (unfortunately), you need to calllvesp32.deinit()
after initializing the display and only then calllv_async()
. In current project I’m using uasyncio with this technique.
The advantage is that you don’t need to rely on Micropython scheduler.
I think that ili9xxx should not importlvesp32
, but changing that now would break backward compatibility for anyone assuming ili9xxx importslvesp32
, so maybe it’s better to do this change only on the next major release. - Replace
lvesp32
by Python implementation that uses a timer, as done with stm32.
It might be possible to calllv_task_handler
directly, although I’m not sure. The docs, at least, warn that the callback might be called in interrupt context so we would still need to callschedule
in order to calllv_task_handler
. On the other hand, this scheduling is (apparently) not needed for stm32 so maybe we can get away with that on esp32 as well. - Replace
lvesp32
by Python implementation that uses a FreeRTOS timer, like done in lvesp32.
That would require exposingxTimerCreate
on espidf with callback conventions etc. - Another thought - if the Micropython’s thread (FreeRTOS task) priority is higher than the httpd priority, Micropython could block httpd indefinitely since FreeRTOS uses strict priority.
If you don’t want to change thread priorities, a simple thread wait (esp.task_delay_ms
) could give the lower priority thread an opportunity to run. - This problem reminds me the issues we had with lvesp32 + bluetooth. Increasing the timer period there seemed to help to some extent.