library icsp how atmega328 8mhz arduino avr bootloader

icsp - Arduino Bootloader



install arduino bootloader (2)

En nulo

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

Cargadores de arranque de mega

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

Sin embargo, si el Fusible de reinicio de arranque ("BOOTRST") está configurado, el contador del programa se inicializa en una dirección de un bloque en el extremo superior de la memoria (donde depende de cómo se configuren los fusibles, vea una hoja de datos ( PDF, 7 MB) para detalles). El código que comienza allí puede hacer cualquier cosa: si realmente quisiera, podría poner su propio programa allí si usa un ICSP (los cargadores de arranque generalmente no pueden sobrescribirse a sí mismos).

A menudo, sin embargo, es un programa especial, un gestor de arranque , que puede leer datos de una fuente externa (a menudo a través de UART, I 2 C, CAN, etc.) para reescribir el código del programa (almacenado en la memoria interna o externa, dependiendo de la 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 desde el que extraerá el nuevo código. (Para la producción, puede ser un nivel lógico especial en un pin, ya que puede verificarse casi instantáneamente). Si el cargador de arranque ve el evento especial, puede ingresar al modo de carga de arranque, donde volverá a flashear la memoria del programa, de lo contrario, pasará el control. fuera de código de usuario.

Como punto aparte, el punto del fusible del cargador de arranque y el bloque de memoria superior es permitir el uso de un cargador de arranque sin modificaciones al software original (siempre que no se extienda hasta la dirección del cargador de arranque). En lugar de destellar solo con el HEX original y los fusibles deseados, se puede actualizar el HEX original, el cargador de arranque y los fusibles modificados, y listo, el cargador de arranque agregado.

De todos modos, en el caso del Arduino, que creo que usa 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 al programa principal, ubicado en 0. En la fuente de Arduino que se vio anteriormente, esto se hace llamando a app_start(); , definido como void (*app_start)(void) = 0x0000; .

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

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

Cargadores de botas ATtiny

En ATtinys, como mencionó, no hay ningún lujo de los fusibles o la memoria del cargador de arranque, por lo que su código siempre comenzará en la dirección 0. Es posible que pueda colocar su cargador de arranque en algunas páginas superiores de memoria y apuntar su vector RESET hacia ella. luego, cada vez que reciba un nuevo archivo hexadecimal con el que flashear, tome el comando que está en la dirección 0: 1, reemplácelo con la dirección del cargador de arranque, luego almacene la dirección reemplazada en otro lugar para solicitar la ejecución normal. (Si se trata de un RJMP ("salto relativo "), obviamente el valor deberá ser recalculado)

¿Alguien puede 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 lo esencial.

Existe una gran cantidad 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 da como resultado una serie de instrucciones de ensamblaje en línea que programan automáticamente el flash con el programa que se transmite a través de la interfaz en serie.

Lo que no tengo claro está en la 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 cargador de arranque está destinado a delegar en la ejecución del código cargado por el usuario.

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

Envuelto en las aproximadamente 70 líneas de ensamblaje debe ser el anillo de decodificador secreto que le dice al programa principal dónde está realmente app_start? ¿O tal vez es un conocimiento implícito 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 cargador de arranque solo girará sobre sí mismo para siempre ... ¿cuál es el truco?

Editar

Estoy interesado en intentar portar el cargador de arranque a un AVR Tiny que no tiene espacio de memoria separado para el código del cargador de arranque. Cuando me doy cuenta de que el código del cargador de arranque se basa en ciertas configuraciones de fusibles y soporte de chip, creo que lo que realmente me interesa saber es qué se necesita para trasladar el cargador de arranque a un chip que no tenga esos fusibles y hardware. apoyo (pero todavía tiene capacidad de auto-programación)?


Editar

Estoy interesado en intentar portar el cargador de arranque a un AVR Tiny que no tiene espacio de memoria separado para el código del cargador de arranque. Cuando me doy cuenta de que el código del cargador de arranque se basa en ciertas configuraciones de fusibles y soporte de chip, creo que lo que realmente me interesa saber es qué se necesita para trasladar el cargador de arranque a un chip que no tenga esos fusibles y hardware. apoyo (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 portear 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. Querrá una parte que pueda usar spi o lo que sea para escribir el flash, de modo que si su gestor de arranque no funciona o lo que sea que la parte vino se estropee, aún puede continuar con el desarrollo.

Ya sea que transfiera o ruede el suyo, todavía necesitará entender esas tres cosas básicas con respecto a esa parte.