Open gemarcano opened 7 months ago
After some more experimentation, the implementation of async_context_freertos_*
functions, which are called by cyw43_arch_init
, assume that they are taking place within the context of an already running FreeRTOS. For example, async_context_freertos_execute_sync
calls xQueueSemaphoreTake
near its end, and that in turn calls vTaskPlaceOnEventList
, which implicitly assumes the current thread is running within FreeRTOS.
Per the documentation on async_context_execute_sync
I think I understand what the hard_assert
is checking against-- it is very clear in the documentation that the context's lock should not be held by whoever is calling execute_sync
, so it's just checking against that.
So it does look like this behavior is intentional-- it might be a good idea to document that when using the FreeRTOS async_context, cyw43*
functions should be called within a FreeRTOS task.
edit: and possibly also async_context_freertos
functions.
Yes, you're probably right - it needs to be documented.
I've successfully managed to convert the NTP client example Pico W example from its original LwIP raw API form to one using NO_SYS=0 FreeRTOS SMP and the LwIP socket API.
I was thinking the other day that we really need more examples of this. Any chance of contributing this to pico-examples?
Sure, I've submitted a draft example based on my code. My own personal code was all in C++, so it took a bit but I managed to get it back to C.
I am using upstream FreeRTOS with the SMP work merged into main (and using PR #1530 to fix the renaming of a FreeRTOS config).
I've successfully managed to convert the NTP client example Pico W example from its original LwIP raw API form to one using NO_SYS=0 FreeRTOS SMP and the LwIP socket API. In the process, I discovered that if I tried calling
cyw43_arch_init
frommain()
, the pico would hard crash with no output whatsoever. It worked fine if called from a FreeRTOS task.I rigged up a second pico as a debug probe, and found a
hard_assert
that was failing inasync_context_freertos_execute_sync
. Specifically:When called from
main()
or outside of a FreeRTOS task,xTaskGetCurrentTaskHandle()
returns 0, and in general I'm seeingxSemaphoreGetMutexHolder(self->lock_mutex)
return 0 during initialization (as apparently no tasks have claimed the mutex). This clearly leads to the hard_assert to fire when callingasync_context_freertos_execute_sync
outside of a FreeRTOS task.Is this intentional? I'm also not 100% sure what that
hard_assert
is checking. Is it to catch some sort of recursive calling/deadlock (although I don't see that mutex being claimed during init-- maybe it is in other execution paths?)?