#define SYS_THREAD_MAX 4
static bool g_lwip_in_critical_section = false;
+static BaseType_t g_lwip_critical_section_needs_taskswitch;
#if !LWIP_COMPAT_MUTEX
/** Create a new mutex
sys_sem_signal(sys_sem_t *sem)
{
if (g_lwip_in_critical_section){
- xSemaphoreGiveFromISR(*sem, NULL);
+ /* In function event_callback in sockets.c, lwip signals a semaphore inside a critical
+ * section. According to the FreeRTOS documentation for FreertosTaskEnterCritical, it's
+ * not allowed to call any FreeRTOS API function within a critical region. Unfortunately,
+ * it's not feasible to rework the affected region in LWIP. As a solution, when in a
+ * critical region, we call xSemaphoreGiveFromISR. This routine is hand-vetted to work
+ * in a critical region and it will not cause a task switch.
+ */
+ xSemaphoreGiveFromISR(*sem, &g_lwip_critical_section_needs_taskswitch);
} else {
xSemaphoreGive(*sem);
}
(void) pval;
g_lwip_in_critical_section = false;
portEXIT_CRITICAL(&g_lwip_mux);
+ if (g_lwip_critical_section_needs_taskswitch){
+ g_lwip_critical_section_needs_taskswitch = 0;
+ portYIELD();
+ }
}
/*-----------------------------------------------------------------------------------*/