Fix vector table relocation for NRF52

The vector table relocation sequence depends on:

1. Whether the SoftDevice is present.
2. The Application is a bootloader or not.

If the SoftDevice is present and the application is a bootloader
the MBR must be initialized to trap SoftDevice service calls
before setting the new vector table address.

The SCB->VTOR must be set to point at the MBR as well.

If the SoftDevice is not present the SCB->VTOR can point at the
new vector table directly.
pull/6746/head
Marcus Chang 2018-04-25 14:50:31 -07:00
parent c8d72c524d
commit bb14051588
4 changed files with 641 additions and 5 deletions

View File

@ -0,0 +1,154 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
#include "nrf_dfu_mbr.h"
#include "nrf_mbr.h"
#include "nrf_dfu_types.h"
#include "nrf_log.h"
uint32_t nrf_dfu_mbr_copy_bl(uint32_t * p_src, uint32_t len)
{
uint32_t ret_val;
uint32_t const len_words = len / sizeof(uint32_t);
sd_mbr_command_t command =
{
.command = SD_MBR_COMMAND_COPY_BL,
.params.copy_bl.bl_src = p_src,
.params.copy_bl.bl_len = len_words
};
ret_val = sd_mbr_command(&command);
return ret_val;
}
uint32_t nrf_dfu_mbr_copy_sd(uint32_t * p_dst, uint32_t * p_src, uint32_t len)
{
uint32_t ret_val;
uint32_t const len_words = len / sizeof(uint32_t);
if ((len_words & (CODE_PAGE_SIZE / sizeof(uint32_t) - 1)) != 0)
return NRF_ERROR_INVALID_LENGTH;
sd_mbr_command_t command =
{
.command = SD_MBR_COMMAND_COPY_SD,
.params.copy_sd.src = p_src,
.params.copy_sd.dst = p_dst,
.params.copy_sd.len = len_words
};
ret_val = sd_mbr_command(&command);
return ret_val;
}
uint32_t nrf_dfu_mbr_init_sd(void)
{
uint32_t ret_val;
sd_mbr_command_t command =
{
.command = SD_MBR_COMMAND_INIT_SD
};
ret_val = sd_mbr_command(&command);
return ret_val;
}
uint32_t nrf_dfu_mbr_compare(uint32_t * p_ptr1, uint32_t * p_ptr2, uint32_t len)
{
uint32_t ret_val;
uint32_t const len_words = len / sizeof(uint32_t);
sd_mbr_command_t command =
{
.command = SD_MBR_COMMAND_COMPARE,
.params.compare.ptr1 = p_ptr1,
.params.compare.ptr2 = p_ptr2,
.params.compare.len = len_words
};
ret_val = sd_mbr_command(&command);
return ret_val;
}
uint32_t nrf_dfu_mbr_vector_table_set(uint32_t address)
{
uint32_t ret_val;
NRF_LOG_DEBUG("running vector table set");
sd_mbr_command_t command =
{
.command = SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET,
.params.base_set.address = address,
};
ret_val = sd_mbr_command(&command);
NRF_LOG_DEBUG("After running vector table set");
return ret_val;
}
#ifndef SOFTDEVICE_PRESENT
uint32_t nrf_dfu_mbr_irq_forward_address_set(uint32_t address)
{
uint32_t ret_val;
NRF_LOG_DEBUG("running irq table set");
sd_mbr_command_t command =
{
.command = SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET,
.params.irq_forward_address_set.address = address,
};
ret_val = sd_mbr_command(&command);
NRF_LOG_DEBUG("After running irq table set");
return ret_val;
}
#endif

View File

