config changes

Fork of nRF51822 by Nordic Semiconductor

Files at this revision

API Documentation at this revision

Comitter:
rgrover1
Date:
Thu Nov 26 14:33:45 2015 +0000
Parent:
469:aaf82f0337df
Child:
471:945e53179855
Commit message:
Synchronized with git rev f8b3f134
Author: Andres Amaya Garcia
Post radio notification callback through minar

The ble-nrf51822 implementation of the BLE API generated callbacks for radio
notification events without using the minar scheduler and at very high
priority. This functionality is replaced by posting events through minar
when YOTTA_CFG_MBED_OS is defined. Note that minar could not be used directly
to post callbacks because radio notification events are handled at very high
priority, which caused a hard-fault when minar tries to enter a critical
section. Alternatively, a Timeout was used to post the callback in another
context with lower priority.

Changed in this revision

source/nRF5xGap.h Show annotated file Show diff for this revision Revisions of this file
--- a/source/nRF5xGap.h	Thu Nov 26 14:33:45 2015 +0000
+++ b/source/nRF5xGap.h	Thu Nov 26 14:33:45 2015 +0000
@@ -109,12 +109,50 @@
 #endif
 
 private:
+#ifdef YOTTA_CFG_MBED_OS
+    /* Store the current radio notification value that will be used in the next callback */
+    bool radioNotificationCallbackParam;
+
+    /*
+     * In mbed OS, the idea is to post all callbacks through minar scheduler. However, the radio notifications
+     * are handled in IRQs with very high priority. Trying to post a minar callback directly in
+     * processRadioNotification() will result in a hard-fault. This is because minar asumes that all callbacks
+     * are posted from low priority context, so when minar schedules the callback it attempts to enter a
+     * critical section and disable all interrupts. The problem is that minar tries to do this by invoking the
+     * SoftDevice with a call to sd_nvic_critical_region_enter() while already running in high priority. This
+     * results in the SoftDevice generating a hard-fault.
+     * A solution is to reduce the priority from which the callback is posted to minar. Unfortunately, there
+     * are not clean ways to do this. The solution implemented uses a Timeout to call
+     * postRadioNotificationCallback() after a very short delay (1 us) and post the minar callback there.
+     *
+     * !!!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.
+     */
+    Timeout radioNotificationTimeout;
+
+    /*
+     * A helper function to post radio notification callbacks through minar when using mbed OS.
+     */
+    void postRadioNotificationCallback(void) {
+        minar::Scheduler::postCallback(
+            mbed::util::FunctionPointer1<void, bool>(&radioNotificationCallback, &FunctionPointerWithContext<bool>::call).bind(radioNotificationCallbackParam)
+        );
+    }
+#endif
+
     /**
      * 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() */