El cargador de arranque STM32F7 no puede saltar a la aplicación

Mi problema es que mi gestor de arranque no salta a la aplicación, o tal vez sí, pero luego salta de nuevo al gestor de arranque debido a una interrupción. Para darle algo con lo que trabajar aquí hay algo de información:

El código que salta a la aplicación.

typedef void (*pFunction)(void);

pFunction Jump_To_Firmware;

void JumpToInternalFlashImage()
{
    Jump_To_Firmware = (pFunction) (*(uint32_t *)(0x08008000 + 4));

    __set_MSP(*(uint32_t*) 0x08008000);

    Jump_To_Firmware();

}

Cómo se ve main en la aplicación

int main(void)
{
    // Copy ISRs to RAM
    memcpy((uint8_t *)&_isr_vector_ram_start, (uint8_t *)&_isr_vector_flash_start, &_isr_vector_flash_end - &_isr_vector_flash_start);

    // Relocate the vector table
    SCB->VTOR = (uint32_t) &_isr_vector_ram_start;

    HAL_Init();

    SystemClock_Config();

    MX_GPIO_Init();
    MX_DMA_Init();
    MX_USART2_UART_Init();

    while (1)
    {
        HAL_UART_Transmit_DMA(&huart2, "hello", 5);

        uint32_t i =0;
        for(;i<1000000;i++);
}

Tal vez debería señalarse que este programa funciona bien si lo programo a través del enlace ST sin ningún código de cargador de arranque. Además, las partes importantes de este código deberían ser las primeras líneas donde copio los ISR a la RAM y luego reubico el vector

El linkerscript tiene el siguiente aspecto para darle una idea de dónde provienen las direcciones (se ve igual tanto en el gestor de arranque como en la aplicación)

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = 0x20050000;    /* end of SRAM2 */

/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0;      /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack */

// There are more areas but these should be the only relevant ones
MEMORY
{
   FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 1024K
   RAM_ISR (xrw)   : ORIGIN = 0x20000000, LENGTH = 512
   RAM (xrw)   : ORIGIN = 0x20000200, LENGTH = 64K - 512
}

SECTIONS
{
    /* The startup code goes first into FLASH */
    .isr_vector :
    {
        . = ALIGN(4);
        _isr_vector_flash_start = .;
        KEEP(*(.isr_vector)) /* Startup code */
        _isr_vector_flash_end = .;
        . = ALIGN(4);
    } >FLASH

   ._isr_vector_ram (NOLOAD) :
   {
       . = ALIGN(4);
       _isr_vector_ram_start = .;
       KEEP(*(._isr_vector_ram)) /* Startup code */
       . = ALIGN(4);
   }>RAM_ISR
}

Entonces mi problema es que cuando trato de saltar a la aplicación no funciona

Las primeras direcciones de 0x8008000 (dirección de inicio de la aplicación) parecen

ingrese la descripción de la imagen aquí

Y en la dirección 0x08004DD1 parece

ingrese la descripción de la imagen aquí

Lo que pasa es que siempre termino atascado cuando el contador del programa apunta a (no se mueve de esta dirección al intentar dar un paso más)

0x8007770

y MSP

0x2004ffe0

en el mapa de salida para el cargador de arranque puedo ver que 0x08007770 es

.text.Default_Handler
            0x08007770        0x2 startup/startup_stm32f746xx.o
            0x08007770                RTC_Alarm_IRQHandler
            0x08007770                EXTI2_IRQHandler
            0x08007770                TIM8_CC_IRQHandler
            0x08007770                DebugMon_Handler
            0x08007770                UART8_IRQHandler
            0x08007770                SPI4_IRQHandler
            0x08007770                TIM1_CC_IRQHandler
            0x08007770                DMA2_Stream5_IRQHandler
            0x08007770                HardFault_Handler
 and so on (the rest of the handlers )

Alguien sabe cual es mi problema y como solucionarlo? Siéntase libre de hacer preguntas si siente que me he olvidado de decirle algo.

¿No idebería declararse volatilepara evitar que el optimizador del compilador elimine el ciclo?

Respuestas (1)

Debe ajustar las secuencias de comandos del enlazador para reflejar el hecho de que los programas deben cargarse en áreas flash separadas. Entonces, para el cargador de arranque que necesita

FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 32K

y para la aplicación:

FLASH (rx)      : ORIGIN = 0x08008000, LENGTH = 992K /* (992 = 1024 - 32 */
Gracias, esto realmente cambió las cosas. Todavía no funciona, pero lo que sucede cuando hago esto es que la dirección que en las imágenes es 0x08004DD1 cambia a 0x0800CDCD y cuando voy a esa dirección está vacía. Lo que significa que no hay datos de esa dirección. ¿Alguna idea de qué causa eso? Cuando programo, simplemente estoy usando una dirección de inicio y luego incrementando con 4 bytes hasta que se programa todo el archivo bin
Si la dirección está vacía, entonces algo está mal con el proceso de flasheo, o el archivo bin se truncó, primero depuraría ese problema. También tenga en cuenta que la dirección de instrucción real es uno menos que el valor del puntero.
El caso es que mi solución para copiar el vector ISR memcpy((uint8_t *)&_isr_vector_ram_start, (uint8_t *)&_isr_vector_flash_start, &_isr_vector_flash_end - &_isr_vector_flash_start); se basa en la dirección de inicio y fin de flash. ¿Esto realmente sucede después de que cambié el área de memoria?
Sí, deberían obtener los valores correctos del script del enlazador, pero de todos modos consultaría con un depurador para estar seguro.
Me di cuenta de que si programo la aplicación a través de ST-Link y elijo la dirección de inicio 0x08008000, funciona y no falta ningún código en la dirección que señalé anteriormente. Pero no estoy seguro de dónde puede estar el problema. Debido a que todos los datos del archivo bin parecen estar en la memoria flash cuando uso el gestor de arranque, está claro que faltan datos en las direcciones de memoria. ¿Sabes si ST-Link hace algo especial además de copiar el archivo BIN a flash?
ST-Link simplemente copia los bytes y luego los verifica. No estoy tan familiarizado con la serie F7, pero en la F4 había muchas posibilidades en las que la programación flash podía salir mal. Bueno, el problema de "saltar a la aplicación" aparentemente está resuelto, quizás podrías hacer otra pregunta con el problema de la programación flash.
Resuelto el problema. De hecho, fue la programación flash la que falló debido al desbordamiento de los búferes. El linkerscript podría ser 0x08008000 o 0x08000000 pero marcaré esto como la respuesta correcta de todos modos