Mostrando entradas con la etiqueta Boot Loader. Mostrar todas las entradas
Mostrando entradas con la etiqueta Boot Loader. Mostrar todas las entradas

viernes, 11 de marzo de 2016

Bootloader USBasp


Ya muchos conocemos el programador USBasp (gracias a Thomas Fischl) y lo bien que funciona este. El USBasp debe ser uno de los programadores mas conocidos para descargar código a un ATmega, esto gracias a que usa un muy económico ATmega8, que aun no teniendo puerto USB, es capaz de trabajar con una gran cantidad de dispositivos. … y lo mejor de todo: “Es gratis”.
Personalmente lo vengo usando desde el año 2010. Ahora tengo un AVRISPmk2(al parecer ya descontinuado) y un JTAGICE3 (que ya fue remplazado por el Atmel-ICE) y aún en algunas ocasiones uso mi USBasp.

Bueno, es este post mostraré cómo usar el “USBasp“  como bootloader.

Un programador USBasp consta básicamente de un ATmega8 que ha sido programado, en la sección de aplicación de su flash, con un código que permite comunicación USB (low speed 1.5Mbps) con el programador y programar otros uCs. Los anteriormente descrito se muestra en la figura 1, donde la sección de booteo del uC (ATmega8) no es usada.
 
Figura 1.image
 

Pero cuando hablamos de usar el “USBasp” cómo bootloader tendremos un esquema similar a la figura 2. Aquí, el código, “USBasp” , que realizará la comunicación con el programa en la PC (ej. AVRDUDE) es localizado en la sección de booteo de la flash, y es este código el que nos permite poner nuestra aplicación en la sección de aplicación de la flash (usando instrucciones SPM y LPM).
Es decir que no necesitaremos un programador USBasp ya que este lo tendremos integrado en el mismo uC. Lo mejor de todo es que lo podemos poner un diferentes uCs y con diferentes osciladores. Personalmente ya lo he probado con ATmega8 (a 12 y 16MHz), ATmega32(a 12 y 16MHz) y ATmega324P (a 12,16 y 20 MHz).
 
Figura 2.image
 
El hardware necesario los muestro en la figura 3. Aquí se debe tener algunas consideraciones tales como.
  • D+ debe necesariamente ir conectado al pin INT0.
  • D- puede ser cualquier pin del puerto D.
  • El jumper para iniciar el bootloader puede ser cualquier pin.

Figura 3.
image
 

En la figura 4 se muestra el diagrama del flujo del bootloader.
Despues de un reset se inicia en bootloader y este se ejecutara sí:
  • La fuente de reset es externa (MCUCSR & (1 <<  EXTRF)).
  • Si el jumper esta colocado ((PINB & (1 << JUMPER_BIT)) == 0).
