cancel
Showing results for 
Search instead for 
Did you mean: 

No interrupt after the interrupt vector table relocated to SRAM. STM32F072CBTx

ELin.4
Associate II

Hi, there

I am developing a bootloader to upgrade the firmware through CAN. I have done it successfully with a STM32L431CCUx platform. Everything works when the SCB->VTOR is available.

When it comes to this Cortext-M0 core (STM32F072), which has no VTOR, I realized that I need to the followings:

  1. Reserve the beginning 196 bytes of SRAM to store the Interrupt Vector Table. See ReserveSRAM.png. I did this in the beginning of SystemInit(). I've also tried it in the beginning of main(), failed the same.
  2. Copy the Interrupt Vector Table of the application to the beginning of SRAM. My application codes starts at 0x08014000. See CopyMemories.png.
  3. Remap 0x20000000 to 0x00000000. See SYSCFG_CFGR1.png.

However, after I've done all these, the interrupt subroutines in the application code are never called. The SysTick timer interrupt, and any other interrupt if enabled, is always pending. See NVIC.png. The break point at the interrupt handler is never hit. I can trace the firmware from my bootloader all the way to the main application and everything seems to be working fine. The main application hangs inside the HAL SPI driver to wait for the interrupt that never came.

Can anybody point out what I'm missing ?

Thanks,

Regards,

Eric

1 ACCEPTED SOLUTION

Accepted Solutions

>>I did disable all the interrupts before entering the main application.

And did you ever enable them again, most code assumes the processor starts with them enabled, because it does.

The "Disable The Interrupts" mantra in the context it should be used here is that you've turned them off at the sources, so the app doesn't suddenly have to deal with a mess that the loader left behind whilst lacking any initialization or context/instances. ie where is hUart3 and why is it USART3 interrupting..

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

View solution in original post

5 REPLIES 5

Maybe you jump to the application from the bootloader in an interrupt. That is then the same as disabling all interrupts with lower or equal priority.

JW

Hi, JW

This is how I jump from the bootloader to the application:

typedef   void   (*pFunction)(void);

 // jump to the main application.

 __disable_irq();

 uint32_t appStack = (uint32_t) *((volatile uint32_t*)0x08014000);

 pFunction appEntry = (pFunction) *(volatile uint32_t*) (0x08014000 + 4);

 __asm volatile ("MSR msp, %0" : : "r" (appStack) : );

 appEntry();

I did disable all the interrupts before entering the main application. I could see that the jump enters to the Reset_Handler() of the main application.

Is this looked all right with you ?

Eric

>>I did disable all the interrupts before entering the main application.

And did you ever enable them again, most code assumes the processor starts with them enabled, because it does.

The "Disable The Interrupts" mantra in the context it should be used here is that you've turned them off at the sources, so the app doesn't suddenly have to deal with a mess that the loader left behind whilst lacking any initialization or context/instances. ie where is hUart3 and why is it USART3 interrupting..

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

Hi, Tesla

I am not sure I understand completely.

As you can see from the codes posted above, the bootloader enters the main application soon after __disable_irq(). Once the main application takes over, it executes its own Reset_Handler(), SystemInit() and then enters the main(). It is in the beginning of SystemInit() that I map the 0x20000000 to 0x00000000. In the main() of the main application it does what ever it needs to configure the peripherals and enables the interrupts, etc., as such the new interrupts should be serviced by the handler subroutines given from 0x20000008.

In the attached figure, you can see all the enabled and pending interrupts in the main application.

My issue is that the interrupts are enabled, and some of them are pending. It is just that they are not serviced by the interrupt handlers in my main applications. Particularly, if I enable a Timer interrupt, I can see that the interrupt is pending after the period elapses. However, the Timer interrupt handler subroutine is never called to service the interrupt. This to me looks like the interrupt vector table is not configured correctly. I just don't know what I am missing here.

> what I am missing here

__enable_irq()

JW