AVR- "Función principal del cargador de arranque y función principal de la aplicación"

Solo estoy tratando de construir un gestor de arranque personalizado para avr. Sé que las funciones del cargador de arranque se pueden compartir con el programa de aplicación. Sin embargo, estoy realmente confundido con la función principal. ¿El cargador de arranque y el programa de aplicación tienen una función principal? Si no, cómo escribir dos programas separados con una sola función principal

Programa de aplicación:

    #include <avr/io.h> // application program at 0x0000
    #include <string.h>
    int main()
    {
     uart_init();
    }

Programa de cargador de arranque:

    #include <avr/io.h>
    #include <avr/boot.h>
    void uart_init();
    void (*funcptr)( void ) = 0x0000;
    int main(void)
    {
   uart_init();
       //Boot or Goto Application program
    }
    void uart_init()
    {
       //UART initialization code;
    }

Respuestas (2)

Los mantendría separados.

Lo que puedes hacer es:

  • Crea dos programas, tu gestor de arranque y tu aplicación.
  • Asegúrese de que estos dos programas estén vinculados a diferentes ubicaciones (por ejemplo, el cargador de arranque a 0x0 (vector de reinicio) y la aplicación a 0x20000 (dirección de la aplicación).
  • El cargador de arranque se iniciará después de un reinicio e inmediatamente después decidirá si debe iniciar las rutinas del cargador de arranque o si debe bifurcarse a la aplicación. Solo haga lo que sea absolutamente necesario para tomar esa decisión (las reglas para tomar esa decisión dependen de usted; por ejemplo, algún valor especial en flash o presionar un botón).
El cargador de arranque solo se puede cargar en la sección inferior del controlador y el indicador BOOTRST debe estar habilitado para cargarlo después del reinicio. ¿Cómo podemos escribir en la dirección 0x00? ¿Es posible
¿Qué parte exactamente usas? No estoy familiarizado con el fusible BOOTRST y me gustaría buscarlo para su pieza específica. Si entiendo correctamente, este fusible hará que el procesador se inicie desde una dirección diferente. Deberá decirle al enlazador dónde colocar su gestor de arranque o aplicación. Para las partes de 32 bits (AT32...) esto se hace a través de una configuración de enlace + un código llamado trampolín (que solo hace un código de operación de salto).
Sí, BOOTRST hará que el controlador ejecute el código en la sección de inicio después de reiniciar. Entonces podemos dar un salto al código de la aplicación desde el código de arranque
En ese caso, deberá vincular el código del gestor de arranque a la sección de arranque y el código de la aplicación a la sección de aplicación "normal". ¿Es esta una bandera que puede programar con la frecuencia que desee? Porque entonces podrías usarlo como indicador de si se debe ingresar o no al bootloader y no necesitarías dar el salto manualmente.
Esta bandera solo se puede configurar con un programador y no se puede cambiar internamente. Cada vez que termine con algún problema al escribir el código de la aplicación, el código de la aplicación corrupto estropeará todo el uso y nuevamente necesitará un programador externo si inicia el código de la aplicación después de reiniciar. En tal caso, BOOTRST viene a rescatarte

Combinar el gestor de arranque y el programa principal en un solo binario no tiene sentido a menos que desee lograr algo muy especial. El cargador de arranque se usa normalmente para flashear/actualizar el programa principal a través de la interfaz "normal" (USB, UART) y el código BL generalmente se carga solo una vez a través de ISP/JTAG. El código BL también puede admitir el cifrado para no proporcionar su código a todos los que están actualizando su dispositivo (actualización de firmware).

Cuando se ingresa el código del cargador de arranque (depende de los FUSE), debe tomar una decisión rápida si salta al código principal o permanece en el cargador de arranque. El cargador de arranque predeterminado de Arduino usa tiempos de espera para el encabezado del protocolo Stk en serie, lo cual es muy molesto porque prolonga cada proceso de arranque por un par de segundos. Prefiero cuando hay una interfaz de usuario presente (botón, ...) probar rápidamente si el usuario desea hacer que el firmware parpadee (mantenga presionado el botón después del ciclo de encendido más o menos).