cpu/cortexm_common: introduce cpu_jump_to_image()

This new function allows to jump to another execution
environment (VTOR) located at a certain (aligned) address.
It's used to boot firmwares at another location than
`CPU_FLASH_BASE`.

The user needs to ensure that the CPU using this feature
is able to be initialised at least twice while jumping
to the RIOT `reset_handler_default` function, since it
initialises the CPU again (calls cpu_init()).

Co-authored-by: Kaspar Schleiser <kaspar@schleiser.de>
This commit is contained in:
Kaspar Schleiser 2017-10-05 17:13:11 +02:00
parent 281d8084bf
commit 9cfdf6e379

View File

@ -189,6 +189,44 @@ static inline void cortexm_isr_end(void)
} }
} }
/**
* @brief Jumps to another image in flash
*
* This function is supposed to be called by a bootloader application.
*
* @param[in] image_address address in flash of other image
*/
static inline void cpu_jump_to_image(uint32_t image_address)
{
/* Disable IRQ */
__disable_irq();
/* set MSP */
__set_MSP(*(uint32_t*)image_address);
/* skip stack pointer */
image_address += 4;
/* load the images reset_vector address */
uint32_t destination_address = *(uint32_t*)image_address;
/* Make sure the Thumb State bit is set. */
destination_address |= 0x1;
/* Branch execution */
__asm("BX %0" :: "r" (destination_address));
}
/* The following register is only present for Cortex-M0+, -M3, -M4 and -M7 CPUs */
#if defined(CPU_ARCH_CORTEX_M0PLUS) || defined(CPU_ARCH_CORTEX_M3) || \
defined(CPU_ARCH_CORTEX_M4) || defined(CPU_ARCH_CORTEX_M4F) || \
defined(CPU_ARCH_CORTEX_M7)
static inline uint32_t cpu_get_image_baseaddr(void)
{
return SCB->VTOR;
}
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif