No changes
Fork of nRF51822 by
Diff: source/nRF5xGap.h
- Revision:
- 470:2c1d3b1fe249
- Parent:
- 455:e33de7c4574c
- Child:
- 471:945e53179855
diff -r aaf82f0337df -r 2c1d3b1fe249 source/nRF5xGap.h --- 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() */