Merge branch 'feat/ble_mesh_use_iram_for_mem_alloc_v4.0' into 'release/v4.0'

Feat/ble mesh use diff ram for mem alloc (v4.0)

See merge request espressif/esp-idf!9618
This commit is contained in:
Island 2020-07-15 16:07:00 +08:00
commit cf98746771
9 changed files with 255 additions and 133 deletions

View file

@ -18,12 +18,65 @@ if BLE_MESH
option in the Bluetooth Controller section in menuconfig, which is option in the Bluetooth Controller section in menuconfig, which is
"Scan Duplicate By Device Address and Advertising Data". "Scan Duplicate By Device Address and Advertising Data".
config BLE_MESH_ALLOC_FROM_PSRAM_FIRST choice BLE_MESH_MEM_ALLOC_MODE
bool "BLE Mesh will first allocate memory from PSRAM" prompt "Memory allocation strategy"
default BLE_MESH_MEM_ALLOC_MODE_INTERNAL
help
Allocation strategy for BLE Mesh stack, essentially provides ability to
allocate all required dynamic allocations from,
- Internal DRAM memory only
- External SPIRAM memory only
- Either internal or external memory based on default malloc()
behavior in ESP-IDF
Recommended mode here is always internal, since that is most preferred
from security perspective. But if application requirement does not allow
sufficient free internal memory then alternate mode can be selected.
config BLE_MESH_MEM_ALLOC_MODE_INTERNAL
bool "Internal DRAM"
config BLE_MESH_MEM_ALLOC_MODE_EXTERNAL
bool "External SPIRAM"
depends on ESP32_SPIRAM_SUPPORT
config BLE_MESH_MEM_ALLOC_MODE_DEFAULT
bool "Default alloc mode"
depends on ESP32_SPIRAM_SUPPORT
help
Enable this option to use the default memory allocation strategy when
external SPIRAM is enabled. See the SPIRAM options for more details.
endchoice # BLE_MESH_MEM_ALLOC_MODE
config BLE_MESH_FREERTOS_STATIC_ALLOC
bool "Enable FreeRTOS static allocation"
depends on FREERTOS_SUPPORT_STATIC_ALLOCATION && ESP32_SPIRAM_SUPPORT
default n default n
help help
When this option is enabled, BLE Mesh stack will try to allocate memory Enable this option to use FreeRTOS static allocation APIs for BLE Mesh,
from PSRAM firstly. This will save the internal RAM if PSRAM exists. which provides the ability to use different dynamic memory (i.e. SPIRAM)
for FreeRTOS objects.
If this option is disabled, the FreeRTOS static allocation APIs will not
be used, and internal DRAM will be allocated for FreeRTOS objects.
choice BLE_MESH_FREERTOS_STATIC_ALLOC_MODE
prompt "Memory allocation for FreeRTOS objects"
depends on BLE_MESH_FREERTOS_STATIC_ALLOC
help
Choose the memory to be used for FreeRTOS objects.
config BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
bool "External SPIRAM"
depends on ESP32_SPIRAM_SUPPORT
help
If enabled, BLE Mesh allocates dynamic memory from external SPIRAM for
FreeRTOS objects, i.e. mutex, queue, and task stack. External SPIRAM
can only be used for task stack when SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY
is enabled. See the SPIRAM options for more details.
endchoice # BLE_MESH_FREERTOS_STATIC_ALLOC_MODE
config BLE_MESH_FAST_PROV config BLE_MESH_FAST_PROV
bool "Enable BLE Mesh Fast Provisioning" bool "Enable BLE Mesh Fast Provisioning"

View file

