2018-02-18 10:23 AM
Hi,
I'm facing a problem with relocation of the vector table to the internal SRAM. I work with the STM32F030CCT6 (using the Ac6 System Workbench and CubeMX, with the HAL libraries 1.9.0) and I want to design a simple bootloader.
This is a part of my linker script:
/* Specify the memory areas */
MEMORY{RAM (xrw) : ORIGIN = 0x200000C0, LENGTH = 32K-0xC0VTRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0xC0FLASH (rx) : ORIGIN = 0x08000800, LENGTH = 256K-0x800}....RAMVectorTable(NOLOAD): {*(.RAMVectorTable)} >VTRAMThis is a vector table relocation in the main() of the bootloader:
__IO uint32_t VectorTable[48] __attribute__((section('.RAMVectorTable')));
/* USER CODE END 0 *//** * @brief The application entry point. * * @retval None */int main(void){ /* USER CODE BEGIN 1 */ uint32_t i = 0; for(i = 0; i < 48; i++) VectorTable[i] = *(__IO uint32_t*)((uint32_t)0x08000800 + (i<<2)); /* Enable the SYSCFG peripheral clock*/ __HAL_RCC_SYSCFG_CLK_ENABLE(); /* Remap SRAM at 0x00000000 */ __HAL_SYSCFG_REMAPMEMORY_SRAM();...Later on I send some test messages over the UART interface. I do not know why, but the above code works perfectly in the debug mode - I just need to run 'debug' and then 'resume' the program execution (with or without breakpoints later, does not matter).
Nevertheless, if I program the target (right click on the project -> 'Target' -> 'Program chip...', or just power-reset what I uploaded during the debug session), there is no response from the board. I am pretty sure that finally there is the same program on flash since I use the same .elf file both for the debugging session and regular programming... However, I've checked that if I do not relocate the vector table and I program the flash from the beginning (flash starts at 0x08000000), everything works just fine.
Just to clarify - I want to program the bootloader with some offset (0x0800) in memory because I need some space for the bootloader sensitive data (bootheader).
BR,
Marek
2018-02-18 03:55 PM
Well absent a debug connection you're probably going to want to push telemetry out a serial port.
Things would want to dump out would be the FLASH based vector table, the one in SRAM, the address of the table as linked, and the SYSCFG registers, etc.
I might order things like this to avoid any potential clock enable hazards.
/* USER CODE BEGIN 1 */
/* Enable the SYSCFG peripheral clock*/ __HAL_RCC_SYSCFG_CLK_ENABLE(); uint32_t i = 0; for(i = 0; i < 48; i++) VectorTable[i] = *(__IO uint32_t*)((uint32_t)0x08000800 + (i<<2)); /* Remap SRAM at 0x00000000 */ __HAL_SYSCFG_REMAPMEMORY_SRAM();Also make sure BOOT0 is pulled low externally.
Don't transfer control from an IRQ Handler
Watch for name mangling issue with C++ syntax
2018-02-19 01:31 PM
Hi, thank you for your attention! Unfortunately, none of this has helped: what I did:
Any suggestions would be appreciated
BR,
Marek
2018-02-19 02:27 PM
Disabling interrupt can be problematic if you never re-enable them again.
And the code runs without the debugger? ie if you set up a GPIO in the loader, and first code in application main() can toggle.
Without some output to look at and review it is probably not something I can debug through a keyhole.
2018-02-20 12:15 AM
I think you got me wrong: all what I described here concerns only the bootloader. At this point I even do not think about passing the control to a main (loaded) application after the loader stage (in fact it does not exist at the moment ). The problems listed above are ALL in the loader. I need to do all of this remapping stuff etc. in the bootloader as well since I must store some sensitive data at the first flash page; the bootloader will be stored in the second page.
To sum up: we might think about this software as a regular firmware, which has just to be stored in a different flash area (i.e. not in the beginning).
2018-02-20 04:47 AM
The processor isn't going to magically start from an image based at 0x08000800
2018-02-20 12:08 PM
Turvey.Clive.002
thank you for you tips and suggestions. I do not know why I hardcoded in my mind that setting the ENTRY point in the linker script is equivalent to saying to the uC (in this particular case): Hey, start from that point! In this case I will have to move the bootheader to another flash page and locate the bootloader at the address 0x0800 0000.Nevertheless, I'm still curious how it was possible to execute that code in the debug mode?
2018-02-20 12:19 PM
The debugger starts and breakpoints/halts the processor, it then applies the address you want execution to occur. The entry point visible in the .ELF is likely Reset_Handler, so it uses that and off you go.
The processor on the other hand when reset pulls the SP/PC pair from address zero (with FLASH, ROM, RAM mapped there depending on BOOTx pin settings). In the normative case BOOT0=Low, FLASH from 0x08000000 shadows at 0x00000000, and then it vectors off to the FLASH in it's usual address.