sa

Fork of nRF51822 by Nordic Semiconductor

Files at this revision

API Documentation at this revision

Comitter:
rgrover1
Date:
Thu Nov 26 15:02:39 2015 +0000
Parent:
478:b5b54bf15533
Child:
480:cf44bb89e3f1
Commit message:
Synchronized with git rev 167ddd63
Author: Andres Amaya Garcia
Execute radio notification in low priority context

The ble-nrf51822 implementation of the BLE API executes callbacks for radio
notification events at very high priority. This functionality is replaced by
executing the radio notification callback at a lower priority. When using
mbed OS the callback is posted through minar. In mbed classic the callback is
executed directly, but from a lower priority. Note that minar or callback
execution in mbed classic could not be posted/generated directly from the
radio notification handler because this causes race conditions that may lead
to a hard-fault. Alternatively, a Timeout was used to post the callback in
another context with lower priority.

Changed in this revision

LICENSE Show annotated file Show diff for this revision Revisions of this file
bootloader/softdevice_nrf51822_licence_agreement.txt Show annotated file Show diff for this revision Revisions of this file
module.json Show annotated file Show diff for this revision Revisions of this file
softdevice_nrf51822_licence_agreement.txt Show annotated file Show diff for this revision Revisions of this file
source/btle/btle.cpp Show annotated file Show diff for this revision Revisions of this file
source/btle/btle_security.cpp Show annotated file Show diff for this revision Revisions of this file
source/nRF5xGap.h Show annotated file Show diff for this revision Revisions of this file
source/nRF5xn.cpp Show annotated file Show diff for this revision Revisions of this file
source/nordic-sdk/components/drivers_nrf/hal/nrf_wdt.h Show annotated file Show diff for this revision Revisions of this file
source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util_arm.c Show annotated file Show diff for this revision Revisions of this file
--- a/LICENSE	Thu Nov 26 15:02:39 2015 +0000
+++ b/LICENSE	Thu Nov 26 15:02:39 2015 +0000
@@ -1,6 +1,9 @@
 Many of the files in this module have been inherited from the Nordic SDK for
