mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
fix(lwip): Allocate signals/mboxes once to reduce heap frag
This commit is contained in:
committed by
David Čermák
parent
7c1fd3fbbf
commit
1019cb7c19
@@ -207,8 +207,8 @@ static void netif_unset_garp_flag(struct netif *netif)
|
|||||||
#endif // CONFIG_LWIP_GARP_TMR_INTERVAL
|
#endif // CONFIG_LWIP_GARP_TMR_INTERVAL
|
||||||
|
|
||||||
#if !LWIP_TCPIP_CORE_LOCKING
|
#if !LWIP_TCPIP_CORE_LOCKING
|
||||||
static sys_sem_t api_sync_sem = NULL;
|
static sys_sem_t api_sync_sem = {0};
|
||||||
static sys_sem_t api_lock_sem = NULL;
|
static sys_sem_t api_lock_sem = {0};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -588,14 +588,14 @@ esp_err_t esp_netif_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !LWIP_TCPIP_CORE_LOCKING
|
#if !LWIP_TCPIP_CORE_LOCKING
|
||||||
if (!api_sync_sem) {
|
if (!sys_sem_valid(&api_sync_sem)) {
|
||||||
if (ERR_OK != sys_sem_new(&api_sync_sem, 0)) {
|
if (ERR_OK != sys_sem_new(&api_sync_sem, 0)) {
|
||||||
ESP_LOGE(TAG, "esp netif api sync sem init fail");
|
ESP_LOGE(TAG, "esp netif api sync sem init fail");
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!api_lock_sem) {
|
if (!sys_sem_valid(&api_lock_sem)) {
|
||||||
if (ERR_OK != sys_sem_new(&api_lock_sem, 1)) {
|
if (ERR_OK != sys_sem_new(&api_lock_sem, 1)) {
|
||||||
ESP_LOGE(TAG, "esp netif api lock sem init fail");
|
ESP_LOGE(TAG, "esp netif api lock sem init fail");
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*/
|
*/
|
||||||
#ifndef __SYS_ARCH_H__
|
#ifndef __SYS_ARCH_H__
|
||||||
#define __SYS_ARCH_H__
|
#define __SYS_ARCH_H__
|
||||||
@@ -18,12 +18,20 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef SemaphoreHandle_t sys_sem_t;
|
typedef StaticSemaphore_t sys_sem_t;
|
||||||
typedef SemaphoreHandle_t sys_mutex_t;
|
typedef SemaphoreHandle_t sys_mutex_t;
|
||||||
typedef TaskHandle_t sys_thread_t;
|
typedef TaskHandle_t sys_thread_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Mailbox structure using static allocation to prevent heap fragmentation
|
||||||
|
*
|
||||||
|
* This structure uses FreeRTOS static queue allocation instead of dynamic allocation.
|
||||||
|
* The buffer[] field is a flexible array member that points to the queue storage
|
||||||
|
* allocated immediately after this structure.
|
||||||
|
*/
|
||||||
typedef struct sys_mbox_s {
|
typedef struct sys_mbox_s {
|
||||||
QueueHandle_t os_mbox;
|
StaticQueue_t os_mbox; /**< FreeRTOS static queue structure */
|
||||||
|
uint8_t buffer[]; /**< Flexible array member for queue storage */
|
||||||
}* sys_mbox_t;
|
}* sys_mbox_t;
|
||||||
|
|
||||||
/** This is returned by _fromisr() sys functions to tell the outermost function
|
/** This is returned by _fromisr() sys functions to tell the outermost function
|
||||||
@@ -45,9 +53,20 @@ void sys_delay_ms(uint32_t ms);
|
|||||||
#define sys_mbox_valid(mbox) (*(mbox) != NULL)
|
#define sys_mbox_valid(mbox) (*(mbox) != NULL)
|
||||||
#define sys_mbox_set_invalid(mbox) (*(mbox) = NULL)
|
#define sys_mbox_set_invalid(mbox) (*(mbox) = NULL)
|
||||||
|
|
||||||
#define sys_sem_valid_val(sema) ((sema) != NULL)
|
/**
|
||||||
#define sys_sem_valid(sema) (((sema) != NULL) && sys_sem_valid_val(*(sema)))
|
* @brief Check if a static semaphore is valid (initialized)
|
||||||
#define sys_sem_set_invalid(sema) ((*(sema)) = NULL)
|
*
|
||||||
|
* For static semaphores, we check if the structure is zero-initialized.
|
||||||
|
* A zero-initialized StaticSemaphore_t indicates an uninitialized semaphore.
|
||||||
|
*/
|
||||||
|
#define sys_sem_valid(sema) ((memcmp((sema), &(StaticSemaphore_t){0}, sizeof(StaticSemaphore_t)) == 0) ? pdFALSE : pdTRUE)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Mark a static semaphore as invalid (uninitialized)
|
||||||
|
*
|
||||||
|
* Sets the entire StaticSemaphore_t structure to zero, indicating it's uninitialized.
|
||||||
|
*/
|
||||||
|
#define sys_sem_set_invalid(sema) (memset((sema), 0, sizeof(StaticSemaphore_t)))
|
||||||
|
|
||||||
void sys_delay_ms(uint32_t ms);
|
void sys_delay_ms(uint32_t ms);
|
||||||
sys_sem_t* sys_thread_sem_init(void);
|
sys_sem_t* sys_thread_sem_init(void);
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
#include "arch/vfs_lwip.h"
|
#include "arch/vfs_lwip.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp_compiler.h"
|
#include "esp_compiler.h"
|
||||||
|
#include "esp_heap_caps.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static const char* TAG = "lwip_arch";
|
static const char* TAG = "lwip_arch";
|
||||||
|
|
||||||
@@ -96,11 +98,14 @@ sys_mutex_free(sys_mutex_t *pxMutex)
|
|||||||
#endif /* !LWIP_COMPAT_MUTEX */
|
#endif /* !LWIP_COMPAT_MUTEX */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates a new semaphore
|
* @brief Creates a new semaphore using static allocation
|
||||||
*
|
*
|
||||||
* @param sem pointer of the semaphore
|
* Uses FreeRTOS static semaphore allocation to prevent heap fragmentation.
|
||||||
* @param count initial state of the semaphore
|
* The semaphore structure is pre-allocated and passed to this function.
|
||||||
* @return err_t
|
*
|
||||||
|
* @param sem pointer to the pre-allocated semaphore structure
|
||||||
|
* @param count initial state of the semaphore (0 or 1)
|
||||||
|
* @return err_t ERR_OK on success, ERR_MEM on failure
|
||||||
*/
|
*/
|
||||||
err_t
|
err_t
|
||||||
sys_sem_new(sys_sem_t *sem, u8_t count)
|
sys_sem_new(sys_sem_t *sem, u8_t count)
|
||||||
@@ -108,14 +113,14 @@ sys_sem_new(sys_sem_t *sem, u8_t count)
|
|||||||
LWIP_ASSERT("initial_count invalid (neither 0 nor 1)",
|
LWIP_ASSERT("initial_count invalid (neither 0 nor 1)",
|
||||||
(count == 0) || (count == 1));
|
(count == 0) || (count == 1));
|
||||||
|
|
||||||
*sem = xSemaphoreCreateBinary();
|
QueueHandle_t res = xSemaphoreCreateBinaryStatic(sem);
|
||||||
if (*sem == NULL) {
|
if ((sys_sem_t *)res != sem) {
|
||||||
LWIP_DEBUGF(SYS_DEBUG, ("sys_sem_new: out of mem\r\n"));
|
LWIP_DEBUGF(SYS_DEBUG, ("sys_sem_new: out of mem\r\n"));
|
||||||
return ERR_MEM;
|
return ERR_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count == 1) {
|
if (count == 1) {
|
||||||
BaseType_t ret = xSemaphoreGive(*sem);
|
BaseType_t ret = xSemaphoreGive(sem);
|
||||||
LWIP_ASSERT("sys_sem_new: initial give failed", ret == pdTRUE);
|
LWIP_ASSERT("sys_sem_new: initial give failed", ret == pdTRUE);
|
||||||
(void)ret;
|
(void)ret;
|
||||||
}
|
}
|
||||||
@@ -131,7 +136,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)
|
||||||
{
|
{
|
||||||
BaseType_t ret = xSemaphoreGive(*sem);
|
BaseType_t ret = xSemaphoreGive(sem);
|
||||||
/* queue full is OK, this is a signal only... */
|
/* queue full is OK, this is a signal only... */
|
||||||
LWIP_ASSERT("sys_sem_signal: sane return value",
|
LWIP_ASSERT("sys_sem_signal: sane return value",
|
||||||
(ret == pdTRUE) || (ret == errQUEUE_FULL));
|
(ret == pdTRUE) || (ret == errQUEUE_FULL));
|
||||||
@@ -144,7 +149,7 @@ int
|
|||||||
sys_sem_signal_isr(sys_sem_t *sem)
|
sys_sem_signal_isr(sys_sem_t *sem)
|
||||||
{
|
{
|
||||||
BaseType_t woken = pdFALSE;
|
BaseType_t woken = pdFALSE;
|
||||||
xSemaphoreGiveFromISR(*sem, &woken);
|
xSemaphoreGiveFromISR(sem, &woken);
|
||||||
return woken == pdTRUE;
|
return woken == pdTRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +167,7 @@ sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
|
|||||||
|
|
||||||
if (!timeout) {
|
if (!timeout) {
|
||||||
/* wait infinite */
|
/* wait infinite */
|
||||||
ret = xSemaphoreTake(*sem, portMAX_DELAY);
|
ret = xSemaphoreTake((QueueHandle_t)sem, portMAX_DELAY);
|
||||||
LWIP_ASSERT("taking semaphore failed", ret == pdTRUE);
|
LWIP_ASSERT("taking semaphore failed", ret == pdTRUE);
|
||||||
} else {
|
} else {
|
||||||
/* Round up the number of ticks.
|
/* Round up the number of ticks.
|
||||||
@@ -172,7 +177,7 @@ sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
|
|||||||
* 1 tick before triggering a timeout. Thus, we need to pass 2 ticks as a timeout
|
* 1 tick before triggering a timeout. Thus, we need to pass 2 ticks as a timeout
|
||||||
* to `xSemaphoreTake`. */
|
* to `xSemaphoreTake`. */
|
||||||
TickType_t timeout_ticks = ((timeout + portTICK_PERIOD_MS - 1) / portTICK_PERIOD_MS) + 1;
|
TickType_t timeout_ticks = ((timeout + portTICK_PERIOD_MS - 1) / portTICK_PERIOD_MS) + 1;
|
||||||
ret = xSemaphoreTake(*sem, timeout_ticks);
|
ret = xSemaphoreTake((QueueHandle_t)sem, timeout_ticks);
|
||||||
if (ret == errQUEUE_EMPTY) {
|
if (ret == errQUEUE_EMPTY) {
|
||||||
/* timed out */
|
/* timed out */
|
||||||
return SYS_ARCH_TIMEOUT;
|
return SYS_ARCH_TIMEOUT;
|
||||||
@@ -191,35 +196,39 @@ sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
|
|||||||
void
|
void
|
||||||
sys_sem_free(sys_sem_t *sem)
|
sys_sem_free(sys_sem_t *sem)
|
||||||
{
|
{
|
||||||
vSemaphoreDelete(*sem);
|
vSemaphoreDelete((QueueHandle_t)sem);
|
||||||
*sem = NULL;
|
memset(sem, 0, sizeof(*sem));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create an empty mailbox.
|
* @brief Create an empty mailbox using static allocation
|
||||||
*
|
*
|
||||||
* @param mbox pointer of the mailbox
|
* Uses FreeRTOS static queue allocation to prevent heap fragmentation.
|
||||||
* @param size size of the mailbox
|
* Allocates memory for the mailbox structure plus the queue storage buffer.
|
||||||
|
* The buffer[] flexible array member points to the queue storage area.
|
||||||
|
*
|
||||||
|
* @param mbox pointer to the mailbox pointer (will be allocated)
|
||||||
|
* @param size size of the mailbox (number of messages)
|
||||||
* @return ERR_OK on success, ERR_MEM when out of memory
|
* @return ERR_OK on success, ERR_MEM when out of memory
|
||||||
*/
|
*/
|
||||||
err_t
|
err_t
|
||||||
sys_mbox_new(sys_mbox_t *mbox, int size)
|
sys_mbox_new(sys_mbox_t *mbox, int size)
|
||||||
{
|
{
|
||||||
*mbox = mem_malloc(sizeof(struct sys_mbox_s));
|
*mbox = (sys_mbox_t)heap_caps_malloc(sizeof(struct sys_mbox_s) + (size * sizeof(void *)), ( MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT ));
|
||||||
if (*mbox == NULL){
|
if (*mbox == NULL){
|
||||||
LWIP_DEBUGF(SYS_DEBUG, ("fail to new *mbox\n"));
|
LWIP_DEBUGF(SYS_DEBUG, ("fail to new *mbox\n"));
|
||||||
return ERR_MEM;
|
return ERR_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*mbox)->os_mbox = xQueueCreate(size, sizeof(void *));
|
QueueHandle_t res = xQueueCreateStatic(size, sizeof(void *), (*mbox)->buffer, &(*mbox)->os_mbox);
|
||||||
|
|
||||||
if ((*mbox)->os_mbox == NULL) {
|
if ((QueueHandle_t)&(*mbox)->os_mbox != res) {
|
||||||
LWIP_DEBUGF(SYS_DEBUG, ("fail to new (*mbox)->os_mbox\n"));
|
LWIP_DEBUGF(SYS_DEBUG, ("fail to new (*mbox)->os_mbox\n"));
|
||||||
mem_free(*mbox);
|
heap_caps_free(*mbox);
|
||||||
return ERR_MEM;
|
return ERR_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
LWIP_DEBUGF(SYS_DEBUG, ("new *mbox ok mbox=%p os_mbox=%p\n", *mbox, (*mbox)->os_mbox));
|
LWIP_DEBUGF(SYS_DEBUG, ("new *mbox ok mbox=%p os_mbox=%p\n", *mbox, (QueueHandle_t)&(*mbox)->os_mbox));
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,7 +241,7 @@ sys_mbox_new(sys_mbox_t *mbox, int size)
|
|||||||
void
|
void
|
||||||
sys_mbox_post(sys_mbox_t *mbox, void *msg)
|
sys_mbox_post(sys_mbox_t *mbox, void *msg)
|
||||||
{
|
{
|
||||||
BaseType_t ret = xQueueSendToBack((*mbox)->os_mbox, &msg, portMAX_DELAY);
|
BaseType_t ret = xQueueSendToBack((QueueHandle_t)&(*mbox)->os_mbox, &msg, portMAX_DELAY);
|
||||||
LWIP_ASSERT("mbox post failed", ret == pdTRUE);
|
LWIP_ASSERT("mbox post failed", ret == pdTRUE);
|
||||||
(void)ret;
|
(void)ret;
|
||||||
}
|
}
|
||||||
@@ -249,10 +258,10 @@ sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
|
|||||||
{
|
{
|
||||||
err_t xReturn;
|
err_t xReturn;
|
||||||
|
|
||||||
if (xQueueSend((*mbox)->os_mbox, &msg, 0) == pdTRUE) {
|
if (xQueueSend((QueueHandle_t)&(*mbox)->os_mbox, &msg, 0) == pdTRUE) {
|
||||||
xReturn = ERR_OK;
|
xReturn = ERR_OK;
|
||||||
} else {
|
} else {
|
||||||
LWIP_DEBUGF(SYS_DEBUG, ("trypost mbox=%p fail\n", (*mbox)->os_mbox));
|
LWIP_DEBUGF(SYS_DEBUG, ("trypost mbox=%p fail\n", (QueueHandle_t)&(*mbox)->os_mbox));
|
||||||
xReturn = ERR_MEM;
|
xReturn = ERR_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,7 +283,7 @@ sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg)
|
|||||||
BaseType_t ret;
|
BaseType_t ret;
|
||||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
|
||||||
ret = xQueueSendFromISR((*mbox)->os_mbox, &msg, &xHigherPriorityTaskWoken);
|
ret = xQueueSendFromISR((QueueHandle_t)&(*mbox)->os_mbox, &msg, &xHigherPriorityTaskWoken);
|
||||||
if (ret == pdTRUE) {
|
if (ret == pdTRUE) {
|
||||||
if (xHigherPriorityTaskWoken == pdTRUE) {
|
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||||
return ERR_NEED_SCHED;
|
return ERR_NEED_SCHED;
|
||||||
@@ -306,11 +315,11 @@ sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
|
|||||||
|
|
||||||
if (timeout == 0) {
|
if (timeout == 0) {
|
||||||
/* wait infinite */
|
/* wait infinite */
|
||||||
ret = xQueueReceive((*mbox)->os_mbox, &(*msg), portMAX_DELAY);
|
ret = xQueueReceive((QueueHandle_t)&(*mbox)->os_mbox, &(*msg), portMAX_DELAY);
|
||||||
LWIP_ASSERT("mbox fetch failed", ret == pdTRUE);
|
LWIP_ASSERT("mbox fetch failed", ret == pdTRUE);
|
||||||
} else {
|
} else {
|
||||||
TickType_t timeout_ticks = timeout / portTICK_PERIOD_MS;
|
TickType_t timeout_ticks = timeout / portTICK_PERIOD_MS;
|
||||||
ret = xQueueReceive((*mbox)->os_mbox, &(*msg), timeout_ticks);
|
ret = xQueueReceive((QueueHandle_t)&(*mbox)->os_mbox, &(*msg), timeout_ticks);
|
||||||
if (ret == errQUEUE_EMPTY) {
|
if (ret == errQUEUE_EMPTY) {
|
||||||
/* timed out */
|
/* timed out */
|
||||||
*msg = NULL;
|
*msg = NULL;
|
||||||
@@ -338,7 +347,7 @@ sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
|
|||||||
if (msg == NULL) {
|
if (msg == NULL) {
|
||||||
msg = &msg_dummy;
|
msg = &msg_dummy;
|
||||||
}
|
}
|
||||||
ret = xQueueReceive((*mbox)->os_mbox, &(*msg), 0);
|
ret = xQueueReceive((QueueHandle_t)&(*mbox)->os_mbox, &(*msg), 0);
|
||||||
if (ret == errQUEUE_EMPTY) {
|
if (ret == errQUEUE_EMPTY) {
|
||||||
*msg = NULL;
|
*msg = NULL;
|
||||||
return SYS_MBOX_EMPTY;
|
return SYS_MBOX_EMPTY;
|
||||||
@@ -359,11 +368,11 @@ sys_mbox_free(sys_mbox_t *mbox)
|
|||||||
if ((NULL == mbox) || (NULL == *mbox)) {
|
if ((NULL == mbox) || (NULL == *mbox)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
UBaseType_t msgs_waiting = uxQueueMessagesWaiting((*mbox)->os_mbox);
|
UBaseType_t msgs_waiting = uxQueueMessagesWaiting((QueueHandle_t)&(*mbox)->os_mbox);
|
||||||
LWIP_ASSERT("mbox quence not empty", msgs_waiting == 0);
|
LWIP_ASSERT("mbox quence not empty", msgs_waiting == 0);
|
||||||
|
|
||||||
vQueueDelete((*mbox)->os_mbox);
|
vQueueDelete((QueueHandle_t)&(*mbox)->os_mbox);
|
||||||
mem_free(*mbox);
|
heap_caps_free(*mbox);
|
||||||
*mbox = NULL;
|
*mbox = NULL;
|
||||||
|
|
||||||
(void)msgs_waiting;
|
(void)msgs_waiting;
|
||||||
@@ -490,31 +499,42 @@ sys_thread_sem_free(void* data) // destructor for TLS semaphore
|
|||||||
{
|
{
|
||||||
sys_sem_t *sem = (sys_sem_t*)(data);
|
sys_sem_t *sem = (sys_sem_t*)(data);
|
||||||
|
|
||||||
if (sem && *sem){
|
if (sem){
|
||||||
LWIP_DEBUGF(SYS_DEBUG, ("sem del, sem=%p\n", *sem));
|
LWIP_DEBUGF(SYS_DEBUG, ("sem del, sem=%p\n", sem));
|
||||||
vSemaphoreDelete(*sem);
|
vSemaphoreDelete((QueueHandle_t)sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sem) {
|
if (sem) {
|
||||||
LWIP_DEBUGF(SYS_DEBUG, ("sem pointer del, sem_p=%p\n", sem));
|
LWIP_DEBUGF(SYS_DEBUG, ("sem pointer del, sem_p=%p\n", sem));
|
||||||
mem_free(sem);
|
heap_caps_free(sem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize thread-local semaphore using static allocation
|
||||||
|
*
|
||||||
|
* Creates a thread-local semaphore using static allocation to prevent heap fragmentation.
|
||||||
|
* Uses heap_caps_malloc with internal memory capabilities for better performance.
|
||||||
|
*
|
||||||
|
* @return pointer to the allocated semaphore structure, or NULL on failure
|
||||||
|
*/
|
||||||
sys_sem_t*
|
sys_sem_t*
|
||||||
sys_thread_sem_init(void)
|
sys_thread_sem_init(void)
|
||||||
{
|
{
|
||||||
sys_sem_t *sem = (sys_sem_t*)mem_malloc(sizeof(sys_sem_t*));
|
// Always allocate semaphores from internal memory
|
||||||
|
sys_sem_t *sem = (sys_sem_t*)heap_caps_malloc(sizeof(StaticSemaphore_t), ( MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT ));
|
||||||
|
|
||||||
if (!sem){
|
if (!sem){
|
||||||
ESP_LOGE(TAG, "thread_sem_init: out of memory");
|
ESP_LOGE(TAG, "thread_sem_init: out of memory");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*sem = xSemaphoreCreateBinary();
|
// If successful, create a binary semaphore the pointer to the semaphore is returned
|
||||||
if (!(*sem)){
|
QueueHandle_t res = xSemaphoreCreateBinaryStatic(sem);
|
||||||
mem_free(sem);
|
|
||||||
ESP_LOGE(TAG, "thread_sem_init: out of memory");
|
if (res != (QueueHandle_t)sem){
|
||||||
|
heap_caps_free(sem);
|
||||||
|
ESP_LOGE(TAG, "thread_sem_init: unable to create semaphore %p != %p", res, sem);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user