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.
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
#

View file

@ -27,6 +27,10 @@
# include <stdlib.h>
# 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";
/**
@ -44,12 +48,14 @@ bool NimBLEUtils::taskWait(const NimBLETaskData& taskData, uint32_t timeout) {
}
# 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();
# ifdef ulTaskNotifyValueClear
// 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;
return xTaskNotifyWait(0, TASK_BLOCK_BIT, nullptr, ticks) == pdTRUE;
# else
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.
*/
void NimBLEUtils::taskRelease(const NimBLETaskData& taskData, int flags) {
if (taskData.m_pHandle != nullptr) {
taskData.m_flags = flags;
if (taskData.m_pHandle != nullptr) {
# 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
ble_npl_sem_release(static_cast<ble_npl_sem*>(taskData.m_pHandle));
# endif