@ -0,0 +1,131 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
/**@file
*
* @defgroup sdk_nrf_dfu_mbr MBR functions
* @{
* @ingroup nrf_dfu
*/
#ifndef NRF_DFU_MBR_H__
#define NRF_DFU_MBR_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Function for copying the bootloader using an MBR command.
*
* @param[in] p_src Source address of the bootloader data to copy.
* @param[in] len Length of the data to copy in bytes.
*
* @return This function will return only if the command request could not be run.
* See @ref sd_mbr_command_copy_bl_t for possible return values.
*/
uint32_t nrf_dfu_mbr_copy_bl(uint32_t * p_src, uint32_t len);
/** @brief Function for copying the SoftDevice using an MBR command.
*
* @param[in] p_dst Target of the SoftDevice copy.
* @param[in] p_src Source address of the SoftDevice image to copy.
* @param[in] len Length of the data to copy in bytes.
*
* @retval NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly.
* @retval NRF_ERROR_INVALID_LENGTH Invalid len
* @retval NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF).
* @retval NRF_ERROR_INVALID_PARAM if an invalid command is given.
* @retval NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying.
*/
uint32_t nrf_dfu_mbr_copy_sd(uint32_t * p_dst, uint32_t * p_src, uint32_t len);
/** @brief Function for initializing the SoftDevice using an MBR command.
*
* @retval NRF_SUCCESS If the SoftDevice was copied successfully.
* Any other return value indicates that the SoftDevice
* could not be copied.
*/
uint32_t nrf_dfu_mbr_init_sd(void);
/** @brief Function for comparing source and target using an MBR command.
*
* @param[in] p_ptr1 First pointer to data to compare.
* @param[in] p_ptr2 Second pointer to data to compare.
* @param[in] len Length of the data to compare in bytes.
*
* @retval NRF_SUCCESS If the content of both memory blocks is equal.
* @retval NRF_ERROR_NULL If the content of the memory blocks differs.
*/
uint32_t nrf_dfu_mbr_compare(uint32_t * p_ptr1, uint32_t * p_ptr2, uint32_t len);
/** @brief Function for setting the address of the vector table using an MBR command.
*
* @param[in] address Address of the new vector table.
*
* @retval NRF_SUCCESS If the address of the new vector table was set. Any other
* return value indicates that the address could not be set.
*/
uint32_t nrf_dfu_mbr_vector_table_set(uint32_t address);
#ifndef SOFTDEVICE_PRESENT
/** @brief Function for setting the address of the irq table using an MBR command.
*
* @param[in] address Address of the new irq table.
*
* @retval NRF_SUCCESS If the address of the new irq table was set. Any other
* return value indicates that the address could not be set.
*/
uint32_t nrf_dfu_mbr_irq_forward_address_set(uint32_t address);
#endif
#ifdef __cplusplus
}
#endif
#endif // NRF_DFU_MBR_H__
/** @} */

View File

