Refactor NimBLEUtils::taskWait to check notification value before blocking.

Instead of incrementing the notificatin value via `xTaskNotifyGive` this will now set a specific bit in the task notification value
which will be tested before blocking a task. This will prevent a task from blocking indefinitely if the event that calls `taskRelease`
occurs before entering the blocked state.

* Adds a config setting for the bit to set in the task notification value.
This commit is contained in:
h2zero 2024-11-13 13:41:02 -07:00 committed by h2zero
parent 7d2ad92ad2
commit 5aa2fb1443
2 changed files with 20 additions and 7 deletions

View file

@ -76,6 +76,13 @@ config NIMBLE_CPP_DEBUG_ASSERT_ENABLED
Enabling this option will add debug asserts to the NimBLE CPP library. Enabling this option will add debug asserts to the NimBLE CPP library.
This will use approximately 1kB of flash memory. This will use approximately 1kB of flash memory.
config NIMBLE_CPP_FREERTOS_TASK_BLOCK_BIT
int "FreeRTOS task block bit"
default 31
help
Configure the bit to set in the task notification value when a task is blocked waiting for an event.
This should be set to a bit that is not used by other notifications in the system.
# #
# BT config # BT config
# #

View file

@ -27,6 +27,10 @@
# include <stdlib.h> # include <stdlib.h>
# include <climits> # include <climits>
# if defined INC_FREERTOS_H
constexpr uint32_t TASK_BLOCK_BIT = (1 << CONFIG_NIMBLE_CPP_FREERTOS_TASK_BLOCK_BIT);
# endif
static const char* LOG_TAG = "NimBLEUtils"; static const char* LOG_TAG = "NimBLEUtils";
/** /**
@ -44,12 +48,14 @@ bool NimBLEUtils::taskWait(const NimBLETaskData& taskData, uint32_t timeout) {
} }
# if defined INC_FREERTOS_H # if defined INC_FREERTOS_H
uint32_t notificationValue;
xTaskNotifyWait(0, TASK_BLOCK_BIT, &notificationValue, 0);
if (notificationValue & TASK_BLOCK_BIT) {
return true;
}
taskData.m_pHandle = xTaskGetCurrentTaskHandle(); taskData.m_pHandle = xTaskGetCurrentTaskHandle();
# ifdef ulTaskNotifyValueClear return xTaskNotifyWait(0, TASK_BLOCK_BIT, nullptr, ticks) == pdTRUE;
// Clear the task notification value to ensure we block
ulTaskNotifyValueClear(static_cast<TaskHandle_t>(taskData.m_pHandle), ULONG_MAX);
# endif
return ulTaskNotifyTake(pdTRUE, ticks) == pdTRUE;
# else # else
ble_npl_sem sem; ble_npl_sem sem;
@ -73,10 +79,10 @@ bool NimBLEUtils::taskWait(const NimBLETaskData& taskData, uint32_t timeout) {
* @param [in] flags A return value to set in the task data structure. * @param [in] flags A return value to set in the task data structure.
*/ */
void NimBLEUtils::taskRelease(const NimBLETaskData& taskData, int flags) { void NimBLEUtils::taskRelease(const NimBLETaskData& taskData, int flags) {
if (taskData.m_pHandle != nullptr) {
taskData.m_flags = flags; taskData.m_flags = flags;
if (taskData.m_pHandle != nullptr) {
# if defined INC_FREERTOS_H # if defined INC_FREERTOS_H
xTaskNotifyGive(static_cast<TaskHandle_t>(taskData.m_pHandle)); xTaskNotify(static_cast<TaskHandle_t>(taskData.m_pHandle), TASK_BLOCK_BIT, eSetBits);
# else # else
ble_npl_sem_release(static_cast<ble_npl_sem*>(taskData.m_pHandle)); ble_npl_sem_release(static_cast<ble_npl_sem*>(taskData.m_pHandle));
# endif # endif