mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'bugfix/tw19728_support_static_allocation_of_freertos_queue_used_by_isr' into 'release/v3.0'
esp32/driver/bt: support static allocation of FreeRTOS queues used by ISR routine See merge request idf/esp-idf!2171
This commit is contained in:
commit
fddc905fa3
@ -17,6 +17,8 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_heap_caps_init.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
@ -113,6 +115,17 @@ static btdm_dram_available_region_t btdm_dram_available_region[] = {
|
||||
{ESP_BT_MODE_BTDM, 0x3ffbdb28, 0x3ffc0000},
|
||||
};
|
||||
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
typedef struct {
|
||||
QueueHandle_t handle;
|
||||
void *storage;
|
||||
void *buffer;
|
||||
} btdm_queue_item_t;
|
||||
#define BTDM_MAX_QUEUE_NUM (5)
|
||||
static btdm_queue_item_t btdm_queue_table[BTDM_MAX_QUEUE_NUM];
|
||||
SemaphoreHandle_t btdm_queue_table_mux = NULL;
|
||||
#endif /* #if CONFIG_SPIRAM_USE_MALLOC */
|
||||
|
||||
struct osi_funcs_t {
|
||||
xt_handler (*_set_isr)(int n, xt_handler f, void *arg);
|
||||
void (*_ints_on)(unsigned int mask);
|
||||
@ -157,6 +170,52 @@ static portMUX_TYPE global_int_mux = portMUX_INITIALIZER_UNLOCKED;
|
||||
static esp_pm_lock_handle_t s_pm_lock;
|
||||
#endif
|
||||
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
bool IRAM_ATTR btdm_queue_generic_register(const btdm_queue_item_t *queue)
|
||||
{
|
||||
if (!btdm_queue_table_mux || !queue) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool ret = false;
|
||||
btdm_queue_item_t *item;
|
||||
xSemaphoreTake(btdm_queue_table_mux, portMAX_DELAY);
|
||||
for (int i = 0; i < BTDM_MAX_QUEUE_NUM; ++i) {
|
||||
item = &btdm_queue_table[i];
|
||||
if (item->handle == NULL) {
|
||||
memcpy(item, queue, sizeof(btdm_queue_item_t));
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(btdm_queue_table_mux);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool IRAM_ATTR btdm_queue_generic_deregister(btdm_queue_item_t *queue)
|
||||
{
|
||||
if (!btdm_queue_table_mux || !queue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ret = false;
|
||||
btdm_queue_item_t *item;
|
||||
xSemaphoreTake(btdm_queue_table_mux, portMAX_DELAY);
|
||||
for (int i = 0; i < BTDM_MAX_QUEUE_NUM; ++i) {
|
||||
item = &btdm_queue_table[i];
|
||||
if (item->handle == queue->handle) {
|
||||
memcpy(queue, item, sizeof(btdm_queue_item_t));
|
||||
memset(item, 0, sizeof(btdm_queue_item_t));
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(btdm_queue_table_mux);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SPIRAM_USE_MALLOC */
|
||||
|
||||
static void IRAM_ATTR interrupt_disable(void)
|
||||
{
|
||||
portENTER_CRITICAL(&global_int_mux);
|
||||
@ -174,12 +233,63 @@ static void IRAM_ATTR task_yield_from_isr(void)
|
||||
|
||||
static void *IRAM_ATTR semphr_create_wrapper(uint32_t max, uint32_t init)
|
||||
{
|
||||
#if !CONFIG_SPIRAM_USE_MALLOC
|
||||
return (void *)xSemaphoreCreateCounting(max, init);
|
||||
#else
|
||||
StaticQueue_t *queue_buffer = NULL;
|
||||
QueueHandle_t handle = NULL;
|
||||
|
||||
queue_buffer = heap_caps_malloc(sizeof(StaticQueue_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
if (!queue_buffer) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
handle = xSemaphoreCreateCountingStatic(max, init, queue_buffer);
|
||||
if (!handle) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
btdm_queue_item_t item = {
|
||||
.handle = handle,
|
||||
.storage = NULL,
|
||||
.buffer = queue_buffer,
|
||||
};
|
||||
|
||||
if (!btdm_queue_generic_register(&item)) {
|
||||
goto error;
|
||||
}
|
||||
return handle;
|
||||
|
||||
error:
|
||||
if (handle) {
|
||||
vSemaphoreDelete(handle);
|
||||
}
|
||||
if (queue_buffer) {
|
||||
free(queue_buffer);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void IRAM_ATTR semphr_delete_wrapper(void *semphr)
|
||||
{
|
||||
#if !CONFIG_SPIRAM_USE_MALLOC
|
||||
vSemaphoreDelete(semphr);
|
||||
#else
|
||||
btdm_queue_item_t item = {
|
||||
.handle = semphr,
|
||||
.storage = NULL,
|
||||
.buffer = NULL,
|
||||
};
|
||||
|
||||
if (btdm_queue_generic_deregister(&item)) {
|
||||
vSemaphoreDelete(item.handle);
|
||||
free(item.buffer);
|
||||
}
|
||||
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int32_t IRAM_ATTR semphr_take_from_isr_wrapper(void *semphr, void *hptw)
|
||||
@ -208,12 +318,63 @@ static int32_t IRAM_ATTR semphr_give_wrapper(void *semphr)
|
||||
|
||||
static void *IRAM_ATTR mutex_create_wrapper(void)
|
||||
{
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
StaticQueue_t *queue_buffer = NULL;
|
||||
QueueHandle_t handle = NULL;
|
||||
|
||||
queue_buffer = heap_caps_malloc(sizeof(StaticQueue_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
if (!queue_buffer) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
handle = xSemaphoreCreateMutexStatic(queue_buffer);
|
||||
if (!handle) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
btdm_queue_item_t item = {
|
||||
.handle = handle,
|
||||
.storage = NULL,
|
||||
.buffer = queue_buffer,
|
||||
};
|
||||
|
||||
if (!btdm_queue_generic_register(&item)) {
|
||||
goto error;
|
||||
}
|
||||
return handle;
|
||||
|
||||
error:
|
||||
if (handle) {
|
||||
vSemaphoreDelete(handle);
|
||||
}
|
||||
if (queue_buffer) {
|
||||
free(queue_buffer);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
#else
|
||||
return (void *)xSemaphoreCreateMutex();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void IRAM_ATTR mutex_delete_wrapper(void *mutex)
|
||||
{
|
||||
#if !CONFIG_SPIRAM_USE_MALLOC
|
||||
vSemaphoreDelete(mutex);
|
||||
#else
|
||||
btdm_queue_item_t item = {
|
||||
.handle = mutex,
|
||||
.storage = NULL,
|
||||
.buffer = NULL,
|
||||
};
|
||||
|
||||
if (btdm_queue_generic_deregister(&item)) {
|
||||
vSemaphoreDelete(item.handle);
|
||||
free(item.buffer);
|
||||
}
|
||||
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int32_t IRAM_ATTR mutex_lock_wrapper(void *mutex)
|
||||
@ -228,12 +389,74 @@ static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex)
|
||||
|
||||
static void *IRAM_ATTR queue_create_wrapper(uint32_t queue_len, uint32_t item_size)
|
||||
{
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
StaticQueue_t *queue_buffer = NULL;
|
||||
uint8_t *queue_storage = NULL;
|
||||
QueueHandle_t handle = NULL;
|
||||
|
||||
queue_buffer = heap_caps_malloc(sizeof(StaticQueue_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
if (!queue_buffer) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
queue_storage = heap_caps_malloc((queue_len*item_size), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
if (!queue_storage ) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
handle = xQueueCreateStatic(queue_len, item_size, queue_storage, queue_buffer);
|
||||
if (!handle) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
btdm_queue_item_t item = {
|
||||
.handle = handle,
|
||||
.storage = queue_storage,
|
||||
.buffer = queue_buffer,
|
||||
};
|
||||
|
||||
if (!btdm_queue_generic_register(&item)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
return handle;
|
||||
|
||||
error:
|
||||
if (handle) {
|
||||
vQueueDelete(handle);
|
||||
}
|
||||
if (queue_storage) {
|
||||
free(queue_storage);
|
||||
}
|
||||
if (queue_buffer) {
|
||||
free(queue_buffer);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
#else
|
||||
return (void *)xQueueCreate(queue_len, item_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void IRAM_ATTR queue_delete_wrapper(void *queue)
|
||||
{
|
||||
#if !CONFIG_SPIRAM_USE_MALLOC
|
||||
vQueueDelete(queue);
|
||||
#else
|
||||
btdm_queue_item_t item = {
|
||||
.handle = queue,
|
||||
.storage = NULL,
|
||||
.buffer = NULL,
|
||||
};
|
||||
|
||||
if (btdm_queue_generic_deregister(&item)) {
|
||||
vQueueDelete(item.handle);
|
||||
free(item.storage);
|
||||
free(item.buffer);
|
||||
}
|
||||
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int32_t IRAM_ATTR queue_send_wrapper(void *queue, void *item, uint32_t block_time_ms)
|
||||
@ -480,6 +703,18 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
|
||||
ESP_LOGI(BTDM_LOG_TAG, "BT controller compile version [%s]\n", btdm_controller_get_compile_version());
|
||||
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
btdm_queue_table_mux = xSemaphoreCreateMutex();
|
||||
if (btdm_queue_table == NULL) {
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
esp_pm_lock_delete(s_pm_lock);
|
||||
s_pm_lock = NULL;
|
||||
#endif
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
memset(btdm_queue_table, 0, sizeof(btdm_queue_item_t) * BTDM_MAX_QUEUE_NUM);
|
||||
#endif
|
||||
|
||||
btdm_osi_funcs_register(&osi_funcs);
|
||||
|
||||
btdm_controller_mem_init();
|
||||
@ -513,6 +748,12 @@ esp_err_t esp_bt_controller_deinit(void)
|
||||
|
||||
periph_module_disable(PERIPH_BT_MODULE);
|
||||
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
vSemaphoreDelete(btdm_queue_table_mux);
|
||||
btdm_queue_table_mux = NULL;
|
||||
memset(btdm_queue_table, 0, sizeof(btdm_queue_item_t) * BTDM_MAX_QUEUE_NUM);
|
||||
#endif
|
||||
|
||||
btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
|
@ -12,6 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <esp_types.h>
|
||||
#include <string.h>
|
||||
#include "esp_intr.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
@ -40,6 +41,9 @@ typedef struct {
|
||||
ledc_fade_mode_t mode;
|
||||
xSemaphoreHandle ledc_fade_sem;
|
||||
xSemaphoreHandle ledc_fade_mux;
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
StaticQueue_t ledc_fade_sem_storage;
|
||||
#endif
|
||||
} ledc_fade_t;
|
||||
|
||||
static ledc_fade_t *s_ledc_fade_rec[LEDC_SPEED_MODE_MAX][LEDC_CHANNEL_MAX];
|
||||
@ -485,9 +489,20 @@ static esp_err_t ledc_fade_channel_deinit(ledc_mode_t speed_mode, ledc_channel_t
|
||||
static esp_err_t ledc_fade_channel_init_check(ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
if (s_ledc_fade_rec[speed_mode][channel] == NULL) {
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
s_ledc_fade_rec[speed_mode][channel] = (ledc_fade_t *) heap_caps_calloc(1, sizeof(ledc_fade_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
if (!s_ledc_fade_rec[speed_mode][channel]) {
|
||||
ledc_fade_channel_deinit(speed_mode, channel);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
memset(&s_ledc_fade_rec[speed_mode][channel]->ledc_fade_sem_storage, 0, sizeof(StaticQueue_t));
|
||||
s_ledc_fade_rec[speed_mode][channel]->ledc_fade_sem = xSemaphoreCreateBinaryStatic(&s_ledc_fade_rec[speed_mode][channel]->ledc_fade_sem_storage);
|
||||
#else
|
||||
s_ledc_fade_rec[speed_mode][channel] = (ledc_fade_t *) calloc(1, sizeof(ledc_fade_t));
|
||||
s_ledc_fade_rec[speed_mode][channel]->ledc_fade_mux = xSemaphoreCreateMutex();
|
||||
s_ledc_fade_rec[speed_mode][channel]->ledc_fade_sem = xSemaphoreCreateBinary();
|
||||
#endif
|
||||
s_ledc_fade_rec[speed_mode][channel]->ledc_fade_mux = xSemaphoreCreateMutex();
|
||||
}
|
||||
if (s_ledc_fade_rec[speed_mode][channel]
|
||||
&& s_ledc_fade_rec[speed_mode][channel]->ledc_fade_mux
|
||||
|
@ -60,6 +60,7 @@ config SPIRAM_USE_CAPS_ALLOC
|
||||
bool "Make RAM allocatable using heap_caps_malloc(..., MALLOC_CAP_SPIRAM)"
|
||||
config SPIRAM_USE_MALLOC
|
||||
bool "Make RAM allocatable using malloc() as well"
|
||||
select SUPPORT_STATIC_ALLOCATION
|
||||
endchoice
|
||||
|
||||
choice SPIRAM_TYPE
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <string.h>
|
||||
#include "esp_types.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_err.h"
|
||||
@ -82,6 +83,12 @@ static esp_timer_handle_t s_timer_in_callback;
|
||||
static TaskHandle_t s_timer_task;
|
||||
// counting semaphore used to notify the timer task from ISR
|
||||
static SemaphoreHandle_t s_timer_semaphore;
|
||||
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
// memory for s_timer_semaphore
|
||||
static StaticQueue_t s_timer_semaphore_memory;
|
||||
#endif
|
||||
|
||||
// lock protecting s_timers, s_inactive_timers, s_timer_in_callback
|
||||
static portMUX_TYPE s_timer_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
@ -329,7 +336,12 @@ esp_err_t esp_timer_init(void)
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
memset(&s_timer_semaphore_memory, 0, sizeof(StaticQueue_t));
|
||||
s_timer_semaphore = xSemaphoreCreateCountingStatic(TIMER_EVENT_QUEUE_SIZE, 0, &s_timer_semaphore_memory);
|
||||
#else
|
||||
s_timer_semaphore = xSemaphoreCreateCounting(TIMER_EVENT_QUEUE_SIZE, 0);
|
||||
#endif
|
||||
if (!s_timer_semaphore) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
@ -40,6 +40,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
QueueHandle_t handle; /**< FreeRTOS queue handler */
|
||||
void *storage; /**< storage for FreeRTOS queue */
|
||||
} wifi_static_queue_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize Wi-Fi Driver
|
||||
* Alloc resource for WiFi driver, such as WiFi control structure, RX/TX buffer,
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 52e2ab228033b65b8aa0aff1747a33c18257586c
|
||||
Subproject commit a472a0ce53aafbea650a906c699f276a6f5ed448
|
@ -12,9 +12,14 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <string.h>
|
||||
#include "esp_attr.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_wifi_internal.h"
|
||||
|
||||
/*
|
||||
If CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST is enabled. Prefer to allocate a chunk of memory in SPIRAM firstly.
|
||||
@ -54,3 +59,58 @@ IRAM_ATTR void *wifi_calloc( size_t n, size_t size )
|
||||
return calloc(n, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
wifi_static_queue_t* wifi_create_queue( int queue_len, int item_size)
|
||||
{
|
||||
wifi_static_queue_t *queue = NULL;
|
||||
|
||||
queue = (wifi_static_queue_t*)heap_caps_malloc(sizeof(wifi_static_queue_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
if (!queue) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
|
||||
queue->storage = heap_caps_calloc(1, sizeof(StaticQueue_t) + (queue_len*item_size), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||
if (!queue->storage) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
queue->handle = xQueueCreateStatic( queue_len, item_size, ((uint8_t*)(queue->storage)) + sizeof(StaticQueue_t), (StaticQueue_t*)(queue->storage));
|
||||
|
||||
if (!queue->handle) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
return queue;
|
||||
|
||||
_error:
|
||||
if (queue) {
|
||||
if (queue->storage) {
|
||||
free(queue->storage);
|
||||
}
|
||||
|
||||
free(queue);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
#else
|
||||
queue->handle = xQueueCreate( queue_len, item_size);
|
||||
return queue;
|
||||
#endif
|
||||
}
|
||||
|
||||
void wifi_delete_queue(wifi_static_queue_t *queue)
|
||||
{
|
||||
if (queue) {
|
||||
vQueueDelete(queue->handle);
|
||||
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
if (queue->storage) {
|
||||
free(queue->storage);
|
||||
}
|
||||
#endif
|
||||
|
||||
free(queue);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user