@ -0,0 +1,327 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
/**@file
*
* @defgroup sdk_nrf_dfu_types DFU types
* @{
* @ingroup nrf_dfu
*/
#ifndef NRF_DFU_TYPES_H__
#define NRF_DFU_TYPES_H__
#include <stdint.h>
#include <stddef.h>
#include "nrf.h"
#include "nrf_mbr.h"
#include "app_util_platform.h"
#ifdef SOFTDEVICE_PRESENT
#include "nrf_sdm.h"
#include "ble_gap.h"
#endif
#if defined(NRF_DFU_SVCI_ENABLED)
#include "nrf_dfu_svci.h"
#else
// Dummy type for nrf_dfu_peer_data_t if DFU SVCI is not in use
typedef struct
{
uint32_t crc;
} nrf_dfu_peer_data_t;
// Dummy type for nrf_dfu_adv_name_t if DFU SVCI is not in use
typedef struct
{
uint32_t crc;
} nrf_dfu_adv_name_t;
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if defined(SOFTDEVICE_PRESENT)
#include "nrf_sdm.h"
/** @brief Start address of the SoftDevice (excluding the area for the MBR).
*/
#define SOFTDEVICE_REGION_START MBR_SIZE
#ifndef CODE_REGION_1_START
#define CODE_REGION_1_START SD_SIZE_GET(MBR_SIZE)
#endif
#else
#ifndef CODE_REGION_1_START
#define CODE_REGION_1_START MBR_SIZE
#endif
#endif
#define INIT_COMMAND_MAX_SIZE 256 /**< Maximum size of the init command stored in dfu_settings. */
/** @brief Size of a flash codepage. This value is used for calculating the size of the reserved
* flash space in the bootloader region. It is checked against NRF_UICR->CODEPAGESIZE
* at run time to ensure that the region is correct.
*/
#if defined(NRF51)
#define CODE_PAGE_SIZE (PAGE_SIZE_IN_WORDS * sizeof(uint32_t))
#elif defined(NRF52) || defined(NRF52840_XXAA)
#define CODE_PAGE_SIZE (MBR_PAGE_SIZE_IN_WORDS * sizeof(uint32_t))
#else
#error "Architecture not set."
#endif
/** @brief Maximum size of a data object.*/
#if defined( NRF51 )
#define DATA_OBJECT_MAX_SIZE (CODE_PAGE_SIZE * 4)
#elif defined( NRF52_SERIES ) || defined ( __SDK_DOXYGEN__ )
#define DATA_OBJECT_MAX_SIZE (CODE_PAGE_SIZE)
#else
#error "Architecture not set."
#endif
/** @brief Page location of the bootloader settings address.
*/
#if defined ( NRF51 )
#define BOOTLOADER_SETTINGS_ADDRESS (0x0003FC00UL)
#elif defined( NRF52832_XXAA )
#define BOOTLOADER_SETTINGS_ADDRESS (0x0007F000UL)
#elif defined( NRF52840_XXAA )
#define BOOTLOADER_SETTINGS_ADDRESS (0x000FF000UL)
#else
#error No valid target set for BOOTLOADER_SETTINGS_ADDRESS.
#endif
#if defined(NRF52832_XXAA)
/**
* @brief MBR parameters page in UICR.
*
* Register location in UICR where the page address of the MBR parameters page is stored (only used by the nRF52 MBR).
*
* @note If the value at the given location is 0xFFFFFFFF, no MBR parameters page is set.
*/
#define NRF_UICR_MBR_PARAMS_PAGE_ADDRESS (NRF_UICR_BASE + 0x18)
/** @brief Page location of the MBR parameters page address.
*
*/
#if !defined(NRF52840_XXAA_ENGA)
#define NRF_MBR_PARAMS_PAGE_ADDRESS (0x0007E000UL)
#else
#define NRF_MBR_PARAMS_PAGE_ADDRESS (0x000FE000UL)
#endif
#endif
#if defined(NRF52840_XXAA)
/**
* @brief MBR parameters page in UICR.
*
* Register location in UICR where the page address of the MBR parameters page is stored (only used by the nRF52 MBR).
*
* @note If the value at the given location is 0xFFFFFFFF, no MBR parameters page is set.
*/
#define NRF_UICR_MBR_PARAMS_PAGE_ADDRESS (NRF_UICR_BASE + 0x18)
/** @brief Page location of the MBR parameters page address.
*
*/
#define NRF_MBR_PARAMS_PAGE_ADDRESS (0x000FE000UL)
#endif
/** @brief Size of the flash space reserved for application data.
*/
#ifndef DFU_APP_DATA_RESERVED
#define DFU_APP_DATA_RESERVED CODE_PAGE_SIZE * 3
#endif
/** @brief Total size of the region between the SoftDevice and the bootloader.
*/
#define DFU_REGION_TOTAL_SIZE ((* (uint32_t *)NRF_UICR_BOOTLOADER_START_ADDRESS) - CODE_REGION_1_START)
#ifdef SOFTDEVICE_PRESENT
/** @brief Start address of the SoftDevice (excluding the area for the MBR).
*/
#define SOFTDEVICE_REGION_START MBR_SIZE
/** @brief Size of the Code Region 0, found in the UICR.CLEN0 register.
*
* @details This value is identical to the start of Code Region 1. This value is used for
* compilation safety, because the linker will fail if the application expands
* into the bootloader. At run time, the bootloader uses the value found in UICR.CLEN0.
*/
#ifndef CODE_REGION_1_START
#define CODE_REGION_1_START SD_SIZE_GET(MBR_SIZE)
#endif
#else
#ifndef CODE_REGION_1_START
#define CODE_REGION_1_START MBR_SIZE
#endif
#endif
#define NRF_DFU_CURRENT_BANK_0 0x00
#define NRF_DFU_CURRENT_BANK_1 0x01
#define NRF_DFU_BANK_LAYOUT_DUAL 0x00
#define NRF_DFU_BANK_LAYOUT_SINGLE 0x01
/** @brief DFU bank state codes.
*
* @details The DFU bank state indicates the content of a bank:
* A valid image of a certain type or an invalid image.
*/
#define NRF_DFU_BANK_INVALID 0x00 /**< Invalid image. */
#define NRF_DFU_BANK_VALID_APP 0x01 /**< Valid application. */
#define NRF_DFU_BANK_VALID_SD 0xA5 /**< Valid SoftDevice. */
#define NRF_DFU_BANK_VALID_BL 0xAA /**< Valid bootloader. */
#define NRF_DFU_BANK_VALID_SD_BL 0xAC /**< Valid SoftDevice and bootloader. */
/** @brief Description of a single bank. */
#pragma pack(4)
typedef struct
{
uint32_t image_size; /**< Size of the image in the bank. */
uint32_t image_crc; /**< CRC of the image. If set to 0, the CRC is ignored. */
uint32_t bank_code; /**< Identifier code for the bank. */
} nrf_dfu_bank_t;
/**@brief DFU progress.
*
* Be aware of the difference between objects and firmware images. A firmware image consists of multiple objects, each of a maximum size @ref DATA_OBJECT_MAX_SIZE.
*
* @note The union inside this struct is cleared when CREATE_OBJECT of command type is executed, and when there is a valid post-validation.
* In DFU activation (after reset) the @ref sd_start_address will be used in case of a SD/SD+BL update.
*/
ANON_UNIONS_ENABLE
typedef struct
{
uint32_t command_size; /**< The size of the current init command stored in the DFU settings. */
uint32_t command_offset; /**< The offset of the currently received init command data. The offset will increase as the init command is received. */
uint32_t command_crc; /**< The calculated CRC of the init command (calculated after the transfer is completed). */
uint32_t data_object_size; /**< The size of the last object created. Note that this size is not the size of the whole firmware image.*/
union
{
struct
{
uint32_t firmware_image_crc; /**< CRC value of the current firmware (continuously calculated as data is received). */
uint32_t firmware_image_crc_last; /**< The CRC of the last executed object. */
uint32_t firmware_image_offset; /**< The offset of the current firmware image being transferred. Note that this offset is the offset in the entire firmware image and not only the current object. */
uint32_t firmware_image_offset_last;/**< The offset of the last executed object from the start of the firmware image. */
};
struct
{
uint32_t sd_start_address; /**< Value indicating the start address of the SoftDevice source. Used for an SD/SD+BL update where the SD changes size or if the DFU process had a power loss when updating a SD with changed size. */
};
};
} dfu_progress_t;
ANON_UNIONS_DISABLE
/**@brief DFU settings for application and bank data.
*/
typedef struct
{
uint32_t crc; /**< CRC for the stored DFU settings, not including the CRC itself. If 0xFFFFFFF, the CRC has never been calculated. */
uint32_t settings_version; /**< Version of the currect DFU settings struct layout. */
uint32_t app_version; /**< Version of the last stored application. */
uint32_t bootloader_version; /**< Version of the last stored bootloader. */
uint32_t bank_layout; /**< Bank layout: single bank or dual bank. This value can change. */
uint32_t bank_current; /**< The bank that is currently used. */
nrf_dfu_bank_t bank_0; /**< Bank 0. */
nrf_dfu_bank_t bank_1; /**< Bank 1. */
uint32_t write_offset; /**< Write offset for the current operation. */
uint32_t sd_size; /**< SoftDevice size (if combined BL and SD). */
dfu_progress_t progress; /**< Current DFU progress. */
uint32_t enter_buttonless_dfu;
uint8_t init_command[INIT_COMMAND_MAX_SIZE]; /**< Buffer for storing the init command. */
nrf_dfu_peer_data_t peer_data; /**< Not included in calculated CRC. */
nrf_dfu_adv_name_t adv_name; /**< Not included in calculated CRC. */
} nrf_dfu_settings_t;
#ifdef SOFTDEVICE_PRESENT
#endif // SYSTEM_SERVICE_ATT_SIZE
#pragma pack() // revert pack settings
#ifdef __cplusplus
}
#endif
#endif // NRF_DFU_TYPES_H__
/** @} */