-nRF51822; they come with a BSD-like license offered by Nordic for use in mbed.
-Some other files come from the mbed SDK, and are licensed under Apache-2.0.
-Unless specifically indicated otherwise in a file, files are licensed
-under the Apache 2.0 license, as can be found in: apache-2.0.txt.
-The BSD-like Nordic license can be found in BSD-3clause-Nordic.txt
\ No newline at end of file
+nRF51822. With the exception of the softdevice, they come with a BSD license
+offered by Nordic for use in mbed. The Nordic Softdevice License Agreement, a
+BSD-like licence for binary distributions, applies to the softdevice. Some
+other files come from the mbed SDK, and are licensed under Apache-2.0. Unless
+specifically indicated otherwise in a file, files are licensed under the
+Apache 2.0 license, as can be found in: apache-2.0.txt. The BSD-like Nordic
+license can be found in BSD-3clause-Nordic.txt. The Nordic Semiconductor Softdevice
+License Agreement can be found in softdevice_nrf51822_licence_agreement.txt.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bootloader/softdevice_nrf51822_licence_agreement.txt	Thu Nov 26 15:02:39 2015 +0000
@@ -0,0 +1,30 @@
+/*
+ * S110/S120/S130 License Agreement
+ *
+ * Copyright (c) 2015, Nordic Semiconductor ASA, All rights reserved.
+ *
+ * Redistribution. Redistribution and use in binary form, without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * • Redistributions must reproduce the above copyright notice and the following
+ *   disclaimer in the documentation and/or other materials provided with the
+ *   distribution.
+ * • Neither the name of the copyright holder nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ * • No reverse engineering, decompilation, or disassembly of this software is
+ *   permitted.
+ *
+ * DISCLAIMER.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * /
\ No newline at end of file
--- a/module.json	Thu Nov 26 15:02:39 2015 +0000
+++ b/module.json	Thu Nov 26 15:02:39 2015 +0000
@@ -1,6 +1,6 @@
 {
   "name": "ble-nrf51822",
-  "version": "2.0.2",
+  "version": "2.0.7",
   "description": "Nordic stack and drivers for the mbed BLE API.",
   "keywords": [
     "Bluetooth",
@@ -18,6 +18,9 @@
     {
       "url": "https://spdx.org/licenses/Apache-2.0",
       "type": "Apache-2.0"
+    },
+    {
+      "type": "LicenseRef-softdevice_nrf51822_licence_agreement.txt"
     }
   ],
   "dependencies": {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/softdevice_nrf51822_licence_agreement.txt	Thu Nov 26 15:02:39 2015 +0000
@@ -0,0 +1,30 @@
+/*
+ * S110/S120/S130 License Agreement
+ *
+ * Copyright (c) 2015, Nordic Semiconductor ASA, All rights reserved.
+ *
+ * Redistribution. Redistribution and use in binary form, without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * • Redistributions must reproduce the above copyright notice and the following
+ *   disclaimer in the documentation and/or other materials provided with the
+ *   distribution.
+ * • Neither the name of the copyright holder nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ * • No reverse engineering, decompilation, or disassembly of this software is
+ *   permitted.
+ *
+ * DISCLAIMER.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * /
\ No newline at end of file
--- a/source/btle/btle.cpp	Thu Nov 26 15:02:39 2015 +0000
+++ b/source/btle/btle.cpp	Thu Nov 26 15:02:39 2015 +0000
@@ -19,7 +19,6 @@
 
 #include "btle.h"
 
-#include "ble_stack_handler_types.h"
 #include "ble_flash.h"
 #include "ble_conn_params.h"
 
@@ -27,15 +26,17 @@
 #include "btle_advertising.h"
 #include "custom/custom_helper.h"
 
-#include "softdevice_handler.h"
-#include "pstorage.h"
-
 #include "ble/GapEvents.h"
 #include "nRF5xGap.h"
 #include "nRF5xGattServer.h"
 #include "nRF5xSecurityManager.h"
 
+extern "C" {
+#include "pstorage.h"
 #include "device_manager.h"
+#include "softdevice_handler.h"
+#include "ble_stack_handler_types.h"
+}
 
 #include "ble_hci.h"
 #include "btle_discovery.h"
--- a/source/btle/btle_security.cpp	Thu Nov 26 15:02:39 2015 +0000
+++ b/source/btle/btle_security.cpp	Thu Nov 26 15:02:39 2015 +0000
@@ -15,12 +15,15 @@
  */
 
 #include "btle.h"
-#include "pstorage.h"
 
 #include "nRF5xGap.h"
 #include "nRF5xSecurityManager.h"
 
+extern "C" {
+#include "pstorage.h"
 #include "device_manager.h"
+}
+
 #include "btle_security.h"
 
 static dm_application_instance_t applicationInstance;
--- a/source/nRF5xGap.h	Thu Nov 26 15:02:39 2015 +0000
+++ b/source/nRF5xGap.h	Thu Nov 26 15:02:39 2015 +0000
@@ -26,7 +26,11 @@
 #include "ble/GapScanningParams.h"
 
 #include "nrf_soc.h"
+
+extern "C" {
 #include "ble_radio_notification.h"
+}
+
 #include "btle_security.h"
 
 void radioNotificationStaticCallback(bool param);
@@ -109,12 +113,84 @@
 #endif
 
 private:
+    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.
+     */
+    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) {
-        radioNotificationCallback.call(param);
+        radioNotificationCallbackParam = param;
+        radioNotificationTimeout.attach_us(this, &nRF5xGap::postRadioNotificationCallback, 0);
     }
     friend void radioNotificationStaticCallback(bool param); /* allow invocations of processRadioNotificationEvent() */
 
--- a/source/nRF5xn.cpp	Thu Nov 26 15:02:39 2015 +0000
+++ b/source/nRF5xn.cpp	Thu Nov 26 15:02:39 2015 +0000
@@ -22,7 +22,9 @@
 #include "btle/btle.h"
 #include "nrf_delay.h"
 
