Skip to content
This repository was archived by the owner on Dec 20, 2023. It is now read-only.

Commit 723d27c

Browse files
committed
Fixes to the device layer/nRF implementation
* Correctly dispatch at compile time on the NRF_SDH_DISPATCH_MODEL rather than on the enum that defines the model. This change enables the softdevice to actually use the right queue posting primitives. * When NRF_DEBUG is enabled, softdevice will dispatch log statements from interrupt context. In order to support this, if appropriate, log timestamping needs to be available; in turn, this implies that TicksSinceBoot must be callable from interrupt context. Since FreeRTOS does not provide generalized facility to determine whether a function is in an interrupt context, we make the symbol weak here, and leave it to more specific adaptations to provide a more robust implementation. * With softdevice executing code in the interrupt context, pbuf_alloc in LwIP must also be callable from the interrupt context. Following a survey of usage of SYS_ARCH_{PROTECT|UNPROTECT} in LwIP code, it is appropriate to use the task{ENTER|EXIT}_CRITICAL_FROM_ISR variants of the critical sections.
1 parent 22d3f74 commit 723d27c

File tree

4 files changed

+49
-11
lines changed

4 files changed

+49
-11
lines changed

src/adaptations/device-layer/FreeRTOS/SystemTimeSupport.cpp

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,24 +40,64 @@ constexpr uint32_t kTicksOverflowShift = (configUSE_16_BIT_TICKS) ? 16 : 32;
4040

4141
uint64_t sBootTimeUS = 0;
4242

43-
uint64_t TicksSinceBoot(void)
43+
#ifdef __CORTEX_M
44+
BaseType_t sNumOfOverflows;
45+
#endif
46+
} // unnamed namespace
47+
48+
/**
49+
* Returns the number of FreeRTOS ticks since the system booted.
50+
*
51+
* NOTE: The default implementation of this function uses FreeRTOS's
52+
* vTaskSetTimeOutState() function to get the total number of ticks,
53+
* irrespective of tick counter overflows. Unfortunately, this function cannot
54+
* be called in interrupt context, no equivalent ISR function exists, and
55+
* FreeRTOS provides no portable way of determining whether a function is being
56+
* called in an interrupt context. Adaptations that need to use the Weave
57+
* Get/SetClock methods from within an interrupt handler must override this
58+
* function with a suitable alternative that works on the target platform. The
59+
* provided version is safe to call on ARM Cortex platforms with CMSIS
60+
* libraries.
61+
*/
62+
63+
uint64_t FreeRTOSTicksSinceBoot(void) __attribute__((weak));
64+
65+
uint64_t FreeRTOSTicksSinceBoot(void)
4466
{
4567
TimeOut_t timeOut;
68+
69+
#ifdef __CORTEX_M
70+
if (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) // running in an interrupt context
71+
{
72+
// Note that sNumOverflows may be quite stale, and under those
73+
// circumstances, the function may violate monotonicity guarantees
74+
timeout.xTimeOnEntering = xTaskGetTickCountFromISR();
75+
timeout.xOverflowCount = sNumOfOverflows;
76+
}
77+
else
78+
{
79+
#endif
80+
4681
vTaskSetTimeOutState(&timeOut);
82+
83+
#ifdef __CORTEX_M
84+
// BaseType_t is supposed to be atomic
85+
sNumOfOverflows = timeOut.xOverflowCount;
86+
}
87+
#endif
88+
4789
return static_cast<uint64_t>(timeOut.xTimeOnEntering) +
4890
(static_cast<uint64_t>(timeOut.xOverflowCount) << kTicksOverflowShift);
4991
}
5092

51-
} // unnamed namespace
52-
5393
uint64_t GetClock_Monotonic(void)
5494
{
55-
return (TicksSinceBoot() * kMicrosecondsPerSecond) / configTICK_RATE_HZ;
95+
return (FreeRTOSTicksSinceBoot() * kMicrosecondsPerSecond) / configTICK_RATE_HZ;
5696
}
5797

5898
uint64_t GetClock_MonotonicMS(void)
5999
{
60-
return (TicksSinceBoot() * kMillisecondPerSecond) / configTICK_RATE_HZ;
100+
return (FreeRTOSTicksSinceBoot() * kMillisecondPerSecond) / configTICK_RATE_HZ;
61101
}
62102

63103
uint64_t GetClock_MonotonicHiRes(void)

src/adaptations/device-layer/nRF5/BLEManagerImpl.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,7 @@ void BLEManagerImpl::SoftDeviceBLEEventCallback(const ble_evt_t * bleEvent, void
802802
}
803803

804804
// Post the event to the Weave queue.
805-
#if NRF_SDH_DISPATCH_MODEL_INTERRUPT
805+
#if (NRF_SDH_DISPATCH_MODEL == NRF_SDH_DISPATCH_MODEL_INTERRUPT)
806806
BaseType_t yieldRequired;
807807
PlatformMgrImpl().PostEventFromISR(&event, yieldRequired);
808808
portYIELD_FROM_ISR(yieldRequired);
@@ -1050,4 +1050,3 @@ bool BLEManagerImpl::IsSubscribed(uint16_t conId)
10501050
} // namespace nl
10511051

10521052
#endif // WEAVE_DEVICE_CONFIG_ENABLE_WOBLE
1053-

src/lwip/freertos/arch/sys_arch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ typedef QueueHandle_t sys_mbox_t;
3333
typedef xSemaphoreHandle sys_mutex_t;
3434
typedef xSemaphoreHandle sys_sem_t;
3535
typedef TaskHandle_t sys_thread_t;
36-
typedef int sys_prot_t;
36+
typedef UBaseType_t sys_prot_t;
3737

3838
#include "arch/sys_arch.h"
3939
#include "lwip/opt.h"

src/lwip/freertos/sys_arch.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,12 +274,11 @@ u32_t sys_now(void)
274274

275275
sys_prot_t sys_arch_protect(void)
276276
{
277-
taskENTER_CRITICAL();
278-
return 1;
277+
return taskENTER_CRITICAL_FROM_ISR();
279278
}
280279

281280
void sys_arch_unprotect(sys_prot_t pval)
282281
{
283-
taskEXIT_CRITICAL();
282+
taskEXIT_CRITICAL_FROM_ISR(pval);
284283
}
285284

0 commit comments

Comments
 (0)