cancel
Showing results for 
Search instead for 
Did you mean: 

Exti stop working after jumping to the new firmware stm32L4

raed
Associate II
Posted on March 31, 2017 at 21:28

http://electronics.stackexchange.com/questions/295904/exti-stop-working-after-jumping-to-the-new-firmware-stm32l4

Hi I am new here ,I am working on an application on stm32l4 microcontroller ,

the idea is when I press the user button the bootloader jump from the main application (0x08000000)

to the second one (0x08080000) . THe second firmware is just a blinking led application ,

the jumping is fine and the led start blinking , but my problem is that when I want to go back from the second application to

the first one (0x08000000) the exti won't work ! here's my code :

first firmware :

 if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000) { 
/* Jump to user application */ 
JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
 JumpToApplication = (pFunction) JumpAddress;
 /* Initialize user application's Stack Pointer */
 __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
 __disable_irq; 
SCB->VTOR = FLASH_BASE | 0x80000; 
HAL_RCC_DeInit(); 
SysTick->CTRL =0; 
SysTick->LOAD=0; 
SysTick->VAL=0; 
__set_PRIMASK(1); 
printf('Starting Firmware 2 . . . \r\n'); 
HAL_DeInit(); 
JumpToApplication();}

the beginng of the second firmware :

 SCB->VTOR = FLASH_BASE | 0x80000; 
__set_PRIMASK(0);
 HAL_Init(); 
SystemClock_Config(); 
HAL_InitTick(1); 

...

this is the exti callback from the second firmware :

 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){ 
HAL_NVIC_ClearPendingIRQ(EXTI15_10_IRQn); 
HAL_NVIC_DisableIRQ(EXTI15_10_IRQn); 
if (GPIO_Pin == GPIO_PIN_13) 
{ 
if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000) 
{JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4); 
JumpToApplication = (pFunction) JumpAddress;
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS); 
HAL_NVIC_DisableIRQ(EXTI15_10_IRQn); 
__disable_irq; 
SCB->VTOR = FLASH_BASE; 
JumpToApplication(); }}}

Can any one please tell me why this is not working ?

#stm32l4-bootloader
16 REPLIES 16
S.Ma
Principal
Posted on April 01, 2017 at 16:52

What is the intended purpose beyond the app switch?

Here when jumping to a function, it is assumed that the stack is still the same with some registers pushed by the EXTI IRQ... doing a function jump might confuse the compiler/linker.

Also remember that a physical button has debounce effect : put a 20 msec delay in the interrupt then clear the PR flag to make sure. Otherwise, everytime someone push the button, you might get 3-6 EXTI in a very short time...

Another way is to disable the EXTI within and rearm by the other task after fully started. (PR bit cleared before enable IRQ)

Why not put an RTOS and have 2 tasks (not time slicing) which would switch between the two by EXTI?

Posted on April 01, 2017 at 17:06

Transferring control from an IRQHandler is problematic because when you don't exit it doesn't clear the NVIC properly, and then effectively blocks that and lower priority sources.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
raed
Associate II
Posted on April 01, 2017 at 17:05

thnx for the reply ,

the purpose 

beyond the app switch is that the first app (0x08000000) download a firmware and flash it to 0x08080000

, so after the download is done , I press the button and it switch the app , and if I want to go back to the first firmware to download for exemple new firmware I press the button again .

the first jump works fine but going back isn't working , (the led still blinking from the second firmware)  ..

Posted on April 01, 2017 at 17:10

 __disable_irq; 

// remember to re-enable on the otherside

Also just set SCB->VTOR = APPLICATION_BASE, or-ing it with FLASH_BASE and offsets just gives additional dependencies you can miss when copying and pasting.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on April 01, 2017 at 17:11

yes, the exti works just the first time but it stop working after the first jump !

if I press the reset button it switch back from the second firmware

(0x08080000)  

to the first one (0x08000000) !

I just want to get the same results using the user button 

Posted on April 01, 2017 at 17:12

Or just NVIC_SystemReset() ?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on April 01, 2017 at 17:19

Yes this work too , but the project needs to be done with a normal jump like the first one

raed
Associate II
Posted on April 01, 2017 at 20:23

No one ????

Posted on April 01, 2017 at 20:30

That's really not how forums work...

If your base firmware expects to enter in reset conditions, try to ensure that you don't put it in some odd state. Make sure you enable interrupts, and look more critically at what exactly is blocking in your case.

If I was transferring control from an EXTI interrupt I'd fix the return address on the stack to the Reset_Handler entry point, and make sure the firmware set up it's own vector table address and stack when it got there.

Make a minimal pair of firmware that demonstrate your case of going back and forth, I'm not going to guess what's wrong from a few snippets cut out of context.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..