cancel
Showing results for 
Search instead for 
Did you mean: 

External interrupt not working when ran by secondary bootloader

ECost
Associate II

Custom board based on STM32F030C8, application compiled with Keil. Using the HAL for initialization and runtime.

When compiled to run directly out of the flash, the EXTI for PB0 works. It is configured to generate interrupts for both edges and when the button connected to it is pressed or depressed, the ISR is ran. The application image is generated with Keil default scatter file.

When the very same application is compiled to be ran out of a secondary boot loader, EXTI simply does not run. The difference of this version is a customized scatter file, an extra assembly file with a MBR that is appended to the end of the image and an externally generated CRC that is checked by the BL on startup. The image starts at 0x80004000. The interrupt vector is copied to the first 48 words of the RAM by the BL and remapped to address 0 (because of the Cortex M0 limitation).

GPIO and EXTI registers have the same value for both application versions. But the corresponding bit in PR register is never set on the BL version.

The application has a second source of interrupt, from a UART and it is working normaly on the BL version. So is the systick interrupt.

Any hint of what I should look at to solve this issue?

Thanks in advance.

8 REPLIES 8

> GPIO and EXTI registers have the same value for both application versions.

Actually read from the registers?

Post them.

> But the corresponding bit in PR register is never set

Did you actually measure *directly on the pin* that the pressed button causes the required edge?

Or at least confirmed this by reading out the respective GPIO_IDR?

JW

Is transfer from boot loader done in interrupt or callback context?​

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

Hi, I will post the registers later.

Did not measure the pin but checked IDR with the debugger and the corresponding bit changes when I press the button.

Not sure if I understand your question but... No, not called from an ISR or ISR callback. It is called from the main loop. It is based on the code of the IAP app note (AN4065):

static uint32_t Boot(void * arg, uint32_t address)
{
    BootApp_Context *obj = (BootApp_Context *)arg;
    (void)obj;
 
    uint32_t resetAddress = *((volatile uint32_t* )(address + 4));
 
    void (*resetFunction)(void) = (void (*)())(resetAddress);
    
    /* Disable all interrupts */
    RCC->CIR = 0x00000000U;
    NVIC_DisableIRQ(USART1_IRQn);
 
    /* Copy the vector table from the Flash (mapped at the base of the application
                     load address 0x08003000) to the base address of the SRAM at 0x20000000. */
    for(int i = 0; i < 48; i++)
    {
        VectorTable[i] = *(__IO uint32_t*)(address + (i<<2));
    }
 
    /* Enable the SYSCFG peripheral clock*/
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);
 
    /* Remap SRAM at 0x00000000 */
    SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
 
    /* Initialize user application's Stack Pointer */
    __set_MSP(*(__IO uint32_t*) address);
 
    /*Feed watch dog*/
    IWDG_ReloadCounter();
 
    /*Call application*/
    resetFunction();
 
    return 0;
}

Here are the registers as requested. Top row is of the non-bootloader version. Notice the fourth (left to right) has the PR bit 0 set. The rightmost one is the corresponding GPIOB. Taken after a breakpoint stop on the ISR entry when button was pressed.

Bottom row is the same registers for the bootloader version. The rightmost image is of the GPIOB when I press the button (notice the bit 0 of IDR goes to zero). PR bit 0 never is set.

0693W000000VyPIQA0.png

Maybe it is sheer fatigue but I simply cannot find any difference in the configurations that could justify the behavior.

Below, the core NVIC view of Keil, left the non-bootloader version, right the bootloader one.

0693W000000VyPNQA0.png

What am I missing?

Compare also SYSCFG_EXTICRn.

> RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);

I don't use SPL, but RCC_APB2PeriphResetCmd() does not sound that it's intended to *enable* anything. Doesn't it leave the respective RCC reset bit hanging at 1?

JW

Hello, Jan.

Thank you for chiming in.

You're right, SYCFG_EXTICR1 is different, 1 in the working version, 0 in the BL version.

And yes, the SYSCFGRST bit is set when it enters the application and it is never reset; therefore the configuration on SYSCFG_EXTICR1 is never set.

The funny thing is the proof-of-concept application worked: it also used the blue button on the Discovery board, apparently using EXTI to detect when the button is pressed. I will have to look deeper at it to learn if it does use the interrupt to detect button pressed or the GPIO logic level.

Any idea of why to reset specifically SYSCFG and not other subsystems? As I mentioned before, this Boot function is based on the code of AN4065 so the developer used this part of the code mostly as is and as it worked with the demo application, we assumed everything was well.

ECost
Associate II

Answering my own question

>Any idea of why to reset specifically SYSCFG and not other subsystems?

It looks like the code has an error. The funny thing is it works as the uC jumps to the application but I guess it is out of sheer luck/chance.

I added the intruction

	/* Enable the SYSCFG peripheral clock*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

After doing this, I found an old post by Clive that did just that.

https://community.st.com/s/question/0D50X00009XkePcSAJ/interrupt-vector-table-relocation-on-cortex-m0

I kept the reset but added the deassertion

	/* Reset SYSCFG */
	RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);
	RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, DISABLE);

I am not sure this is really necessary though.

I also disabled the SysTick counter and interrupt to avoid the case where an SysTick interrupt occurrs between the __set_MSP() and the jump to the application image (resetFunction()).

As for the original question, thank you all for your support.

Elder.

PS: Suggestion on other things to set before running the application image are very welcome.