Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of nRF51822 by
Revision 502:276f86ae2b68, committed 2015-12-02
- Comitter:
- rgrover1
- Date:
- Wed Dec 02 10:32:52 2015 +0000
- Parent:
- 501:21dae189f6c5
- Child:
- 503:34fd6280c8ab
- Commit message:
- Synchronized with git rev a5a46f2f
Author: Rohit Grover
Release 2.0.7
=============
* Fix a bug in the assembly sequence that starts the Nordic bootloader. With
GCC, a MOV instruction was getting converted into an ADDS, which came with
an unwanted side-effect of updating the XPSR. We relocated the offending MOV
instruction such that it would not affect a conditional branch statement.
This would show only with GCC, and when jumping to the bootloader while in
handler mode.
* Fix hardfaults generated from the handling of Radio Notification events.
Radio notification events are interrupts generated at very high priority.
They have the potential to pre-empt other interrupt handling, causing race
conditions when interrupted handlers were involved in calling into BLE_API.
Radio-notification events should defer their callback handling to low-
priority handlers through the use of Tickers or Timeouts.
* Introduce watchdog header file from Nordic SDK 8.1.
* Update license headers to reflect the latest licenses from Nordic.
Changed in this revision
| source/nRF5xGap.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/source/nRF5xGap.h Wed Dec 02 10:32:52 2015 +0000
+++ b/source/nRF5xGap.h Wed Dec 02 10:32:52 2015 +0000
@@ -113,84 +113,64 @@
#endif
private:
+#ifdef YOTTA_CFG_MBED_OS
+ /*
+ * In mbed OS, all user-facing BLE events (interrupts) are posted to the
+ * MINAR scheduler to be executed as callbacks in thread mode. MINAR guards
+ * its critical sections from interrupts by acquiring CriticalSectionLock,
+ * which results in a call to sd_nvic_critical_region_enter(). Thus, it is
+ * safe to invoke MINAR APIs from interrupt context as long as those
+ * interrupts are blocked by sd_nvic_critical_region_enter().
+ *
+ * Radio notifications are a special case for the above. The Radio
+ * Notification IRQ is handled at a very high priority--higher than the
+ * level blocked by sd_nvic_critical_region_enter(). Thus Radio Notification
+ * events can preempt MINAR's critical sections. Using MINAR APIs (such as
+ * posting an event) directly in processRadioNotification() may result in a
+ * race condition ending in a hard-fault.
+ *
+ * The solution is to *not* call MINAR APIs directly from the Radio
+ * Notification handling; i.e. to do the bulk of RadioNotification
+ * processing at a reduced priority which respects MINAR's critical
+ * sections. Unfortunately, on a cortex-M0, there is no clean way to demote
+ * priority for the currently executing interrupt--we wouldn't want to
+ * demote the radio notification handling anyway because it is sensitive to
+ * timing, and the system expects to finish this handling very quickly. The
+ * workaround is to employ a Timeout to trigger
+ * postRadioNotificationCallback() after a very short delay (~0 us) and post
+ * the MINAR callback that context.
+ *
+ * !!!WARNING!!! Radio notifications are very time critical events. The
+ * current solution is expected to work under the assumption that
+ * postRadioNotificationCalback() will be executed BEFORE the next radio
+ * notification event is generated.
+ */
+
bool radioNotificationCallbackParam; /* parameter to be passed into the Timeout-generated radio notification callback. */
Timeout radioNotificationTimeout;
/*
- * A helper function to post radio notification callbacks with low interrupt priority.
+ * A helper function to post radio notification callbacks through MINAR when using mbed OS.
*/
void postRadioNotificationCallback(void) {
-#ifdef YOTTA_CFG_MBED_OS
- /*
- * In mbed OS, all user-facing BLE events (interrupts) are posted to the
- * MINAR scheduler to be executed as callbacks in thread mode. MINAR guards
- * its critical sections from interrupts by acquiring CriticalSectionLock,
- * which results in a call to sd_nvic_critical_region_enter(). Thus, it is
- * safe to invoke MINAR APIs from interrupt context as long as those
- * interrupts are blocked by sd_nvic_critical_region_enter().
- *
- * Radio notifications are a special case for the above. The Radio
- * Notification IRQ is handled at a very high priority--higher than the
- * level blocked by sd_nvic_critical_region_enter(). Thus Radio Notification
- * events can preempt MINAR's critical sections. Using MINAR APIs (such as
- * posting an event) directly in processRadioNotification() may result in a
- * race condition ending in a hard-fault.
- *
- * The solution is to *not* call MINAR APIs directly from the Radio
- * Notification handling; i.e. to do the bulk of RadioNotification
- * processing at a reduced priority which respects MINAR's critical
- * sections. Unfortunately, on a cortex-M0, there is no clean way to demote
- * priority for the currently executing interrupt--we wouldn't want to
- * demote the radio notification handling anyway because it is sensitive to
- * timing, and the system expects to finish this handling very quickly. The
- * workaround is to employ a Timeout to trigger
- * postRadioNotificationCallback() after a very short delay (~0 us) and post
- * the MINAR callback that context.
- *
- * !!!WARNING!!! Radio notifications are very time critical events. The
- * current solution is expected to work under the assumption that
- * postRadioNotificationCalback() will be executed BEFORE the next radio
- * notification event is generated.
- */
minar::Scheduler::postCallback(
mbed::util::FunctionPointer1<void, bool>(&radioNotificationCallback, &FunctionPointerWithContext<bool>::call).bind(radioNotificationCallbackParam)
);
-#else
- /*
- * In mbed classic, all user-facing BLE events execute callbacks in interrupt
- * mode. Radio Notifications are a special case because its IRQ is handled at
- * a very high priority. Thus Radio Notification events can preempt other
- * operations that require interaction with the SoftDevice such as advertising
- * payload updates and changing the Gap state. Therefore, executing a Radio
- * Notification callback directly from processRadioNotification() may result
- * in a race condition ending in a hard-fault.
- *
- * The solution is to *not* execute the Radio Notification callback directly
- * from the Radio Notification handling; i.e. to do the bulk of the
- * Radio Notification processing at a reduced priority. Unfortunately, on a
- * cortex-M0, there is no clean way to demote priority for the currently
- * executing interrupt--we wouldn't want to demote the radio notification
- * handling anyway because it is sensitive to timing, and the system expects
- * to finish this handling very quickly. The workaround is to employ a Timeout
- * to trigger postRadioNotificationCallback() after a very short delay (~0 us)
- * and execute the callback in that context.
- *
- * !!!WARNING!!! Radio notifications are very time critical events. The
- * current solution is expected to work under the assumption that
- * postRadioNotificationCalback() will be executed BEFORE the next radio
- * notification event is generated.
- */
- radioNotificationCallback.call(radioNotificationCallbackParam);
+ }
#endif /* #ifdef YOTTA_CFG_MBED_OS */
- }
/**
* A helper function to process radio-notification events; to be called internally.
* @param param [description]
*/
void processRadioNotificationEvent(bool param) {
+#ifdef YOTTA_CFG_MBED_OS
+ /* When using mbed OS the callback to the user-defined function will be posted through minar */
radioNotificationCallbackParam = param;
radioNotificationTimeout.attach_us(this, &nRF5xGap::postRadioNotificationCallback, 0);
+#else
+ radioNotificationCallback.call(param);
+#endif
}
friend void radioNotificationStaticCallback(bool param); /* allow invocations of processRadioNotificationEvent() */