En otras palabras, para ejecutar el bootloader hay que colocar el jumper y presionar el boton de reset.
Para salir del bootloader sólo hay que quitar el jumper.
 
    Figura 4.image
     

    Antes de programar el bootoalder debemos debemos modificar los siguientes fuses.
    • En High Fuse debemos seleccionar una de las secciones que tengan como mínimo 1024 words (2048 bytes) ya que el bootloader ocupa más de 1900 bytes. También debemos seleccionar “Boot Reset Enable” para que el programa inicie en la sección de booteo y no en la de aplicación. Para ATmega8 recomiendo 0xC8.
    • En Low Fuses debemos seleccionar alguna de las opciones Ext. Crystal/Resonator High Freq. Para un ATmega8 recomiendo 0xFF.



    Figura 5.
    image
     
    En la figura 6 se muestra el mapa de memoria de la sección de booteo de un ATmega8. Como ya se dijo antes, de esta usaremos mas de 1900 bytes, por ello en los fuses se seleccionará la mayor área.
     
    Figura 6.image

    SOFTWARE


    El código original lo pueden encontrar en el siguiente enlace link.
    Aquí les dejo el proyecto en ATMEL STUDIO 7 USBasp-boot. El proyecto esta configurado para un ATmega8 a 12MHz, pero puede ser cambiado facilmente a otros dispositivos.
    Las modificaciones necesarias para usarlo con otros dispositivos son las siguientes:
    • Sí se quiere usar otras frecuencias de oscilador debemos hacer el cambio en Toolchain>Symbols. Las frecuencia pueden ser de 12,15,16,18 y 20 MHz. En las figuras 7 y 8 se muestran los lugares donde se deben realizar los cambios de frecuencia.



    Figura 7.
    image



    Figura 8.
    image
     
    También debemos decirle al compilador que el código generado debe iniciar en el sección de booteo seleccionada en los High Fuses. En el ejemplo de la figura 5 se selecciono “Boot start address=0x0C00” donde 0xC00 es la dirección, en words, de inicio de la sección de booteo.
    Tenemos dos formas de reasignar el inicio del código:
    En la figura 9 se hace la reasignación usando el inicio de la dirección en words (0x0C00).
    En la figura 10 se hace la reasignación usando el inicio de la dirección en bytes (0x1800).
    Nosotros debemos seleccionar sóla una de las dos formas (Figura 9 o 10).
    Hay que tener en cuenta que 0x0C00 words = 0x1800 bytes.
     
    Figura 9.image
     
    Figura 10.image
     

    En la figura 11 se muestra parte del código generado. Aquí vemos que el inicio es en la dirección 0x1080 (para 2014 bytes). Cuando el código generado es para la sección de aplicación la dirección de inicio es 0x0000.
     
    Figura 11.image
     

    En la figura 12 se indica que el se usará PD3 para conectar D- del USB. Esto lo podemos cambiar a algún otro pin en el mismo puerto.
     
    Figura 12.image
     

    En la figura 13 se indica el pin que se usará para el jumper de inicio del bootloader. Este puede ser cualquier pin que no se esté usando.
     
    Figura 13.image


    En la figura 14 se activa la resistencia pull up correspondiente al pin del jumper.
     
    Figura 14.image
     

    En la figura 15 se evalúa la condición para permanecer o salir del área de booteo.
     
    Figura 15.image


    En los caso de la figura 14 y 15 se pueden usar el pin y el puerto que se deseé.
    Si el ATmega que queremos usar  no se encontrase en la lista de la figura 16 corresponde agregarlo con sus respectivos “SIGNATURE BYTES”.
     
    Figura 16.image
     

    El proyecto es para un ATmega8, cómo cambiamos de dispositivo ?
     
    • Damos click en l icono         image
    • Click en “Change Device…”    image
    • Seleccionamos el nuevo dispositivo.    image
    • Ya habremos cambiado nuestro nuevo dispositivo. image
    • Luego sólo queda compilar y tendremos el .hex del bootloader para poder programarlo.
    Finalmente, y cuando el bootolader se encuentre instalado, podremos usar programas como SinaProg para descargar nuestra aplicación sin afectar el bootloader.
    hay que resaltar que el bootloader no permite hacer cambio de los fuses.
    En resumen:
    1. Preparar el hardware (figura 3).
    2. Con un programador cualquiera cambiar los fuses del uC (figura 5).
    3. Hacer los cambios en el software, sólo si son requeridos: F_CPU (figuras 7 y 8), .text (figura 9 ó 10), D- (figura 12), JUMPER_BIT (figura 13), PORT/PIN JUMPER (figuras 14 y 15).
    4. Agregar un nuevo uC si falta (figura 16).

    Espero que esto les sea de utilidad, ya que no necesitar un programador puede ser muy útil.




    sábado, 1 de octubre de 2011

    Boot Loader en ATmega

    Primero un saludo a mis lectores, hace mucho que no escribo.

    En este post hablare del bootloader y les daré el código para que ustedes puedan usarlo y editarlo a voluntad.

    ¿Qué es un bootloader?
    En el mundo de los uC un bootloader es un pequeño programa que grabado previamente en un área especial de la flash, la zona o área de booteo, nos permitirá la actualización de la flash.  Es decir que una vez que el uC tiene el bootloader ya no necesitarás un programador para volver a actualizar tus aplicaciones.
    Esta zona de booteo se encuentra siempre al final de la flash, y su tamaño puede variar entre 4 valores (que dependerán del tamaño de la flash). La elección del tamaño de ésta área se debe realizar en los fuses como se muestra en la siguiente figura.


    boot


    Se puede ver que se definen dos áreas, la de Aplicación y la de Booteo. En la sección de aplicación es donde normalmente colocamos nuestro código (inicia en la dirección 0x0000 de la flash).

    Todos los periféricos funcionan igual en las dos áreas, pero en el área de booteo sí se puede usar la instrucción SPM (SPM - Store Program Memory). Esta instrucción es la que nos permitirá modificar la flash.
    La flash esta dividida en páginas (el tamaño de la página dependerá del uC), por ejemplo un ATmega8 tiene 128 página y cada página es de 32 palabras ó 64 bytes, esto es 128*64 =8KB de flash.
    Un ATmega128 tiene (512 páginas)*(256 bytes/página)=128KB.
    Todos esos números los encuentran en las hojas de datos.

    La programación de la flash se realiza página a página y hay dos métodos para hacerlo, el método que uso yo, y que es el método que se encuentra en el ejemplo de las hojas de datos, consiste en borrar la página, poner los bytes correspondientes a esa página en el buffer de la flash y ejecutar el comando de programación… esto es algo que se debe repetir para cada página.

    El bootloader puede recibir los datos para la programación por cualquier medio que le sea posible(UART, SPI, I2C, USB, ETHERNET…etc), éste bootloader lo realiza por el UART.

    El funcionamiento del programa es el siguiente:
    1. El programa testea un pin del uC,
    1.1  si es ‘1’ salta a la dirección cero de la flash y ejecutará nuestra aplicación ( si ésta existe).
    1.2  si es ‘0’ se inicia la ejecución de bootloader.
    2.      El programa configura el uart. F_CPU y BAUD pueden ser cambiados y adecuados a las necesidades de cada persona.
    3.      Luego espera todos los datos de una página.
    4.      Entre los datos se encuentra la dirección de la página a grabar, con este dato se borra la página correspondiente, se llena el buffer de la flash con los datos (que no son otra cosa que las instrucciones de nuestra aplicación) y por último se ejecuta el comando para programar.
    El programa puede ser adaptado fácilmente a otros uC’s, esto ya que las macros ayudan mucho al momento de realizar las operaciones con los registros.

    ¿Y cómo envío por el uart el bendito código de mi programa ?

    Para esto desarrollé un pequeño programa en visual C#.


    programa


    El programa es muy sencillo de manejar, solamente hay que buscar el firmware de nuestra aplicación, buscar el puerto por lo cual descargaremos, seleccionar la velocidad (debe ser igual a BAUD del bootloader), seleccionar el dispositivo y por ultimo dar click en el botón “Program”.
    En este caso no les puedo poner una simulación en proteus ya que éste no soporta la característica de auto-programación.

    El bootloader no ocupa mucho espacio de la flash, es por ello que el inicio de código lo hago en FIRSTBOOTSTART. FIRSTBOOTSTART es un número que cambia con cada uC, su valor lo pueden encontrar en el archivo “m#def.inc” de cada uC.

    Cuando programen el bootloader los fuses deben incluir: BOOTZS =11 y BOOTRST=0 . Lo primero es para que el área de booteo sea la menor y lo segundo le indicará que después de cada reset inicie en la dirección de booteo indicada (en este caso iniciará en la dirección FIRSTBOOTSTART).
    Luego ya no necesitarán llevar su programador a todas partes… basta con usar el puerto serie para realizar esta actualización.

    Espero esto les ayude… también espero sus comentario para la mejora del programa.
    El código fuente lo pueden descargar aquí: BOOT_JRSF
    El programa en C"# : BOOT_Downloader … si no pueden abrirlo quizá necesiten instalar el netframework 3.5.
    Si alguien quiere el código fuente del programa hecho en C# aquí lo tiene : BOOT …. Esta demás decir que deben tener instalado Visual Studio 2008 para abrir esto, o por lo menos Visual C# 2008 Express.

    ver: USBasp bootloader