Skip to content

Commit 6361e92

Browse files
authored
Merge pull request #6798 from marcuschangarm/fix-mbr
Fix bug in MBR for NRF52 series
2 parents e43d21d + 41c1654 commit 6361e92

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)