11 votos

Detalles del gestor de arranque de Arduino

¿Puede alguien explicar cómo el Cargador de arranque de Arduino ¿funciona? No estoy buscando una respuesta de alto nivel aquí, he leído el código y tengo la esencia de la misma. También he leído esto otro puesto (Incluso he sido uno de los que han respondido a ella).

Hay un montón de interacción de protocolo que ocurre entre el IDE de Arduino y el código del cargador de arranque, lo que finalmente resulta en una serie de instrucciones de ensamblaje en línea que autoprograman la flash con el programa que se transmite a través de la interfaz de serie.

Lo que no tengo claro es la línea 270:

void (*app_start)(void) = 0x0000; 

...que reconozco como la declaración, e inicialización a NULL, de un puntero de función. Hay llamadas posteriores a app_start en lugares donde el gestor de arranque pretende delegar en la ejecución del código cargado por el usuario.

Seguramente, de alguna manera app_start tiene que obtener un valor no NULL en algún momento para que todo esto se cumpla. No veo eso en el código del gestor de arranque... ¿está vinculado mágicamente por el programa que es cargado por el gestor de arranque? Supongo que la parte principal del cargador de arranque es el punto de entrada en el software después de un reinicio del chip.

En las aproximadamente 70 líneas de ensamblaje debe estar el anillo decodificador secreto que le dice al programa principal dónde está realmente app_start? ¿O tal vez es algún conocimiento implícito aprovechado por el IDE de Arduino? Todo lo que sé es que si alguien no cambia app_start para que apunte a otro lugar que no sea 0, el código del cargador de arranque simplemente giraría sobre sí mismo para siempre... así que ¿cuál es el truco?

Por otro lado, ¿sería posible que el código del cargador de arranque se basara en las interrupciones o es un no-no?

Editar

Estoy interesado en tratar de portar el cargador de arranque a un Tiny AVR (específicamente el ATTiny44A) que no tiene espacio de memoria separado para el código del cargador de arranque. Como se me hace evidente que el código del gestor de arranque depende de ciertas configuraciones de fusibles y del soporte del chip, supongo que lo que realmente me interesa saber es qué se necesita para portar el gestor de arranque a un chip que no tiene esos fusibles ni soporte de hardware (pero que sigue teniendo capacidad de autoprogramación).

Estaba pensando que podría usar la implementación del AVR307 para usar el USI como una UART half-duplex (usa la interrupción Timer0, y la interrupción de cambio de pin). ¿Alguien puede orientarme sobre cómo escribir/portar el código del cargador de arranque para un chip que no tiene soporte de hardware para cargadores de arranque?

Supongo que pondría mi código del gestor de arranque en la ubicación normal de la dirección main (por ejemplo, 0x029e o donde el compilador ponga main). Entonces haría que la 'dirección' en el código del cargador de arranque añadiera un desplazamiento que me pusiera justo después del final de main, y tendría 'app_start' establecido en esa dirección. ¿Estoy pensando en esto correctamente o me estoy perdiendo algo? Gracias.

EDITAR 2

FWIW, encontré un proceso documentado para cómo cargar los bocetos de Arduino en un ATTiny85 que es a lo que iba originalmente con esta pregunta... bastante limpio, creo.

12voto

letronje Puntos 128
void (*app_start)(void) = 0x0000; 

Esto no es un puntero NULL. Realmente es la dirección del inicio del código de la aplicación, a la que salta el gestor de arranque. El enlazador se encarga de que tu código de aplicación comience en la dirección 0. Ver la tabla 26-6 en la hoja de datos del ATMEGA168.

El código del cargador de arranque comienza más arriba en la flash. El lugar exacto depende de los fusibles del cargador de arranque.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X