2017-06-01 08:34 AM
Hello,
I have some problems to implement a bootloader in a STM32F4. I searched on internet and I found coherent informations and examples, but I 'm not able to make simple test work.Here my simple code:
bootloader (writed on 0x08000000 address):
&sharpdefine APPLICATION_ADDRESS 0x08008000
typedef void (*pFunction)(void);
pFunction appEntry;uint32_t appStack, test, i;int main(void){
/* Get the application stack pointer (First entry in the application vector table) */
appStack = (uint32_t) *((__IO uint32_t*)APPLICATION_ADDRESS);/* Get the application entry point (Second entry in the application vector table) */
appEntry = (pFunction) *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);/* Reconfigure vector table offset register to match the application location */
SCB->VTOR = APPLICATION_ADDRESS;/* Set the application stack pointer */
__set_MSP(appStack);/* Start the application */
appEntry();while(1);
return 0;
}program (writed on 0x08008000 address):
int main(void){
register uint32_t tl;GPIO_InitTypeDef GPIO_InitStructure;
ErrorStatus HSEStartUpStatus; RCC_DeInit(); // Enable HSE RCC_HSEConfig(RCC_HSE_ON); // Wait till HSE is ready HSEStartUpStatus = RCC_WaitForHSEStartUp(); if(HSEStartUpStatus == SUCCESS){ // HCLK = SYSCLK impostato a 168 tick RCC_HCLKConfig(RCC_SYSCLK_Div1); // PCLK2 = HCLK/2 perch� massimo � 84Mhz RCC_PCLK2Config(RCC_HCLK_Div2); // PCLK1 = HCLK/4 perch� massimo � 42Mhz RCC_PCLK1Config(RCC_HCLK_Div4); // PLLCLK = 168 MHz RCC_PLLConfig(RCC_PLLSource_HSE, 12, 336, 2, 7); // PLLCLK = 144 MHz //RCC_PLLConfig(RCC_PLLSource_HSE, 12, 288, 2, 6); // Enable PLL RCC_PLLCmd(ENABLE); // Wait till PLL is ready while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) { } // Select PLL as system clock source RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // Wait till PLL is used as system clock source while(RCC_GetSYSCLKSource() != 0x08){} SystemCoreClockUpdate(); } RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOG, &GPIO_InitStructure);GPIO_SetBits(GPIOG, GPIO_Pin_4);
while(1){
for(tl=0; tl < 0xFFFFFF; tl++); // about 0.6 seconds GPIO_ToggleBits(GPIOG, GPIO_Pin_4); }return 0;
}I write program to 0x08000000 address for test and it works, so I'm sure there is no bugs.When I use bootloader system doesn't work. I try to understand with debugger and I see that instruction appEntry(); has no effect and next command is while(1);
Can anyone tell me where it is wrong?
ThanksRoberto#bootloader #stm-32f407Solved! Go to Solution.
2017-06-26 11:05 AM
I've presented multiple examples over the years here. Perhaps the better course is to provide the two sides of the transaction you are doing, and it might be more apparent. Ideally as a complete project.
If you disable IRQ's before the jump, you have to reenable them.
If you jump from interrupt context this will also block interrupts, at this preemption level and above, moving forward.
Make sure SystemInit() isn't changing SCB->VTOR to some other address.
Use breakpoints and a debugger, better understand the state you've left the system in.
2017-06-01 09:34 AM
>>
Can anyone tell me where it is wrong?
Not from information presented. Use the debugger in disassembly mode and look at where the transfer goes. Confirm the addresses match those described by the .MAP for the application.
Make sure NO interrupts are firing, ie SysTick, etc
Print out the appStack and appEntry values.
2017-06-05 03:19 AM
SOLVED!
Thanks for your help. the problem was mapping program memory. I changed stm32f4xx_flash.ld file (program) fromMEMORY{... FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K...}toMEMORY{... FLASH (rx) : ORIGIN = 0x8008000, LENGTH = 992K...}checked .MAP file and tested. All works. If it may be usefull for anyother...Thanks Roberto
2017-06-26 08:45 AM
I have another problem: I'm unable to run interrupt in the program.
I try a simple test with SysTick_Handler but after bootloader no interrupts work.
Any suggestions?
Any simple examples?
I try to disable all thinks in bootloader before jump to program, but it may not be sufficient
thank in advance
Roberto
2017-06-26 11:05 AM
I've presented multiple examples over the years here. Perhaps the better course is to provide the two sides of the transaction you are doing, and it might be more apparent. Ideally as a complete project.
If you disable IRQ's before the jump, you have to reenable them.
If you jump from interrupt context this will also block interrupts, at this preemption level and above, moving forward.
Make sure SystemInit() isn't changing SCB->VTOR to some other address.
Use breakpoints and a debugger, better understand the state you've left the system in.
2017-06-28 01:21 AM
2017-07-04 11:41 PM
help from anyone?
2017-07-05 08:25 AM
Today I add this line at start of application main function:
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x8000);
and the SysTick interrupt works. I hope this is the solution.
If it may be usefull for anyother...
Roberto
2017-07-05 11:29 PM
Ok, I 've understood. For a mistake I don't correctly set the VECT_TAB_OFFSET macro.
thanks Clive for your suggestions.
Roberto
2018-01-15 09:16 AM
Hi Roberto, I have the same problem as you when trying to jump to the application from a custom bootloader.
I followed your code and I'm stuck at the same point as you,
If I launch the bootloader and then try to switch to the main application the interrupts stop working the SysTick Handler doesn't work too.
You said in your solution that you failed to set correctly the VECT_TAB_OFFSET, but to me I think that I'm setting it correctly:
BOOTLOADER_START: 0x8000000
APPLICATION_START: 0x8004000
SCB->VTOR in the boot loader start code is 0x8000000
SCB->VTOR in the application start code is 0x8004000
moreover if I halt the code with the debugger in the application, the SCB->VTOR variable is correctly set to 0x8004000
Do you have any hints for me?