+extern "C" {
 #include "softdevice_handler.h"
+}
 
 /**
  * The singleton which represents the nRF51822 transport for the BLE.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/nordic-sdk/components/drivers_nrf/hal/nrf_wdt.h	Thu Nov 26 15:02:39 2015 +0000
@@ -0,0 +1,299 @@
+/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+/**
+ * @defgroup nrf_wdt_hal WDT HAL
+ * @{
+ * @ingroup nrf_wdt
+ *
+ * @brief Hardware abstraction layer for accessing the watchdog timer (WDT) peripheral.
+ */
+
+#ifndef NRF_WDT_H__
+#define NRF_WDT_H__
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nrf.h"
+
+#define NRF_WDT_CHANNEL_NUMBER 0x8UL
+#define NRF_WDT_RR_VALUE       0x6E524635UL /* Fixed value, shouldn't be modified.*/
+
+#define NRF_WDT_TASK_SET       1UL
+#define NRF_WDT_EVENT_CLEAR    0UL
+
+/**
+ * @enum nrf_wdt_task_t
+ * @brief WDT tasks.
+ */
+typedef enum
+{
+    /*lint -save -e30 -esym(628,__INTADDR__)*/
+    NRF_WDT_TASK_START = offsetof(NRF_WDT_Type, TASKS_START), /**< Task for starting WDT. */
+    /*lint -restore*/
+} nrf_wdt_task_t;
+
+/**
+ * @enum nrf_wdt_event_t
+ * @brief WDT events.
+ */
+typedef enum
+{
+    /*lint -save -e30*/
+    NRF_WDT_EVENT_TIMEOUT = offsetof(NRF_WDT_Type, EVENTS_TIMEOUT), /**< Event from WDT time-out. */
+    /*lint -restore*/
+} nrf_wdt_event_t;
+
+/**
+ * @enum nrf_wdt_behaviour_t
+ * @brief WDT behavior in CPU SLEEP or HALT mode.
+ */
+typedef enum
+{
+    NRF_WDT_BEHAVIOUR_RUN_SLEEP        = WDT_CONFIG_SLEEP_Msk,                       /**< WDT will run when CPU is in SLEEP mode. */
+    NRF_WDT_BEHAVIOUR_RUN_HALT         = WDT_CONFIG_HALT_Msk,                        /**< WDT will run when CPU is in HALT mode. */
+    NRF_WDT_BEHAVIOUR_RUN_SLEEP_HALT   = WDT_CONFIG_SLEEP_Msk | WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in SLEEP or HALT mode. */
+    NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT = 0,                                          /**< WDT will be paused when CPU is in SLEEP or HALT mode. */
+} nrf_wdt_behaviour_t;
+
+/**
+ * @enum nrf_wdt_rr_register_t
+ * @brief WDT reload request registers.
+ */
+typedef enum
+{
+    NRF_WDT_RR0 = 0, /**< Reload request register 0. */
+    NRF_WDT_RR1,     /**< Reload request register 1. */
+    NRF_WDT_RR2,     /**< Reload request register 2. */
+    NRF_WDT_RR3,     /**< Reload request register 3. */
+    NRF_WDT_RR4,     /**< Reload request register 4. */
+    NRF_WDT_RR5,     /**< Reload request register 5. */
+    NRF_WDT_RR6,     /**< Reload request register 6. */
+    NRF_WDT_RR7      /**< Reload request register 7. */
+} nrf_wdt_rr_register_t;
+
+/**
+ * @enum nrf_wdt_int_mask_t
+ * @brief WDT interrupts.
+ */
+typedef enum
+{
+    NRF_WDT_INT_TIMEOUT_MASK = WDT_INTENSET_TIMEOUT_Msk, /**< WDT interrupt from time-out event. */
+} nrf_wdt_int_mask_t;
+
+/**
+ * @brief Function for configuring the watchdog behavior when the CPU is sleeping or halted.
+ *
+ * @param behaviour Watchdog behavior when CPU is in SLEEP or HALT mode.
+ */
+__STATIC_INLINE void nrf_wdt_behaviour_set(nrf_wdt_behaviour_t behaviour)
+{
+    NRF_WDT->CONFIG = behaviour;
+}
+
+
+/**
+ * @brief Function for starting the watchdog.
+ *
+ * @param[in]  task             Task.
+ */
+__STATIC_INLINE void nrf_wdt_task_trigger(nrf_wdt_task_t task)
+{
+    *((volatile uint32_t *)((uint8_t *)NRF_WDT + task)) = NRF_WDT_TASK_SET;
+}
+
+
+/**
+ * @brief Function for clearing the WDT event.
+ *
+ * @param[in]  event       Event.
+ */
+__STATIC_INLINE void nrf_wdt_event_clear(nrf_wdt_event_t event)
+{
+    *((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event)) = NRF_WDT_EVENT_CLEAR;
+}
+
+
+/**
+ * @brief Function for retrieving the state of the WDT event.
+ *
+ * @param[in]  event       Event.
+ *
+ * @retval     true              If the event is set.
+ * @retval     false             If the event is not set.
+ */
+__STATIC_INLINE bool nrf_wdt_event_check(nrf_wdt_event_t event)
+{
+    return (bool)*((volatile uint32_t *)((uint8_t *)NRF_WDT + event));
+}
+
+
+/**
+ * @brief Function for enabling a specific interrupt.
+ *
+ * @param[in]  int_mask         Interrupt.
+ */
+__STATIC_INLINE void nrf_wdt_int_enable(uint32_t int_mask)
+{
+    NRF_WDT->INTENSET = int_mask;
+}
+
+
+/**
+ * @brief Function for retrieving the state of given interrupt.
+ *
+ * @param[in]  int_mask         Interrupt.
+ *
+ * @retval     true                   Interrupt is enabled.
+ * @retval     false                  Interrupt is not enabled.
+ */
+__STATIC_INLINE bool nrf_wdt_int_enable_check(uint32_t int_mask)
+{
+    return (bool)(NRF_WDT->INTENSET & int_mask);
+}
+
+
+/**
+ * @brief Function for disabling a specific interrupt.
+ *
+ * @param[in]  int_mask         Interrupt.
+ */
+__STATIC_INLINE void nrf_wdt_int_disable(uint32_t int_mask)
+{
+    NRF_WDT->INTENCLR = int_mask;
+}
+
+
+/**
+ * @brief Function for returning the address of a specific WDT task register.
+ *
+ * @param[in]  task             Task.
+ */
+__STATIC_INLINE uint32_t nrf_wdt_task_address_get(nrf_wdt_task_t task)
+{
+    return ((uint32_t)NRF_WDT + task);
+}
+
+
+/**
+ * @brief Function for returning the address of a specific WDT event register.
+ *
+ * @param[in]  event       Event.
+ *
+ * @retval     address of requested event register
+ */
+__STATIC_INLINE uint32_t nrf_wdt_event_address_get(nrf_wdt_event_t event)
+{
+    return ((uint32_t)NRF_WDT + event);
+}
+
+
+/**
+ * @brief Function for retrieving the watchdog status.
+ *
+ * @retval     true             If the watchdog is started.
+ * @retval     false            If the watchdog is not started.
+ */
+__STATIC_INLINE bool nrf_wdt_started(void)
+{
+    return (bool)(NRF_WDT->RUNSTATUS);
+}
+
+
+/**
+ * @brief Function for retrieving the watchdog reload request status.
+ *
+ * @param[in]  rr_register      Reload request register to check.
+ *
+ * @retval     true             If a reload request is running.
+ * @retval     false            If no reload request is running.
+ */
+__STATIC_INLINE bool nrf_wdt_request_status(nrf_wdt_rr_register_t rr_register)
+{
+    return (bool)(((NRF_WDT->REQSTATUS) >> rr_register) & 0x1UL);
+}
+
+
+/**
+ * @brief Function for setting the watchdog reload value.
+ *
+ * @param[in]  reload_value     Watchdog counter initial value.
+ */
+__STATIC_INLINE void nrf_wdt_reload_value_set(uint32_t reload_value)
+{
+    NRF_WDT->CRV = reload_value;
+}
+
+
+/**
+ * @brief Function for retrieving the watchdog reload value.
+ *
+ * @retval                      Reload value.
+ */
+__STATIC_INLINE uint32_t nrf_wdt_reload_value_get(void)
+{
+    return (uint32_t)NRF_WDT->CRV;
+}
+
+
+/**
+ * @brief Function for enabling a specific reload request register.
+ *
+ * @param[in]  rr_register       Reload request register to enable.
+ */
+__STATIC_INLINE void nrf_wdt_reload_request_enable(nrf_wdt_rr_register_t rr_register)
+{
+    NRF_WDT->RREN |= 0x1UL << rr_register;
+}
+
+
+/**
+ * @brief Function for disabling a specific reload request register.
+ *
+ * @param[in]  rr_register       Reload request register to disable.
+ */
+__STATIC_INLINE void nrf_wdt_reload_request_disable(nrf_wdt_rr_register_t rr_register)
+{
+    NRF_WDT->RREN &= ~(0x1UL << rr_register);
+}
+
+
+/**
+ * @brief Function for retrieving the status of a specific reload request register.
+ *
+ * @param[in]  rr_register       Reload request register to check.
+ *
+ * @retval     true              If the reload request register is enabled.
+ * @retval     false             If the reload request register is not enabled.
+ */
+__STATIC_INLINE bool nrf_wdt_reload_request_is_enabled(nrf_wdt_rr_register_t rr_register)
+{
+    return (bool)(NRF_WDT->RREN & (0x1UL << rr_register));
+}
+
+
+/**
+ * @brief Function for setting a specific reload request register.
+ *
+ * @param[in]  rr_register       Reload request register to set.
+ */
+__STATIC_INLINE void nrf_wdt_reload_request_set(nrf_wdt_rr_register_t rr_register)
+{
+    NRF_WDT->RR[rr_register] = NRF_WDT_RR_VALUE;
+}
+
+
+#endif
+
+/** @} */
\ No newline at end of file
--- a/source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util_arm.c	Thu Nov 26 15:02:39 2015 +0000
+++ b/source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util_arm.c	Thu Nov 26 15:02:39 2015 +0000
@@ -59,10 +59,10 @@
     MSR   MSP, R5               ; Set the main stack pointer to the applications MSP.
     LDR   R6, [R0, #0x04]       ; Load Reset handler into register 6.
 
+    MOV   R0, R6
     LDR   R2, =MASK_ZEROS       ; Load zeros to R2
     MRS   R3, IPSR              ; Load IPSR to R3 to check for handler or thread mode
     CMP   R2, R3                ; Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader
-    MOV   R0, R6
     BNE   isr_abort             ; If not zero we need to exit current ISR and jump to reset handler of bootloader
 
     LDR   R4, =MASK_ONES        ; Load ones to R4 to be placed in Link Register.
@@ -98,10 +98,10 @@
         "MSR   MSP, r5        \n\t"       /* Set the main stack pointer to the applications MSP.              */
         "LDR   r6,[r0, #0x04] \n\t"       /* Load Reset handler into register 0.                              */
 
+        "MOV   R0, R6         \n\t"
         "LDR   r2, =MASK_ZEROS\n\t"       /* Load zeros to R2                                                 */
         "MRS   r3, IPSR       \n\t"       /* Load IPSR to R3 to check for handler or thread mode              */
         "CMP   r2, r3         \n\t"       /* Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader */
-        "MOV   R0, R6         \n\t"
         "BNE   isr_abort      \n\t"       /* If not zero we need to exit current ISR and jump to reset handler of bootloader */
 
         "LDR   r4, =MASK_ONES \n\t"       /* Load ones to R4 to be placed in Link Register.                   */