Sure, but under the hoods the Python object you are passing is also created with m_new_obj so I donāt see how that would help.
On the C side a Python object is represented by mp_obj_t.
Maybe the object is garbage collected?
In such case its memory is allocated to another object. So when you write to it you overwrite some other Python object.
To prevent this, a reference to your object must be preserved somewhere on the Python side.
You can verify whether gc is related by trying to disable garbage collection by gc.disable(), and see if the problem still happens when gc is disabled.
I am testing a very ugly solution which so far looks pretty good ⦠I am not generating a new object for every callback. Instead I create it once to re-use it. So I keep a reference and replace the embedded pointer on every callback invocation,
But now I likely have a gc problem since Iāll never know when gc will destroy this object ⦠I can of course keep a reference on python side but that will look confusing as I keep a reference to this object for no apparent reason.
You can keep it as another member of handler_data_t next to user_data.
The user wonāt care about your object in the same way he doesnāt care about user_data, but gc will not collect it as long as the user holds handler_data_t.
Still⦠I wonder what we are missing here that is causing this issue.
I am doing exactly that. But how should gc know that this void pointer actually points to one of the objects its about to delete? MP IMO does not know anything about pointers I store inside handler_data_t.
It knows.
The gc scans all memories it allocated (handler_data_t included) looking for pointers to other memories it allocated, and marks them (itās a āmark and sweepā gc).
Correct.
But the chances for that are low and the consequences are mild (some memory would not be freed).
If anything, the disadvantage is performance. Every time gc is collected, all allocated RAM is being read actually.
But this actually makes my ādirtyā solution to be at least āokā. Yes, you are right, that we should understand whatās the problem with this object creation as I am still doing this once and it may just be the case that this is still doing harm and still overwrites the wrong memory area. The problem may just have become less obvious but it may still be there.
Anyway, things start to become usable and the httpd performs pretty good even when lvgl is under load and when each httpd request requires a callback into python.
I still think I would like to add the ability to serve files without any callback into python. But in order to do that I would have to access vfs from httpd ā¦
With LVGL in the bg it still crashes quite fast. Even with a minimal single label screen without touch driver.
What happens is quite interesting: The args pointer given to the scheduler doesnāt arrive in the handler. Instead ā6ā arrives which imho is MPās represenation for āNoneā. This happens with gc disabled.
⦠and reboot as dereferencing 6 isnāt a good idea. Now I need to figure out where this can get lost.
Edit: This is not a permanent thing. If I allow the handler to return if arg is wrong then the subsequent calls are often fine again. So thereās nothing permanently messed up.
Using uasync for the lvgl handling doesnāt change anything (assuming I did it correctly). Attached are my two simple http_servers, each serving a single simple page and running a small scrolling label inlvgl. One classic style using the scheduler and one using uasync.
Iāve checked that MP_STATE_VM(sched_queue) is consistent in the good and the failing scheduler invocations. It is ā¦
No, I donāt. The ESP32 modules donāt expose the JTAG pins, do they?
Anyway, I was wrong about the uasync test. The lvesp32.deinit() also needs to be put after the display has been initialized. Otherwise it starts to call the scheduler, again.
And guess what? Now that the scheduler is not used by lvgl anymore, the httpd runs somewhat stable. I still think we should understand why using the scheduler the normal way leads to this problem.
ESP32 PORT FT232H PORT COLOR
========== ========== ======
GPIO13 AD0 (TCK) Purple
GPIO12 AD1 (TDI) Blue
GPIO15 AD2 (TDO) Green
GPIO14 AD3 (TMS) Yellow
GND GND Black
I agree, and I think that a debugger could be helpful for that.
I just ordered a ft232h adapter. These GPIOs are being used on my custom board but I should easily do a breadboard setup that exposes the same issues.
My current suspicion is that the MP scheduler is not multicore safe. What I do see in these problematic situations is that function pointers and arg pointers do get messed up ⦠as if the scheduler queue is written while the scheduler runs entries from it. There are āatomicā macros which are supposed to handle that.
Under the hoods it uses a mutex exposed by ESP32-FreeRTOS, which is multicore safe, but maybe thereās some MP code which should be protected and is not.