View File

@ -42,6 +42,7 @@
#if defined(SOFTDEVICE_PRESENT)
#include "nrf_sdm.h"
#include "nrf_dfu_mbr.h"
#endif
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
@ -54,12 +55,11 @@
uint32_t nrf_dispatch_vector[NVIC_NUM_VECTORS] @ ".noinit";
#endif
typedef void (*generic_irq_handler_t)(void);
extern uint32_t __Vectors[];
#define VECTORS_FLASH_START __Vectors
#define UICR_BOOTLOADER_ADDRESS 0x10001014
#define MBR_ADDRESS 0x0
/**
* @brief Function for relocation of the vector to RAM on nRF5x devices.
@ -75,8 +75,32 @@ void nrf_reloc_vector_table(void)
}
#if defined(SOFTDEVICE_PRESENT)
sd_softdevice_vector_table_base_set((uint32_t) nrf_dispatch_vector);
/* Bootloader address is stored in UICR */
uint32_t *bootloader = (uint32_t *) UICR_BOOTLOADER_ADDRESS;
/**
* Before setting the new vector table address in the SoftDevice the MBR must be initialized.
* If no bootloader is present the MBR will be initialized automatically.
* If a bootloader is present nrf_dfu_mbr_init_sd must be called once and only once.
*
* This application is a bootloader being booted for the first time if:
* 1. The application's vector table (VECTORS_FLASH_START) is set in the UICR.
* 2. SCB->VTOR is still pointing to the MBR's vector table (MBR_ADDRESS).
*/
if ((VECTORS_FLASH_START == (uint32_t *) *bootloader) && (SCB->VTOR == MBR_ADDRESS)) {
/* Initialize MBR so SoftDevice service calls are being trapped correctly. */
nrf_dfu_mbr_init_sd();
}
/* Set SCB->VTOR to go through MBR to trap SoftDevice service calls. */
SCB->VTOR = 0x0;
/* Instruct the SoftDevice to forward interrupts to the application's vector table in RAM. */
sd_softdevice_vector_table_base_set((uint32_t) nrf_dispatch_vector);
#else
/* No SoftDevice is present. Set all interrupts to vector table in RAM. */
SCB->VTOR = (uint32_t) nrf_dispatch_vector;
#endif
}