@ -22,6 +22,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
#include "esp_attr.h"
#include "esp_heap_caps.h" #include "esp_heap_caps.h"
#include "mesh_byteorder.h" #include "mesh_byteorder.h"
@ -34,14 +35,11 @@
extern "C" { extern "C" {
#endif #endif
#if CONFIG_BLE_MESH_ALLOC_FROM_PSRAM_FIRST IRAM_ATTR void *bt_mesh_malloc(size_t size);
#define bt_mesh_malloc(size) heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL)
#define bt_mesh_calloc(size) heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL) IRAM_ATTR void *bt_mesh_calloc(size_t size);
#else
#define bt_mesh_malloc(size) malloc((size)) IRAM_ATTR void bt_mesh_free(void *ptr);
#define bt_mesh_calloc(size) calloc(1, (size))
#endif /* CONFIG_BLE_MESH_ALLOC_FROM_PSRAM_FIRST */
#define bt_mesh_free(p) free((p))
/** /**
* @brief This function allocates memory to store outgoing message. * @brief This function allocates memory to store outgoing message.

View file

@ -13,6 +13,7 @@
#include "freertos/queue.h" #include "freertos/queue.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "sdkconfig.h"
#include "mesh_types.h" #include "mesh_types.h"
#ifdef __cplusplus #ifdef __cplusplus
@ -36,6 +37,8 @@ extern "C" {
#endif #endif
#define BLE_MESH_ADV_TASK_STACK_SIZE 3072 #define BLE_MESH_ADV_TASK_STACK_SIZE 3072
#define BLE_MESH_ADV_TASK_NAME "mesh_adv_task"
#define BLE_MESH_ADV_TASK_PRIO (configMAX_PRIORITIES - 5)
/** /**
* @brief Put the current thread to sleep. * @brief Put the current thread to sleep.

View file

@ -25,7 +25,7 @@ extern "C" {
typedef struct { typedef struct {
SemaphoreHandle_t mutex; SemaphoreHandle_t mutex;
#if CONFIG_SPIRAM_USE_MALLOC #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
StaticQueue_t *buffer; StaticQueue_t *buffer;
#endif #endif
} bt_mesh_mutex_t; } bt_mesh_mutex_t;

View file

@ -19,6 +19,37 @@
#include "client_common.h" #include "client_common.h"
#include "mesh_common.h" #include "mesh_common.h"
IRAM_ATTR void *bt_mesh_malloc(size_t size)
{
#ifdef CONFIG_BLE_MESH_MEM_ALLOC_MODE_INTERNAL
return heap_caps_malloc(size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
#elif CONFIG_BLE_MESH_MEM_ALLOC_MODE_EXTERNAL
return heap_caps_malloc_prefer(size, 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
#elif CONFIG_BLE_MESH_MEM_ALLOC_MODE_IRAM_8BIT
return heap_caps_malloc_prefer(size, 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
#else
return malloc(size);
#endif
}
IRAM_ATTR void *bt_mesh_calloc(size_t size)
{
#ifdef CONFIG_BLE_MESH_MEM_ALLOC_MODE_INTERNAL
return heap_caps_calloc(1, size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
#elif CONFIG_BLE_MESH_MEM_ALLOC_MODE_EXTERNAL
return heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
#elif CONFIG_BLE_MESH_MEM_ALLOC_MODE_IRAM_8BIT
return heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
#else
return calloc(1, size);
#endif
}
IRAM_ATTR void bt_mesh_free(void *ptr)
{
heap_caps_free(ptr);
}
struct net_buf_simple *bt_mesh_alloc_buf(u16_t size) struct net_buf_simple *bt_mesh_alloc_buf(u16_t size)
{ {
struct net_buf_simple *buf = NULL; struct net_buf_simple *buf = NULL;

View file

@ -26,15 +26,19 @@ void bt_mesh_mutex_create(bt_mesh_mutex_t *mutex)
return; return;
} }
#if CONFIG_SPIRAM_USE_MALLOC #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
mutex->buffer = heap_caps_calloc(1, sizeof(StaticQueue_t), MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM); #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
__ASSERT(mutex->buffer, "%s, Failed to create queue buffer", __func__); mutex->buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
mutex->mutex = xSemaphoreCreateMutexStatic(mutex->buffer); #elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
__ASSERT(mutex->mutex, "%s, Failed to create static mutex", __func__); mutex->buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
#else
mutex->mutex = xSemaphoreCreateMutex();
__ASSERT(mutex->mutex, "%s, Failed to create mutex", __func__);
#endif #endif
__ASSERT(mutex->buffer, "Failed to create mutex buffer");
mutex->mutex = xSemaphoreCreateMutexStatic(mutex->buffer);
__ASSERT(mutex->mutex, "Failed to create static mutex");
#else /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
mutex->mutex = xSemaphoreCreateMutex();
__ASSERT(mutex->mutex, "Failed to create mutex");
#endif /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
} }
void bt_mesh_mutex_free(bt_mesh_mutex_t *mutex) void bt_mesh_mutex_free(bt_mesh_mutex_t *mutex)
@ -47,7 +51,7 @@ void bt_mesh_mutex_free(bt_mesh_mutex_t *mutex)
if (mutex->mutex) { if (mutex->mutex) {
vSemaphoreDelete(mutex->mutex); vSemaphoreDelete(mutex->mutex);
mutex->mutex = NULL; mutex->mutex = NULL;
#if CONFIG_SPIRAM_USE_MALLOC #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
heap_caps_free(mutex->buffer); heap_caps_free(mutex->buffer);
mutex->buffer = NULL; mutex->buffer = NULL;
#endif #endif

View file

@ -27,25 +27,19 @@
#include "mesh_bearer_adapt.h" #include "mesh_bearer_adapt.h"
/* Convert from ms to 0.625ms units */ /* Convert from ms to 0.625ms units */
#define ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5) #define ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5)
/* Convert from 0.625ms units to interval(ms) */ /* Convert from 0.625ms units to interval(ms) */
#define ADV_SCAN_INT(val) ((val) * 5 / 8) #define ADV_SCAN_INT(val) ((val) * 5 / 8)
/* Window and Interval are equal for continuous scanning */ /* Window and Interval are equal for continuous scanning */
#define MESH_SCAN_INTERVAL 0x20 #define MESH_SCAN_INTERVAL 0x20
#define MESH_SCAN_WINDOW 0x20 #define MESH_SCAN_WINDOW 0x20
/* Pre-5.0 controllers enforce a minimum interval of 100ms /* Pre-5.0 controllers enforce a minimum interval of 100ms
* whereas 5.0+ controllers can go down to 20ms. * whereas 5.0+ controllers can go down to 20ms.
*/ */
#define ADV_INT_DEFAULT_MS 100 #define ADV_INT_DEFAULT_MS 100
#define ADV_INT_FAST_MS 20 #define ADV_INT_FAST_MS 20
#if defined(CONFIG_BT_HOST_CRYPTO)
#define ADV_STACK_SIZE 1024
#else
#define ADV_STACK_SIZE 768
#endif
static const bt_mesh_addr_t *dev_addr; static const bt_mesh_addr_t *dev_addr;
@ -62,19 +56,19 @@ NET_BUF_POOL_DEFINE(adv_buf_pool, CONFIG_BLE_MESH_ADV_BUF_COUNT,
static struct bt_mesh_adv adv_pool[CONFIG_BLE_MESH_ADV_BUF_COUNT]; static struct bt_mesh_adv adv_pool[CONFIG_BLE_MESH_ADV_BUF_COUNT];
struct bt_mesh_queue { struct bt_mesh_queue {
QueueHandle_t queue; QueueHandle_t handle;
#if CONFIG_SPIRAM_USE_MALLOC #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
StaticQueue_t *buffer; StaticQueue_t *buffer;
u8_t *storage; u8_t *storage;
#endif #endif
}; };
static struct bt_mesh_queue xBleMeshQueue; static struct bt_mesh_queue adv_queue;
/* We reserve one queue for bt_mesh_adv_update() */ /* We reserve one queue item for bt_mesh_adv_update() */
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV #if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
#define BLE_MESH_QUEUE_SIZE (CONFIG_BLE_MESH_ADV_BUF_COUNT + CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT + 1) #define BLE_MESH_ADV_QUEUE_SIZE (CONFIG_BLE_MESH_ADV_BUF_COUNT + CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT + 1)
#else #else
#define BLE_MESH_QUEUE_SIZE (CONFIG_BLE_MESH_ADV_BUF_COUNT + 1) #define BLE_MESH_ADV_QUEUE_SIZE (CONFIG_BLE_MESH_ADV_BUF_COUNT + 1)
#endif #endif
#if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) #if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
@ -83,11 +77,11 @@ NET_BUF_POOL_DEFINE(relay_adv_buf_pool, CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT,
static struct bt_mesh_adv relay_adv_pool[CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT]; static struct bt_mesh_adv relay_adv_pool[CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT];
static struct bt_mesh_queue xBleMeshRelayQueue; static struct bt_mesh_queue relay_queue;
#define BLE_MESH_RELAY_QUEUE_SIZE CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT #define BLE_MESH_RELAY_QUEUE_SIZE CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT
static QueueSetHandle_t xBleMeshQueueSet; static QueueSetHandle_t mesh_queue_set;
#define BLE_MESH_QUEUE_SET_SIZE (BLE_MESH_QUEUE_SIZE + BLE_MESH_RELAY_QUEUE_SIZE) #define BLE_MESH_QUEUE_SET_SIZE (BLE_MESH_ADV_QUEUE_SIZE + BLE_MESH_RELAY_QUEUE_SIZE)
#define BLE_MESH_RELAY_TIME_INTERVAL K_SECONDS(6) #define BLE_MESH_RELAY_TIME_INTERVAL K_SECONDS(6)
#define BLE_MESH_MAX_TIME_INTERVAL 0xFFFFFFFF #define BLE_MESH_MAX_TIME_INTERVAL 0xFFFFFFFF
@ -121,7 +115,9 @@ static void bt_mesh_ble_adv_deinit(void);
struct bt_mesh_adv_task { struct bt_mesh_adv_task {
TaskHandle_t handle; TaskHandle_t handle;
#if CONFIG_SPIRAM_USE_MALLOC #if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \
CONFIG_SPIRAM_CACHE_WORKAROUND && \
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY)
StaticTask_t *task; StaticTask_t *task;
StackType_t *stack; StackType_t *stack;
#endif #endif
@ -258,28 +254,28 @@ static void adv_thread(void *p)
#if !defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) #if !defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \ #if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_SERVER CONFIG_BLE_MESH_GATT_PROXY_SERVER
xQueueReceive(xBleMeshQueue.queue, &msg, K_NO_WAIT); xQueueReceive(adv_queue.handle, &msg, K_NO_WAIT);
while (!(*buf)) { while (!(*buf)) {
s32_t timeout; s32_t timeout;
BT_DBG("Mesh Proxy Advertising start"); BT_DBG("Mesh Proxy Advertising start");
timeout = bt_mesh_proxy_adv_start(); timeout = bt_mesh_proxy_adv_start();
BT_DBG("Mesh Proxy Advertising up to %d ms", timeout); BT_DBG("Mesh Proxy Advertising up to %d ms", timeout);
xQueueReceive(xBleMeshQueue.queue, &msg, timeout); xQueueReceive(adv_queue.handle, &msg, timeout);
BT_DBG("Mesh Proxy Advertising stop"); BT_DBG("Mesh Proxy Advertising stop");
bt_mesh_proxy_adv_stop(); bt_mesh_proxy_adv_stop();
} }
#else #else
xQueueReceive(xBleMeshQueue.queue, &msg, portMAX_DELAY); xQueueReceive(adv_queue.handle, &msg, portMAX_DELAY);
#endif /* (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_SERVER */ #endif /* (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_SERVER */
#else /* !defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */ #else /* !defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \ #if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_SERVER CONFIG_BLE_MESH_GATT_PROXY_SERVER
handle = xQueueSelectFromSet(xBleMeshQueueSet, K_NO_WAIT); handle = xQueueSelectFromSet(mesh_queue_set, K_NO_WAIT);
if (handle) { if (handle) {
if (uxQueueMessagesWaiting(xBleMeshQueue.queue)) { if (uxQueueMessagesWaiting(adv_queue.handle)) {
xQueueReceive(xBleMeshQueue.queue, &msg, K_NO_WAIT); xQueueReceive(adv_queue.handle, &msg, K_NO_WAIT);
} else if (uxQueueMessagesWaiting(xBleMeshRelayQueue.queue)) { } else if (uxQueueMessagesWaiting(relay_queue.handle)) {
xQueueReceive(xBleMeshRelayQueue.queue, &msg, K_NO_WAIT); xQueueReceive(relay_queue.handle, &msg, K_NO_WAIT);
} }
} else { } else {
while (!(*buf)) { while (!(*buf)) {
@ -287,25 +283,25 @@ static void adv_thread(void *p)
BT_DBG("Mesh Proxy Advertising start"); BT_DBG("Mesh Proxy Advertising start");
timeout = bt_mesh_proxy_adv_start(); timeout = bt_mesh_proxy_adv_start();
BT_DBG("Mesh Proxy Advertising up to %d ms", timeout); BT_DBG("Mesh Proxy Advertising up to %d ms", timeout);
handle = xQueueSelectFromSet(xBleMeshQueueSet, timeout); handle = xQueueSelectFromSet(mesh_queue_set, timeout);
BT_DBG("Mesh Proxy Advertising stop"); BT_DBG("Mesh Proxy Advertising stop");
bt_mesh_proxy_adv_stop(); bt_mesh_proxy_adv_stop();
if (handle) { if (handle) {
if (uxQueueMessagesWaiting(xBleMeshQueue.queue)) { if (uxQueueMessagesWaiting(adv_queue.handle)) {
xQueueReceive(xBleMeshQueue.queue, &msg, K_NO_WAIT); xQueueReceive(adv_queue.handle, &msg, K_NO_WAIT);
} else if (uxQueueMessagesWaiting(xBleMeshRelayQueue.queue)) { } else if (uxQueueMessagesWaiting(relay_queue.handle)) {
xQueueReceive(xBleMeshRelayQueue.queue, &msg, K_NO_WAIT); xQueueReceive(relay_queue.handle, &msg, K_NO_WAIT);
} }
} }
} }
} }
#else #else
handle = xQueueSelectFromSet(xBleMeshQueueSet, portMAX_DELAY); handle = xQueueSelectFromSet(mesh_queue_set, portMAX_DELAY);
if (handle) { if (handle) {
if (uxQueueMessagesWaiting(xBleMeshQueue.queue)) { if (uxQueueMessagesWaiting(adv_queue.handle)) {
xQueueReceive(xBleMeshQueue.queue, &msg, K_NO_WAIT); xQueueReceive(adv_queue.handle, &msg, K_NO_WAIT);
} else if (uxQueueMessagesWaiting(xBleMeshRelayQueue.queue)) { } else if (uxQueueMessagesWaiting(relay_queue.handle)) {
xQueueReceive(xBleMeshRelayQueue.queue, &msg, K_NO_WAIT); xQueueReceive(relay_queue.handle, &msg, K_NO_WAIT);
} }
} }
#endif /* (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_SERVER */ #endif /* (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_SERVER */
@ -446,18 +442,18 @@ static void bt_mesh_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front)
{ {
BT_DBG("%s", __func__); BT_DBG("%s", __func__);
if (xBleMeshQueue.queue == NULL) { if (adv_queue.handle == NULL) {
BT_ERR("%s, Invalid queue", __func__); BT_ERR("%s, Invalid queue", __func__);
return; return;
} }
if (front) { if (front) {
if (xQueueSendToFront(xBleMeshQueue.queue, msg, timeout) != pdTRUE) { if (xQueueSendToFront(adv_queue.handle, msg, timeout) != pdTRUE) {
BT_ERR("%s, Failed to send item to queue front", __func__); BT_ERR("%s, Failed to send item to queue front", __func__);
bt_mesh_unref_buf(msg); bt_mesh_unref_buf(msg);
} }
} else { } else {
if (xQueueSend(xBleMeshQueue.queue, msg, timeout) != pdTRUE) { if (xQueueSend(adv_queue.handle, msg, timeout) != pdTRUE) {
BT_ERR("%s, Failed to send item to queue back", __func__); BT_ERR("%s, Failed to send item to queue back", __func__);
bt_mesh_unref_buf(msg); bt_mesh_unref_buf(msg);
} }
@ -530,12 +526,12 @@ static void ble_mesh_relay_task_post(bt_mesh_msg_t *msg, uint32_t timeout)
BT_DBG("%s", __func__); BT_DBG("%s", __func__);
if (xBleMeshRelayQueue.queue == NULL) { if (relay_queue.handle == NULL) {
BT_ERR("%s, Invalid relay queue", __func__); BT_ERR("%s, Invalid relay queue", __func__);
return; return;
} }
if (xQueueSend(xBleMeshRelayQueue.queue, msg, timeout) == pdTRUE) { if (xQueueSend(relay_queue.handle, msg, timeout) == pdTRUE) {
return; return;
} }
@ -543,11 +539,11 @@ static void ble_mesh_relay_task_post(bt_mesh_msg_t *msg, uint32_t timeout)
* If failed to send packet to the relay queue(queue is full), we will * If failed to send packet to the relay queue(queue is full), we will
* remove the oldest packet in the queue and put the new one into it. * remove the oldest packet in the queue and put the new one into it.
*/ */
handle = xQueueSelectFromSet(xBleMeshQueueSet, K_NO_WAIT); handle = xQueueSelectFromSet(mesh_queue_set, K_NO_WAIT);
if (handle && uxQueueMessagesWaiting(xBleMeshRelayQueue.queue)) { if (handle && uxQueueMessagesWaiting(relay_queue.handle)) {
BT_INFO("%s, Full queue, remove the oldest relay packet", __func__); BT_INFO("%s, Full queue, remove the oldest relay packet", __func__);
/* Remove the oldest relay packet from queue */ /* Remove the oldest relay packet from queue */
if (xQueueReceive(xBleMeshRelayQueue.queue, &old_msg, K_NO_WAIT) != pdTRUE) { if (xQueueReceive(relay_queue.handle, &old_msg, K_NO_WAIT) != pdTRUE) {
BT_ERR("%s, Failed to remove item from queue", __func__); BT_ERR("%s, Failed to remove item from queue", __func__);
bt_mesh_unref_buf(msg); bt_mesh_unref_buf(msg);
return; return;
@ -555,7 +551,7 @@ static void ble_mesh_relay_task_post(bt_mesh_msg_t *msg, uint32_t timeout)
/* Unref buf used for the oldest relay packet */ /* Unref buf used for the oldest relay packet */
bt_mesh_unref_buf(&old_msg); bt_mesh_unref_buf(&old_msg);
/* Send the latest relay packet to queue */ /* Send the latest relay packet to queue */
if (xQueueSend(xBleMeshRelayQueue.queue, msg, K_NO_WAIT) != pdTRUE) { if (xQueueSend(relay_queue.handle, msg, K_NO_WAIT) != pdTRUE) {
BT_ERR("%s, Failed to send item to relay queue", __func__); BT_ERR("%s, Failed to send item to relay queue", __func__);
bt_mesh_unref_buf(msg); bt_mesh_unref_buf(msg);
return; return;
@ -584,13 +580,13 @@ void bt_mesh_relay_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *c
msg.src = src; msg.src = src;
msg.dst = dst; msg.dst = dst;
msg.timestamp = k_uptime_get_32(); msg.timestamp = k_uptime_get_32();
/* Use K_NO_WAIT here, if xBleMeshRelayQueue is full return immediately */ /* Use K_NO_WAIT here, if relay_queue is full return immediately */
ble_mesh_relay_task_post(&msg, K_NO_WAIT); ble_mesh_relay_task_post(&msg, K_NO_WAIT);
} }
u16_t bt_mesh_get_stored_relay_count(void) u16_t bt_mesh_get_stored_relay_count(void)
{ {
return (u16_t)uxQueueMessagesWaiting(xBleMeshRelayQueue.queue); return (u16_t)uxQueueMessagesWaiting(relay_queue.handle);
} }
#endif /* #if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */ #endif /* #if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */
@ -795,65 +791,81 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, s8_t rssi,
void bt_mesh_adv_init(void) void bt_mesh_adv_init(void)
{ {
#if !CONFIG_SPIRAM_USE_MALLOC #if !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
xBleMeshQueue.queue = xQueueCreate(BLE_MESH_QUEUE_SIZE, sizeof(bt_mesh_msg_t)); adv_queue.handle = xQueueCreate(BLE_MESH_ADV_QUEUE_SIZE, sizeof(bt_mesh_msg_t));
__ASSERT(xBleMeshQueue.queue, "%s, Failed to create queue", __func__); __ASSERT(adv_queue.handle, "Failed to create queue");
#else #else /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
xBleMeshQueue.buffer = heap_caps_calloc(1, sizeof(StaticQueue_t), MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM); #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
__ASSERT(xBleMeshQueue.buffer, "%s, Failed to create queue buffer", __func__); adv_queue.buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
xBleMeshQueue.storage = heap_caps_calloc(1, (BLE_MESH_QUEUE_SIZE * sizeof(bt_mesh_msg_t)), MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM); #elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
__ASSERT(xBleMeshQueue.storage, "%s, Failed to create queue storage", __func__); adv_queue.buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
xBleMeshQueue.queue = xQueueCreateStatic(BLE_MESH_QUEUE_SIZE, sizeof(bt_mesh_msg_t), (uint8_t*)xBleMeshQueue.storage, xBleMeshQueue.buffer);
__ASSERT(xBleMeshQueue.queue, "%s, Failed to create static queue", __func__);
#endif #endif
__ASSERT(adv_queue.buffer, "Failed to create queue buffer");
#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
adv_queue.storage = heap_caps_calloc_prefer(1, (BLE_MESH_ADV_QUEUE_SIZE * sizeof(bt_mesh_msg_t)), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
#elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
adv_queue.storage = heap_caps_calloc_prefer(1, (BLE_MESH_ADV_QUEUE_SIZE * sizeof(bt_mesh_msg_t)), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
#endif
__ASSERT(adv_queue.storage, "Failed to create queue storage");
adv_queue.handle = xQueueCreateStatic(BLE_MESH_ADV_QUEUE_SIZE, sizeof(bt_mesh_msg_t), (uint8_t*)adv_queue.storage, adv_queue.buffer);
__ASSERT(adv_queue.handle, "Failed to create static queue");
#endif /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
#if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) #if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
#if !CONFIG_SPIRAM_USE_MALLOC #if !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
xBleMeshRelayQueue.queue = xQueueCreate(BLE_MESH_RELAY_QUEUE_SIZE, sizeof(bt_mesh_msg_t)); relay_queue.handle = xQueueCreate(BLE_MESH_RELAY_QUEUE_SIZE, sizeof(bt_mesh_msg_t));
__ASSERT(xBleMeshRelayQueue.queue, "%s, Failed to create relay queue", __func__); __ASSERT(relay_queue.handle, "Failed to create relay queue");
#else #else /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
xBleMeshRelayQueue.buffer = heap_caps_calloc(1, sizeof(StaticQueue_t), MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM); #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
__ASSERT(xBleMeshRelayQueue.buffer, "%s, Failed to create relay queue buffer", __func__); relay_queue.buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
xBleMeshRelayQueue.storage = heap_caps_calloc(1, (BLE_MESH_RELAY_QUEUE_SIZE * sizeof(bt_mesh_msg_t)), MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM); #elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
__ASSERT(xBleMeshRelayQueue.storage, "%s, Failed to create relay queue storage", __func__); relay_queue.buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
xBleMeshRelayQueue.queue = xQueueCreateStatic(BLE_MESH_RELAY_QUEUE_SIZE, sizeof(bt_mesh_msg_t), (uint8_t*)xBleMeshRelayQueue.storage, xBleMeshRelayQueue.buffer);
__ASSERT(xBleMeshRelayQueue.queue, "%s, Failed to create static relay queue", __func__);
#endif #endif
__ASSERT(relay_queue.buffer, "Failed to create relay queue buffer");
#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
relay_queue.storage = heap_caps_calloc_prefer(1, (BLE_MESH_RELAY_QUEUE_SIZE * sizeof(bt_mesh_msg_t)), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
#elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
relay_queue.storage = heap_caps_calloc_prefer(1, (BLE_MESH_RELAY_QUEUE_SIZE * sizeof(bt_mesh_msg_t)), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
#endif
__ASSERT(relay_queue.storage, "Failed to create relay queue storage");
relay_queue.handle = xQueueCreateStatic(BLE_MESH_RELAY_QUEUE_SIZE, sizeof(bt_mesh_msg_t), (uint8_t*)relay_queue.storage, relay_queue.buffer);
__ASSERT(relay_queue.handle, "Failed to create static relay queue");
#endif /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
xBleMeshQueueSet = xQueueCreateSet(BLE_MESH_QUEUE_SET_SIZE); mesh_queue_set = xQueueCreateSet(BLE_MESH_QUEUE_SET_SIZE);
__ASSERT(xBleMeshQueueSet, "%s, Failed to create queue set", __func__); __ASSERT(mesh_queue_set, "Failed to create queue set");
xQueueAddToSet(xBleMeshQueue.queue, xBleMeshQueueSet); xQueueAddToSet(adv_queue.handle, mesh_queue_set);
xQueueAddToSet(xBleMeshRelayQueue.queue, xBleMeshQueueSet); xQueueAddToSet(relay_queue.handle, mesh_queue_set);
#endif /* defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */ #endif /* defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */
#if !CONFIG_SPIRAM_USE_MALLOC #if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \
int ret = xTaskCreatePinnedToCore(adv_thread, "BLE_Mesh_ADV_Task", BLE_MESH_ADV_TASK_STACK_SIZE, NULL, CONFIG_SPIRAM_CACHE_WORKAROUND && \
configMAX_PRIORITIES - 5, &adv_task.handle, BLE_MESH_ADV_TASK_CORE); CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY)
__ASSERT(ret == pdTRUE, "%s, Failed to create adv thread", __func__);
#else
adv_task.task = heap_caps_calloc(1, sizeof(StaticTask_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); adv_task.task = heap_caps_calloc(1, sizeof(StaticTask_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
__ASSERT(adv_task.task, "%s, Failed to create adv thread task", __func__); __ASSERT(adv_task.task, "Failed to create adv thread task");
#if CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY adv_task.stack = heap_caps_calloc_prefer(1, BLE_MESH_ADV_TASK_STACK_SIZE * sizeof(StackType_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
adv_task.stack = heap_caps_calloc(1, BLE_MESH_ADV_TASK_STACK_SIZE * sizeof(StackType_t), MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM); __ASSERT(adv_task.stack, "Failed to create adv thread stack");
#else adv_task.handle = xTaskCreateStaticPinnedToCore(adv_thread, BLE_MESH_ADV_TASK_NAME, BLE_MESH_ADV_TASK_STACK_SIZE, NULL,
adv_task.stack = heap_caps_calloc(1, BLE_MESH_ADV_TASK_STACK_SIZE * sizeof(StackType_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); BLE_MESH_ADV_TASK_PRIO, adv_task.stack, adv_task.task, BLE_MESH_ADV_TASK_CORE);
#endif __ASSERT(adv_task.handle, "Failed to create static adv thread");
__ASSERT(adv_task.stack, "%s, Failed to create adv thread stack", __func__); #else /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && CONFIG_SPIRAM_CACHE_WORKAROUND && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY */
adv_task.handle = xTaskCreateStaticPinnedToCore(adv_thread, "BLE_Mesh_ADV_Task", BLE_MESH_ADV_TASK_STACK_SIZE, NULL, int ret = xTaskCreatePinnedToCore(adv_thread, BLE_MESH_ADV_TASK_NAME, BLE_MESH_ADV_TASK_STACK_SIZE, NULL,
configMAX_PRIORITIES - 5, adv_task.stack, adv_task.task, BLE_MESH_ADV_TASK_CORE); BLE_MESH_ADV_TASK_PRIO, &adv_task.handle, BLE_MESH_ADV_TASK_CORE);
__ASSERT(adv_task.handle, "%s, Failed to create static adv thread", __func__); __ASSERT(ret == pdTRUE, "Failed to create adv thread");
#endif #endif /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && CONFIG_SPIRAM_CACHE_WORKAROUND && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY */
} }
void bt_mesh_adv_deinit(void) void bt_mesh_adv_deinit(void)
{ {
if (xBleMeshQueue.queue == NULL) { if (adv_queue.handle == NULL) {
return; return;
} }
vTaskDelete(adv_task.handle); vTaskDelete(adv_task.handle);
adv_task.handle = NULL; adv_task.handle = NULL;
#if CONFIG_SPIRAM_USE_MALLOC #if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \
CONFIG_SPIRAM_CACHE_WORKAROUND && \
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY)
heap_caps_free(adv_task.stack); heap_caps_free(adv_task.stack);
adv_task.stack = NULL; adv_task.stack = NULL;
heap_caps_free(adv_task.task); heap_caps_free(adv_task.task);
@ -861,32 +873,32 @@ void bt_mesh_adv_deinit(void)
#endif #endif
#if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) #if defined(CONFIG_BLE_MESH_RELAY_ADV_BUF)
xQueueRemoveFromSet(xBleMeshQueue.queue, xBleMeshQueueSet); xQueueRemoveFromSet(adv_queue.handle, mesh_queue_set);
xQueueRemoveFromSet(xBleMeshRelayQueue.queue, xBleMeshQueueSet); xQueueRemoveFromSet(relay_queue.handle, mesh_queue_set);
vQueueDelete(xBleMeshRelayQueue.queue); vQueueDelete(relay_queue.handle);
xBleMeshRelayQueue.queue = NULL; relay_queue.handle = NULL;
#if CONFIG_SPIRAM_USE_MALLOC #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
heap_caps_free(xBleMeshRelayQueue.buffer); heap_caps_free(relay_queue.buffer);
xBleMeshRelayQueue.buffer = NULL; relay_queue.buffer = NULL;
heap_caps_free(xBleMeshRelayQueue.storage); heap_caps_free(relay_queue.storage);
xBleMeshRelayQueue.storage = NULL; relay_queue.storage = NULL;
#endif #endif
bt_mesh_unref_buf_from_pool(&relay_adv_buf_pool); bt_mesh_unref_buf_from_pool(&relay_adv_buf_pool);
memset(relay_adv_pool, 0, sizeof(relay_adv_pool)); memset(relay_adv_pool, 0, sizeof(relay_adv_pool));
vQueueDelete(xBleMeshQueueSet); vQueueDelete(mesh_queue_set);
xBleMeshQueueSet = NULL; mesh_queue_set = NULL;
#endif /* defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */ #endif /* defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) */
vQueueDelete(xBleMeshQueue.queue); vQueueDelete(adv_queue.handle);
xBleMeshQueue.queue = NULL; adv_queue.handle = NULL;
#if CONFIG_SPIRAM_USE_MALLOC #if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
heap_caps_free(xBleMeshQueue.buffer); heap_caps_free(adv_queue.buffer);
xBleMeshQueue.buffer = NULL; adv_queue.buffer = NULL;
heap_caps_free(xBleMeshQueue.storage); heap_caps_free(adv_queue.storage);
xBleMeshQueue.storage = NULL; adv_queue.storage = NULL;
#endif #endif
bt_mesh_unref_buf_from_pool(&adv_buf_pool); bt_mesh_unref_buf_from_pool(&adv_buf_pool);

View file

@ -225,6 +225,7 @@ CONFIG_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY CONFIG_BT_BLE_ACT_SC
CONFIG_BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT CONFIG_BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT
CONFIG_BLE_MESH_GATT_PROXY CONFIG_BLE_MESH_GATT_PROXY_SERVER CONFIG_BLE_MESH_GATT_PROXY CONFIG_BLE_MESH_GATT_PROXY_SERVER
CONFIG_BLE_MESH_ALLOC_FROM_PSRAM_FIRST CONFIG_BLE_MESH_MEM_ALLOC_MODE_EXTERNAL
CONFIG_NIMBLE_ENABLED CONFIG_BT_NIMBLE_ENABLED CONFIG_NIMBLE_ENABLED CONFIG_BT_NIMBLE_ENABLED
CONFIG_NIMBLE_MEM_ALLOC_MODE CONFIG_BT_NIMBLE_MEM_ALLOC_MODE CONFIG_NIMBLE_MEM_ALLOC_MODE CONFIG_BT_NIMBLE_MEM_ALLOC_MODE

View file

@ -0,0 +1,20 @@
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BTDM_MODEM_SLEEP=n
CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE=y
CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN=y
CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y
CONFIG_BT_BTU_TASK_STACK_SIZE=4512
CONFIG_BLE_MESH=y
CONFIG_BLE_MESH_FAST_PROV=y
CONFIG_BLE_MESH_PB_GATT=y
CONFIG_BLE_MESH_CFG_CLI=y
CONFIG_ESP32_SPIRAM_SUPPORT=y
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y
CONFIG_BLE_MESH_MEM_ALLOC_MODE_EXTERNAL=y
CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC=y
CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL=y