From 55726385a44a565b707707a91d12adacc7cbcd61 Mon Sep 17 00:00:00 2001 From: Liu Zhi Fu Date: Thu, 15 Dec 2016 15:06:00 +0800 Subject: [PATCH] add more comments and call portYIELD when necessary --- components/lwip/port/freertos/sys_arch.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/components/lwip/port/freertos/sys_arch.c b/components/lwip/port/freertos/sys_arch.c index 9efb151e8..97ee32d1b 100755 --- a/components/lwip/port/freertos/sys_arch.c +++ b/components/lwip/port/freertos/sys_arch.c @@ -43,6 +43,7 @@ #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 @@ -125,7 +126,14 @@ void 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); } @@ -476,6 +484,10 @@ sys_arch_unprotect(sys_prot_t pval) (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(); + } } /*-----------------------------------------------------------------------------------*/