Gestor de arranque Arduino


¿Puede alguien explicar cómo funciona el gestor de arranque Arduino? No estoy buscando una respuesta de alto nivel aquí, he leído el código y entiendo la esencia de la misma.

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 en última instancia resulta en una serie de instrucciones de ensamblaje en línea que auto-programan el flash con el programa que se transmite a través de la interfaz serie.

Lo que no tengo claro está en línea 270:

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

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

Seguramente, de alguna manera app_start necesita obtener un valor no NULO en algún momento para que todo esto se junte. No veo eso en el código del gestor de arranque... ¿está mágicamente vinculado por el programa que se carga por el gestor de arranque? Presumo que principal del gestor de arranque es el punto de entrada en el software después de un reinicio del chip.

Envuelto 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 quizás es algún conocimiento implícito que está siendo aprovechado por el IDE de Arduino? Todo lo que sé es que si alguien no cambia app_start para apuntar a otro lugar que no sea 0, el código del gestor de arranque solo giraría sobre sí mismo para siempre... entonces, ¿cuál es el truco?

Editar

Estoy interesado en intentar portar el gestor de arranque a un pequeño AVR que no tiene espacio de memoria separado para el código del gestor de arranque. A medida que se hace evidente para mí que el código del cargador de arranque se basa en ciertos ajustes de fusibles y soporte de chip, supongo que lo que realmente me interesa saber es lo que se necesita para portar el cargador de arranque a un chip que no tiene esos fusibles y soporte de hardware (pero todavía tiene capacidad de auto-programación)?

Author: vicatcu, 2010-09-06

2 answers

On NULL

La dirección 0 no hace un puntero nulo. Un "puntero nulo" es algo más abstracto: un valor especial que las funciones aplicables deberían reconocer como inválido. C dice que el valor especial es 0, y mientras que el lenguaje dice que la desreferenciación es "comportamiento indefinido", en el mundo simple de los microcontroladores generalmente tiene un efecto muy bien definido.

Cargadores de arranque ATmega

Normalmente, en el reinicio, el contador de programa (PC) del AVR se inicializa a 0, así el microcontrolador comienza a ejecutar código en la dirección 0.

Sin embargo, si se establece el Fusible de Reinicio de arranque ("BOOTRST"), el contador de programa se inicializa en una dirección de un bloque en el extremo superior de la memoria (donde eso depende de cómo se establecen los fusibles, consulte una hoja de datos (PDF, 7 MB) para más detalles). El código que comienza allí puede hacer cualquier cosa,si realmente lo desea, puede poner su propio programa allí si usa un ICSP (los cargadores de arranque generalmente no pueden sobrescribir a sí mismos).

A menudo, sin embargo, es un programa especial-un gestor de arranque - que es capaz de leer datos de una fuente externa (a menudo a través de UART, I2C, PUEDE, etc.) a reescribir el código del programa (almacenado en memoria interna o externa, dependiendo del micro). El gestor de arranque normalmente buscará un "evento especial" que literalmente puede ser cualquier cosa, pero para el desarrollo es más conveniente algo en el bus de datos que extraerá el nuevo código. (Para producción puede ser un nivel lógico especial en un pin, ya que se puede comprobar casi al instante.) Si el gestor de arranque ve el evento especial, puede entrar en el modo de arranque, donde reflasheará la memoria del programa, de lo contrario pasa el control al código de usuario.

Como un lado, el punto del fusible del gestor de arranque y el bloque de memoria superior es permitir el uso de un gestor de arranque con no modificaciones al software original (siempre y cuando no se extienda todo el camino hasta el dirección). En lugar de parpadear con solo el hexágono original y los fusibles deseados, uno puede parpadear el hexágono original, el cargador de arranque y los fusibles modificados, y presto, el cargador de arranque agregado.

De todos modos, en el caso del Arduino, que creo utiliza el protocolo del STK500 , intenta comunicarse a través del UART, y si no recibe respuesta en el tiempo asignado:

uint32_t count = 0;
while(!(UCSRA & _BV(RXC))) { // loops until a byte received
    count++;
    if (count > MAX_TIME_COUNT) // 4 seconds or whatever
        app_start();
}

O si se equivoca demasiado al obtener una respuesta inesperada:

if (++error_count == MAX_ERROR_COUNT)
    app_start();

Pasa el control volver al programa principal, ubicado en 0. En la fuente de Arduino vista anteriormente, esto se hace llamando a app_start();, definido como void (*app_start)(void) = 0x0000;.

Debido a que está formulado como una llamada a la función C, antes de que el PC pase a 0, empujará el valor actual de PC a la pila que también contiene otras variables utilizadas en el gestor de arranque (por ejemplo, count y error_count desde arriba). ¿Esto roba RAM de tu programa? Bueno, después de que el PC se establece en 0, las operaciones que se ejecutan descaradamente "violan" lo que una C adecuada función (que eventualmente volvería) debe hacer. Entre otros pasos de inicialización, restablece el puntero de la pila (borrando efectivamente la pila de llamadas y todas las variables locales), reclamando RAM. Las variables globales / estáticas se inicializan a 0, cuya dirección puede superponerse libremente con lo que el gestor de arranque estaba utilizando porque el gestor de arranque y los programas de usuario se compilaron de forma independiente.

Los únicos efectos duraderos del gestor de arranque son las modificaciones al hardware (periférico) registros, que un buen gestor de arranque no dejará en un estado perjudicial (encender periféricos que podrían desperdiciar energía cuando intenta dormir). En general, es una buena práctica inicializar completamente los periféricos que usará, por lo que incluso si el gestor de arranque hizo algo extraño, lo configurará como desee.

ATtiny Bootloaders

En ATtinys, como mencionaste, no hay lujo de los fusibles o memoria del gestor de arranque, por lo que tu código siempre comenzará en la dirección 0. Usted podría ser capaz de poner su gestor de arranque en algunas páginas más altas de memoria y apunte su vector de REINICIO hacia él, luego cada vez que reciba un nuevo archivo hexadecimal para flashear, tome el comando que está en la dirección 0:1, reemplácelo con la dirección del gestor de arranque, luego almacene la dirección reemplazada en otro lugar para llamar a la ejecución normal. (Si es un RJMP ("relative jump") el valor obviamente tendrá que ser recalculado)

 37
Author: Nick T,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-08 23:10:45

Editar

Estoy interesado en intentar portar el gestor de arranque a un pequeño AVR que no tiene espacio de memoria separado para el código del gestor de arranque. A medida que se hace evidente para mí que el código del cargador de arranque se basa en ciertos ajustes de fusibles y soporte de chip, supongo que lo que realmente me interesa saber es lo que se necesita para portar el cargador de arranque a un chip que no tiene esos fusibles y soporte de hardware (pero todavía tiene capacidad de auto-programación)?

Dependiendo de su objetivo final puede será más fácil crear su propio gestor de arranque en lugar de intentar portar uno. Realmente solo necesitas aprender algunos elementos para esa parte.

1) uart tx

2) uart rx

3) programación de flash automático

Que se puede aprender por separado y luego combinar en un gestor de arranque. Usted querrá una parte que se puede utilizar spi o lo que sea para escribir el flash, de modo que si su gestor de arranque no funciona o lo que la parte viene con se estropea todavía se puede continuar el desarrollo.

Ya sea que portes o hagas rodar el tuyo, todavía necesitarás entender esas tres cosas básicas con respecto a esa parte.

 1
Author: old_timer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-23 21:06:34