kopia lustrzana https://github.com/espressif/esp-idf
lwip: implement lwip critical session with mutex
Currently lwip critical session is based on interrupt, now replace it with mutexpull/408/merge
rodzic
74d0edec0f
commit
778a475136
|
@ -38,12 +38,13 @@
|
||||||
#include "lwip/mem.h"
|
#include "lwip/mem.h"
|
||||||
#include "arch/sys_arch.h"
|
#include "arch/sys_arch.h"
|
||||||
#include "lwip/stats.h"
|
#include "lwip/stats.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
/* This is the number of threads that can be started with sys_thread_new() */
|
/* This is the number of threads that can be started with sys_thread_new() */
|
||||||
#define SYS_THREAD_MAX 4
|
#define SYS_THREAD_MAX 4
|
||||||
|
#define TAG "lwip_arch"
|
||||||
|
|
||||||
static bool g_lwip_in_critical_section = false;
|
static sys_mutex_t g_lwip_protect_mutex = NULL;
|
||||||
static BaseType_t g_lwip_critical_section_needs_taskswitch;
|
|
||||||
|
|
||||||
#if !LWIP_COMPAT_MUTEX
|
#if !LWIP_COMPAT_MUTEX
|
||||||
/** Create a new mutex
|
/** Create a new mutex
|
||||||
|
@ -125,18 +126,7 @@ sys_sem_new(sys_sem_t *sem, u8_t count)
|
||||||
void
|
void
|
||||||
sys_sem_signal(sys_sem_t *sem)
|
sys_sem_signal(sys_sem_t *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);
|
xSemaphoreGive(*sem);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -394,7 +384,7 @@ sys_mbox_free(sys_mbox_t *mbox)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count == (MAX_POLL_CNT-1)){
|
if (count == (MAX_POLL_CNT-1)){
|
||||||
printf("WARNING: mbox %p had a consumer who never unblocked. Leaking!\n", (*mbox)->os_mbox);
|
ESP_LOGW(TAG, "WARNING: mbox %p had a consumer who never unblocked. Leaking!\n", (*mbox)->os_mbox);
|
||||||
}
|
}
|
||||||
sys_delay_ms(PER_POLL_DELAY);
|
sys_delay_ms(PER_POLL_DELAY);
|
||||||
}
|
}
|
||||||
|
@ -440,6 +430,9 @@ sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize
|
||||||
void
|
void
|
||||||
sys_init(void)
|
sys_init(void)
|
||||||
{
|
{
|
||||||
|
if (ERR_OK != sys_mutex_new(&g_lwip_protect_mutex)) {
|
||||||
|
ESP_LOGE(TAG, "sys_init: failed to init lwip protect mutex\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -449,7 +442,6 @@ sys_now(void)
|
||||||
return xTaskGetTickCount();
|
return xTaskGetTickCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
static portMUX_TYPE g_lwip_mux = portMUX_INITIALIZER_UNLOCKED;
|
|
||||||
/*
|
/*
|
||||||
This optional function does a "fast" critical region protection and returns
|
This optional function does a "fast" critical region protection and returns
|
||||||
the previous protection level. This function is only called during very short
|
the previous protection level. This function is only called during very short
|
||||||
|
@ -466,8 +458,7 @@ static portMUX_TYPE g_lwip_mux = portMUX_INITIALIZER_UNLOCKED;
|
||||||
sys_prot_t
|
sys_prot_t
|
||||||
sys_arch_protect(void)
|
sys_arch_protect(void)
|
||||||
{
|
{
|
||||||
portENTER_CRITICAL(&g_lwip_mux);
|
sys_mutex_lock(&g_lwip_protect_mutex);
|
||||||
g_lwip_in_critical_section = true;
|
|
||||||
return (sys_prot_t) 1;
|
return (sys_prot_t) 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,13 +472,7 @@ sys_arch_protect(void)
|
||||||
void
|
void
|
||||||
sys_arch_unprotect(sys_prot_t pval)
|
sys_arch_unprotect(sys_prot_t pval)
|
||||||
{
|
{
|
||||||
(void) pval;
|
sys_mutex_unlock(&g_lwip_protect_mutex);
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -497,7 +482,7 @@ sys_arch_unprotect(sys_prot_t pval)
|
||||||
void
|
void
|
||||||
sys_arch_assert(const char *file, int line)
|
sys_arch_assert(const char *file, int line)
|
||||||
{
|
{
|
||||||
printf("\nAssertion: %d in %s\n", line, file);
|
ESP_LOGE(TAG, "\nAssertion: %d in %s\n", line, file);
|
||||||
|
|
||||||
// vTaskEnterCritical();
|
// vTaskEnterCritical();
|
||||||
while(1);
|
while(1);
|
||||||
|
@ -537,14 +522,14 @@ sys_sem_t* sys_thread_sem_init(void)
|
||||||
sys_sem_t *sem = (sys_sem_t*)malloc(sizeof(sys_sem_t*));
|
sys_sem_t *sem = (sys_sem_t*)malloc(sizeof(sys_sem_t*));
|
||||||
|
|
||||||
if (!sem){
|
if (!sem){
|
||||||
printf("sem f1\n");
|
ESP_LOGE(TAG, "thread_sem_init: out of memory");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*sem = xSemaphoreCreateBinary();
|
*sem = xSemaphoreCreateBinary();
|
||||||
if (!(*sem)){
|
if (!(*sem)){
|
||||||
free(sem);
|
free(sem);
|
||||||
printf("sem f2\n");
|
ESP_LOGE(TAG, "thread_sem_init: out of memory");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue