EXTI deja de funcionar después de saltar al nuevo firmware STM32L4

3

Estoy trabajando en una aplicación en el microcontrolador STM32L4. La idea es que cuando presiono el botón de usuario, el gestor de arranque salta de la aplicación principal (0x08000000) a la segunda (0x08080000).

El segundo firmware es solo una aplicación de LED parpadeante. El salto está bien y el LED comienza a parpadear, pero mi problema es que cuando quiero volver de la segunda aplicación a la primera (0x08000000), la exti no funciona.

Aquí está mi código:

Primer 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();
}

El comienzo del segundo firmware:

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

  SystemClock_Config();

  HAL_InitTick(1);

...

Esta es la devolución de llamada exti del segundo 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();
        }
    }
}

¿Por qué esto no funciona?

    
pregunta Raed Bouchaa

1 respuesta

5

Está iniciando la otra aplicación desde la rutina de servicio de interrupción, nunca regresará del controlador de interrupción . El sistema no ejecutará el mismo controlador de interrupciones (o cualquier otro controlador con la misma o menor prioridad) hasta que aparezca secuencia de retorno de excepción se ejecuta. Debería salir de todos los controladores activos antes de saltar al otro firmware.

El método más simple es establecer un indicador global volatile en el controlador de interrupciones y verificarlo periódicamente en su bucle de aplicación principal.

También puedes reiniciar el sistema usando NVIC_SystemReset() . Necesitaría una forma de verificar y comunicar de dónde proviene la solicitud de restablecimiento, ya que siempre va a la primera aplicación.

También tenga en cuenta que __disable_irq; no hace nada, necesitaría () para llamar a una función. Siempre es una buena idea habilitar y verificar las advertencias del compilador.

    
respondido por el berendi

Lea otras preguntas en las etiquetas