working on a bootloader for the STM32H750IB, and have questions, esp about SCB->VTOR
Hi, I'm working on a bootloader for a board using the STM32H750IB (the Electro-Smith Daisy Seed), and have a few questions about what all needs to be done before jumping to the main image.
The main image (a flat '.bin' file) is stored in a QSPI flash chip, which is copied to the main SRAM at 0x24000000.
In looking at various other ARM Cortex M7 bootloaders, it seems like most of them are NOT setting the SCB->VTOR register. But from what I otherwise read, it should be set. But then I was also seeing some mentions that it should be copied to address 0x0, and/or that there may be an offset.
Here's the current code, it seems to work by just setting the SCB->VTOR to the base SRAM address, but is this correct?
Also, I saw conflicting info on whether interrupts should be disabled or must not be disabled.
And what about the Watchdog timer? I don't think it's being used.
And anything else that needs to be done? It _seems_ to be working, but are there any potential intermittent issues?
Thanks for any feedback!
int main(void)
{
hw.Init();
DbgInit();
uint8_t *app_run_image_ptr=&_app_run_address;
DebugOut("app address = 0x%08X\r\n", app_run_image_ptr);
uint32_t tot_len=480*1024;
uint32_t block_count=tot_len/BLOCK_SIZE;
for (uint32_t bb=0; bb < block_count; bb++)
{
uint32_t index=bb*BLOCK_SIZE;
uint8_t* qspi_data_addr = (uint8_t *)hw.qspi.GetData(0x40000+index);
// We need to explicitly invalidate the QSPI mapped memory to ensure we are
// reading the correct data
dsy_dma_invalidate_cache_for_buffer((uint8_t *)qspi_data_addr, BLOCK_SIZE);
void *app_ram_dest_addr=app_run_image_ptr + index;
memcpy(app_ram_dest_addr, qspi_data_addr, BLOCK_SIZE);
}
uint32_t JumpAddress = *(__IO uint32_t*) (app_run_image_ptr+4);
uint32_t app_stack_ptr=*(__IO uint32_t*) (app_run_image_ptr+0);
hw.DeInit(); // apparently doesn't de-init the qspi.
hw.qspi.DeInit();
// jump to application code
/* Disable all interrupts */
/// __disable_irq();
RCC->CIER = 0x00000000;
/* Disable and reset SysTick */
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
/* Clear Interrupt Enable Register & Interrupt Pending Register */
for (int i = 0;i < 8; i++) {
NVIC->ICER[i]=0xFFFFFFFF;
NVIC->ICPR[i]=0xFFFFFFFF;
}
SCB->VTOR = (uint32_t)(app_run_image_ptr); ///????
//?? // Enable IWDG if firmware has option bit set
//?? //if ((header->options >> OPT_IWDG_OFFSET) & OPT_IWDG_MASK)
//?? MX_IWDG1_Init();
//???? HAL_IWDG_Init();
pFunction jumpToApplication = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(app_stack_ptr);
/// __enable_irq();
jumpToApplication();
for(;;) {}
