Adding esp_http_server.h to the generator

Where am I doing that? I don’t think I do that. lv_tick_inc runs freely at full rate.

And I also don’t think I am doing that. I just try the lock (using the 0 as a parameter to “Take”). If that fails I return immediately.

Oh I see, I thought you were trying to block execution.
So why not use a simple counter? What’s the benefit of a FreeRTOS semaphore here?

This can IMO be called from different threads and from irq context. Using the binary semaphore prevents race conditions if e.g. one thread is in the middle of decreasing your suggested counter e.g. from 0x0100 to 0x00ff and for a fraction of a second the other task sees 0x0000 … or the like.

I think using these mechanisms whenever potentially crossing task or even core boundaries is a good idea. There are also ounters available: https://www.freertos.org/CreateCounting.html

Uhm … you are right … in this case it’s the timer and the MP function which are running in the same context. A counter should be fine …

I don’t think they can be called from irq context.
vTimerCallback is called from FreeRTOS command queue thread while mp_lv_task_handler is called from Micropython main thread, so they are called from different threads.

So an atomic read/write of a counter is enough, but we can also use a counting semaphore if you think there is still a risk.

Did you consider the case of an exception that is thrown from lv_task_handler?

Actually I don’t understand how a python exception would stop the C function execution. This would IMO only work if there were RTOS tasks or threads involved which can be killed before they return. But you just told me that this all runs inside one context.

I could be wrong, but I believe MicroPython can manipulate the stack, so standard C calling conventions get thrown out the window. :wink:

That’s stack unwinding. Same idea as C++ exceptions, implemented with setjmp etc.
You can catch and handle Micropython exceptions in C code.
See an example on cb_isr on espidf.c.

Another option, as mentioned above, is to reimplement modlvesp32 in Python (like done for stm32) and handle the exceptions in Python code.

The whole setup most of the time works but often locks up and sometimes I have even weirder effects like the advance_demo suddenly complaining that list indices are out of range or that some object in the touch driver has no append member.

Sounds like something is messing with memory or the stack. I’ll see if I can increase the stack size …

If it’s working then it’s working really great with great download speeds while the Chart demo runs. It’s IMHO really worth to have this running stable …

You can try changing MP_TASK_STACK_SIZE.
I’ve already increased it in lv_micropython to 32KB, which is a lot, but you can try increasing it even more.

There’s also a 4k stack passed to the httpd as a config parameter. I’ll change that first.

Attached is a patch of the current state. It can be applied to the current https://github.com/lvgl/lv_micropython

It runs the attached python script which expects a previous network setup in boot.py

It serves /index.html from python and will serve all files stored in /www under the uri /fs.

http_server.patch.txt (11 KB)

http_server.py.txt (3.6 KB)

This also includes the latest patch of gen_mpy.py which hasn’t made it into lv_micropython, yet.

Edit: This does not include any patch for modlvesp32.c and will thus not work at all under high graphics load.

For your entertainment, here are some of the error messages I see when running MP+LVGL with the httpd. The httpd itself seems to be fine as nothing fails if i request non-existent urls which httpd handles internally without callback to python.

Traceback (most recent call last):
  File "xpt2046.py", line 209, in read
  File "xpt2046.py", line 181, in get_coords
  File "xpt2046.py", line 174, in get_med_coords
TypeError: 'httpd_req_t' object isn't iterable

SyntaxError: Can't convert httpd_req_t to lv_anim_t!

Traceback (most recent call last):
  File "xpt2046.py", line 209, in read
  File "xpt2046.py", line 181, in get_coords
  File "xpt2046.py", line 170, in get_med_coords
  File "xpt2046.py", line 162, in xpt_cmds
AttributeError: 'httpd_req_t' object has no attribute 'append'

Very funny how httpd_req_t sneaks into things that are totally unrelated.

Interestingly all of these involve httpd_req_t which is the object created by the httpd and which is then passed to MP through the callback …

How sure are we that m_new_obj() is ok to be called from a different context like the httpd?

When is it called from different context?
If it is called inside a scheduled function, then it is always called in the same context.

It’s called here

if(!mp_sched_schedule((mp_obj_t)&http_server_handler_cb_obj, NEW_PTR_OBJ(httpd_req_t, req))) { ... }

inside NEW_PTR_OBJ as this is needed to create the object that can then be passed to the scheduler.

If that is really the problem then I could try to store the req structure somewhere, create an empty httpd_req_t in the python callback and request this to be filled by native code from the stored req structure …

Edit: But I need some minimal context in the scheduled C function. How do I get that if this needs to be a python object and if i cannot create python objects from the httpd context?

Right.
I think it’s safe.
m_new_obj calls m_malloc which calls gc_alloc.
gc_alloc is protected with a mutex. (GC_ENTER)

So my guess is that it’s ok to call m_new_obj() from other threads.


EDIT - I’m assuming MP_STATE_MEM is the same for both contexts, so it’s worth making sure this is the case.

As you can see from my error messages, httpd_req_t shows up in places where it shouldn’t. So something is seriously being messed up somewhere … and it really feels like the python wrapper surrounding httpd_req_t overwrites things it shouldn’t. For some odd reason it likes to show up in the xpt driver. But that may just be because i did these tests at low load and the touch driver cobstantly being polled may just be the part most used in this case.

Can I somehow pass a Python object to the c side? I could avoid having to create the object then.

Yes, both sides seem to agree on the memory location of that and its contents.