AVR y los cargadores de arranque: ¿por dónde empezar?

5

Tengo la necesidad de escribir un programa de cargador de arranque en un microcontrolador AVR (Atmega32) para habilitar la autoprogramación. He leído varios recursos sobre el tema de los cargadores de arranque y he llegado a la siguiente conclusión:

La primera dirección de flash tiene información almacenada sobre dónde está el inicio del programa del cargador de arranque. Por lo tanto, cuando se lee desde flash, la ejecución comenzará en 0x00 y saltará a donde se especifique en esa ubicación al cargador de arranque.

El programa del cargador de arranque debe entonces "escuchar" los datos entrantes en un pin. Si se encuentra información, quizás después de un marco de datos específico que consiste en un comando relacionado con una secuencia de reprogramación, el cargador de arranque comienza a guardar los datos entrantes en otra ubicación en flash. Después del final de la transmisión de datos, el cargador de arranque debe saltar a la dirección flash asociada con el primer byte de información durante la fase de reprogramación y comenzar la ejecución.

Tengo entendido que esta secuencia de eventos, escucha y reprogramación, ocurre en cada evento RESET. Si no se encuentra información entrante, entonces comienza la ejecución normal del código ya presente en flash (comenzando en la misma dirección en la que el cargador de arranque comenzaría a guardar).

Básicamente algo como esto:

Dado que conozco el proceso de este programa de cargador de arranque muy básico, ¿dónde puedo comenzar a aprender exactamente cómo escribir este programa específicamente para la arquitectura AVR? Si el tamaño es una preocupación, entiendo que estos programas pueden estar escritos en ASM. Teniendo en cuenta que no conozco suficiente ASM, por no hablar del conjunto de instrucciones para un controlador determinado, lo más probable es que escriba este programa en C.

¿Alguna sugerencia / recursos?

Gracias

    
pregunta sherrellbc

3 respuestas

5

Dependiendo de sus requisitos, hay un enfoque algo diferente (al que usted describió) que podría interesarle.
Puede dejar que la aplicación principal maneje la descarga / recepción del nuevo firmware e "instruir" al cargador de arranque para que lo ejecute al reiniciarse.

Para darle una idea de cómo se podría implementar esto:

  1. La aplicación principal implementa una interfaz de comunicación para recibir actualizaciones (USB, UART, etc.)
  2. Los datos se almacenan en la memoria externa (por ejemplo, flash de serie)
  3. Después de una recepción exitosa (cálculo de suma de comprobación), el programa principal le indica al cargador de arranque que hay una actualización disponible (marca de advertencia / estado de actualización "actualización disponible" para EEPROM, por ejemplo)
  4. Problemas de la aplicación principal restablecimiento de software
  5. El cargador de arranque lee la información de estado de la actualización, verifica y ejecuta la actualización.
  6. Una vez completada la actualización, el cargador de arranque establece el estado de la actualización en "ejecutado"
  7. El cargador de arranque salta al programa principal
  8. El programa principal puede reconocer que se ejecutó una actualización (y quizás realizar algunas acciones especiales) y establece el estado de la actualización en "ninguna"

En comparación con el enfoque clásico en el que solo participa el cargador de arranque:

Pros:
+ No se requiere reinicio y no hay restricción de tiempo para iniciar la actualización
+ Posible interfaz / protocolo de comunicación compleja debido a que no está limitado al tamaño de flash de la sección de arranque pequeño
+ Mejor control del mecanismo de actualización. + Desacopla la interfaz de comunicación del cargador de arranque (el mecanismo de recepción se puede actualizar / cambiar)
+ La aplicación principal "sabe" sobre la actualización (próxima) y puede reaccionar (realizar migraciones de datos, actualizaciones de configuración, dar comentarios de los usuarios como "actualizado de v1.22 a v1.3", etc.)

Contras:
- Se requiere almacenamiento externo (si nunca usa más de la mitad del flash principal, probablemente se podría abusar de él como almacenamiento temporal)
- Diseño un poco más complejo. - La lógica del cargador de arranque está acoplada a la aplicación principal
- El dispositivo debe enviarse con la aplicación principal pre-flasheada

    
respondido por el Rev1.0
3

La forma más fácil de comenzar es examinar un gestor de arranque existente e intentar modificarlo según sus necesidades.

En cada página de información de AVR en el sitio web de Atmel, hay una pestaña "Documentos", que contiene información y el código que Atmel proporciona a cada visitante de su sitio. En la pestaña Documentos de ATmega32 hay 3 diferentes cargadores de arranque para examinar; Le recomiendo que descargue tanto el PDF como el código fuente de todos ellos para comprender cómo funcionan.

    
respondido por el Ignacio Vazquez-Abrams
2

Escribí algo así para un AT32UC3C. En realidad fue bastante fácil:

  • Comience escribiendo una aplicación que pueda escribir una parte del flash. Intenta hacerlo lo más pequeño posible

  • Defina una condición de activación (puede ser presionar un botón o insertar una memoria USB, depende de lo que desee)

  • Defina una dirección de salto para la aplicación principal (donde se inicia la aplicación principal)

Ahora que va a pasar: Después de RESET, la ejecución comenzará en la dirección predeterminada (aquí es donde reside su gestor de arranque). El gestor de arranque comprobará una condición (botón presionado, datos entrantes, lo que sea). Si la condición existe, nos quedamos en el código del gestor de arranque. Si la condición NO está presente (ejecución normal), reinicie cualquier cambio en los registros o bloques de hardware que haya realizado, luego salte a la dirección especificada. Puedes hacer esto, por ejemplo. de la siguiente manera:

    if (gpio_get_pin_value(PB_STATUS1_PIN) && !is_force_bootloader()) {
    // Run application
    void (*application)(void) = (void*)0x80008000;
    application();
}

Este código saltará a la dirección 0x80008000 - > Asegúrese de que su aplicación esté almacenada allí.

Cuando estás dentro del gestor de arranque, dependiendo de cómo obtengas tus datos, ahora tienes la opción de escribir estos datos en bloque para flash.

Algunos AVR contienen una opción para "proteger" un área del flash. Compruebe dónde están los límites e intente ajustar su cargador de arranque en dicho bloque. Luego protéjalo, e incluso por accidente, no podrá sobrescribir su cargador de arranque :-)

    
respondido por el Tom L.

Lea otras preguntas en las etiquetas