Skip to content

Commit 41c1654

Browse files
author
Marcus Chang
committed
Fix bug in MBR for NRF52 series
The MBR VTOR state depends on how the application is booted. This makes it difficult to initialize the MBR correctly since a bug prevents the MBR from being initialized more than once. This commit resets the MBR and SoftDevice to a known state before initializing the MBR and setting the VTOR through the SoftDevice.
1 parent d08c819 commit 41c1654

File tree

1 file changed

+20
-14
lines changed

1 file changed

+20
-14
lines changed

targets/TARGET_NORDIC/TARGET_NRF5x/reloc_vector_table.c

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@
5858
extern uint32_t __Vectors[];
5959

6060
#define VECTORS_FLASH_START __Vectors
61-
#define UICR_BOOTLOADER_ADDRESS 0x10001014
62-
#define MBR_ADDRESS 0x0
61+
#define MBR_VTOR_ADDRESS 0x20000000
62+
#define SOFTDEVICE_VTOR_ADDRESS 0x20000004
6363

6464
/**
6565
* @brief Function for relocation of the vector to RAM on nRF5x devices.
@@ -68,36 +68,42 @@ extern uint32_t __Vectors[];
6868
void nrf_reloc_vector_table(void)
6969
{
7070
// Copy and switch to dynamic vectors
71-
uint32_t *old_vectors = (uint32_t*)VECTORS_FLASH_START;
71+
uint32_t *old_vectors = VECTORS_FLASH_START;
7272
uint32_t i;
7373
for (i = 0; i< NVIC_NUM_VECTORS; i++) {
7474
nrf_dispatch_vector[i] = old_vectors[i];
7575
}
7676

7777
#if defined(SOFTDEVICE_PRESENT)
78-
/* Bootloader address is stored in UICR */
79-
uint32_t *bootloader = (uint32_t *) UICR_BOOTLOADER_ADDRESS;
8078

8179
/**
82-
* Before setting the new vector table address in the SoftDevice the MBR must be initialized.
83-
* If no bootloader is present the MBR will be initialized automatically.
80+
* Before setting the new vector table address in the SoftDevice the MBR must be initialized.
81+
* If no bootloader is present the MBR will be initialized automatically.
8482
* If a bootloader is present nrf_dfu_mbr_init_sd must be called once and only once.
8583
*
86-
* This application is a bootloader being booted for the first time if:
87-
* 1. The application's vector table (VECTORS_FLASH_START) is set in the UICR.
88-
* 2. SCB->VTOR is still pointing to the MBR's vector table (MBR_ADDRESS).
84+
* By resetting the MBR and SoftDevice VTOR address first, it becomes safe to initialize
85+
* the MBR again regardless of how the application was started.
8986
*/
90-
if ((VECTORS_FLASH_START == (uint32_t *) *bootloader) && (SCB->VTOR == MBR_ADDRESS)) {
9187

92-
/* Initialize MBR so SoftDevice service calls are being trapped correctly. */
93-
nrf_dfu_mbr_init_sd();
94-
}
88+
/* Reset MBR VTOR to original state before calling MBR init. */
89+
uint32_t *mbr_vtor_address = (uint32_t *) MBR_VTOR_ADDRESS;
90+
*mbr_vtor_address = (uint32_t) VECTORS_FLASH_START;
91+
92+
/* Reset SoftDevive VTOR. */
93+
uint32_t *softdevice_vtor_address = (uint32_t *) SOFTDEVICE_VTOR_ADDRESS;
94+
*softdevice_vtor_address = 0xFFFFFFFF;
9595

9696
/* Set SCB->VTOR to go through MBR to trap SoftDevice service calls. */
9797
SCB->VTOR = 0x0;
9898

99+
/* Initialize MBR so SoftDevice service calls are being trapped correctly.
100+
* This call sets MBR_VTOR_ADDRESS to point to the SoftDevice's VTOR at address 0x1000.
101+
*/
102+
nrf_dfu_mbr_init_sd();
103+
99104
/* Instruct the SoftDevice to forward interrupts to the application's vector table in RAM. */
100105
sd_softdevice_vector_table_base_set((uint32_t) nrf_dispatch_vector);
106+
101107
#else
102108

103109
/* No SoftDevice is present. Set all interrupts to vector table in RAM. */

0 commit comments

Comments
 (0)