Skip to content

Commit 5aa2fb1

Browse files
committed
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.
1 parent 7d2ad92 commit 5aa2fb1

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ config NIMBLE_CPP_DEBUG_ASSERT_ENABLED
7676
Enabling this option will add debug asserts to the NimBLE CPP library.
7777
This will use approximately 1kB of flash memory.
7878

79+
config NIMBLE_CPP_FREERTOS_TASK_BLOCK_BIT
80+
int "FreeRTOS task block bit"
81+
default 31
82+
help
83+
Configure the bit to set in the task notification value when a task is blocked waiting for an event.
84+
This should be set to a bit that is not used by other notifications in the system.
85+
7986
#
8087
# BT config
8188
#

src/NimBLEUtils.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
# include <stdlib.h>
2828
# include <climits>
2929

30+
# if defined INC_FREERTOS_H
31+
constexpr uint32_t TASK_BLOCK_BIT = (1 << CONFIG_NIMBLE_CPP_FREERTOS_TASK_BLOCK_BIT);
32+
# endif
33+
3034
static const char* LOG_TAG = "NimBLEUtils";
3135

3236
/**
@@ -44,12 +48,14 @@ bool NimBLEUtils::taskWait(const NimBLETaskData& taskData, uint32_t timeout) {
4448
}
4549

4650
# if defined INC_FREERTOS_H
51+
uint32_t notificationValue;
52+
xTaskNotifyWait(0, TASK_BLOCK_BIT, &notificationValue, 0);
53+
if (notificationValue & TASK_BLOCK_BIT) {
54+
return true;
55+
}
56+
4757
taskData.m_pHandle = xTaskGetCurrentTaskHandle();
48-
# ifdef ulTaskNotifyValueClear
49-
// Clear the task notification value to ensure we block
50-
ulTaskNotifyValueClear(static_cast<TaskHandle_t>(taskData.m_pHandle), ULONG_MAX);
51-
# endif
52-
return ulTaskNotifyTake(pdTRUE, ticks) == pdTRUE;
58+
return xTaskNotifyWait(0, TASK_BLOCK_BIT, nullptr, ticks) == pdTRUE;
5359

5460
# else
5561
ble_npl_sem sem;
@@ -73,10 +79,10 @@ bool NimBLEUtils::taskWait(const NimBLETaskData& taskData, uint32_t timeout) {
7379
* @param [in] flags A return value to set in the task data structure.
7480
*/
7581
void NimBLEUtils::taskRelease(const NimBLETaskData& taskData, int flags) {
82+
taskData.m_flags = flags;
7683
if (taskData.m_pHandle != nullptr) {
77-
taskData.m_flags = flags;
7884
# if defined INC_FREERTOS_H
79-
xTaskNotifyGive(static_cast<TaskHandle_t>(taskData.m_pHandle));
85+
xTaskNotify(static_cast<TaskHandle_t>(taskData.m_pHandle), TASK_BLOCK_BIT, eSetBits);
8086
# else
8187
ble_npl_sem_release(static_cast<ble_npl_sem*>(taskData.m_pHandle));
8288
# endif

0 commit comments

Comments
 (0)