Merge branch 'bugfix/tw9240_fix_lwip_dual_core_issue' into 'master'

lwip: fix lwip dual core issue

Call xSemaphoreGiveFromISR instead xSemaphoreGive when the calling context is in critical section.

See merge request !314
This commit is contained in:
Wu Jian Gang 2016-12-15 17:33:28 +08:00
commit 847092e483

View file

@ -42,6 +42,9 @@
/* This is the number of threads that can be started with sys_thread_new() */
#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
* @param mutex pointer to the mutex to create
@ -122,7 +125,18 @@ sys_sem_new(sys_sem_t *sem, u8_t count)
void
sys_sem_signal(sys_sem_t *sem)
{
xSemaphoreGive(*sem);
if (g_lwip_in_critical_section){
/* 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);
}
}
/*-----------------------------------------------------------------------------------*/
@ -453,6 +467,7 @@ sys_prot_t
sys_arch_protect(void)
{
portENTER_CRITICAL(&g_lwip_mux);
g_lwip_in_critical_section = true;
return (sys_prot_t) 1;
}
@ -467,7 +482,12 @@ void
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();
}
}
/*-----------------------------------------------------------------------------------*/