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

18 comentarios:

  1. amigo es posible que se borre el bootloader por error por ejemplo si mi programa es grande es decir que ocupe casi toda la flash incluyendo parte del bootloader ........ este se borra o esta protegido ???

    ResponderEliminar
  2. El bootloader puede escribir sobre toda la flash (incluyendo la parte de la flash donde éste se encuentra grabado). Si tu programa es muy grande podría malograr tu bootloader (en caso no se encuentre protegido). Lo puedes proteger con los fuses, esto lo debes hacer cuando grabas el bootloader. La protección del bootloader puede evitar que se use la instrucción STM en el área de booteo.
    Pero si tu programa no se escribe completo, a causa de que el bootloader se encuentra ocupando espacio necesario, no creo que funcione correctamente, esto ya que no se grabaran todas las instrucciones.
    Saludos.

    ResponderEliminar
  3. Hola , en el programa para el PC algunas veces falla en la barra de progreso al superar esta el 100%, es debido a que en algunas ocasiones se envian mas bytes por el serie de los que hay en "buf".Puede pasar que al enviar tenga que añadir alguna cabecera que no esta en buf.

    Las modificaciones que he hecho son:

    1 - Al final de "private int Pagina()"

    // return n;
    return index + offset; // Devuelve la posicion en buf.

    2 - En "private void BtnDescarga_Click(object sender, EventArgs e)"
    stado = Pagina();
    // Ahora stado devuelve la posicion en el buffer "buf" y no
    // la cantidad de bytes enviados por serie.
    // Cuando stado vale 0x00 ya hemos terminado.
    // suma += (stado - 1); ;
    //porc=Math.Round((100*suma)/(lineas));
    if (stado != 0x00) {
    porc = Math.Round((100 * stado) / (lineas));
    LblPc.Text = porc.ToString() + "%";
    }

    Aun ando probando asi que no se si la solucion es buena 100%

    Buen trabajo Jonathan

    ResponderEliminar
    Respuestas
    1. Que bueno que modifiques y mejores el programa, Te felicito... buen trabajo !!!

      Eliminar
  4. Puedo aplicar el programa para un celular?

    ResponderEliminar
    Respuestas
    1. Si tu celular tiene algún tipo de puerto serie... Yo creo que si se puede.... Claro, adecuando el lenguaje.

      Eliminar
  5. Gracias por hacerme la vida más sencilla...

    ResponderEliminar
  6. Hola podrías subir nuevamente el código fuente del bootloader pues a desaparecido del servidor. Te consulto esta comentado estoy recién aprendiendo a programar en C para avr y me gustaría mucho mirar este tipo de programa. Desde ya gracias

    ResponderEliminar
    Respuestas
    1. Estimado.
      He revisado y todos los enlaces se encuentran activos, tienes que tener cuenta en 4shared para poder ingresar.
      Saludos.

      Eliminar
  7. buenas noches estoy retornando a estos medios voy aprobar los programas con una Atmega 128 y un Receptor Dish DP301-015 POR FAVOR SI HAY CAMBIOS ENVIENME COMENTARIOS A ESTA DIRECCION mcgguiver2009@outlook.com

    ResponderEliminar
  8. quien me puede ayudar con los programas para programar Atmega 128 EFA

    ResponderEliminar
  9. tengo un programador por el puerto LPT-1, O SEA PUERTO DE IMPRESORA Y NO ES PODIDO ENCONTRAR LOS DRIVERS PARA LA aATMEGA 128 Y EL PROGRAMADOR

    ResponderEliminar
  10. ¿cómo puedo adaptar el programa para trabajar con Atmega2560? ¿No me puede ayudar?

    ResponderEliminar
  11. Buenas noches Jonathan, me parece fantastico tu programa y tus conocimientos del tema. Me podrias decir si el bootloadetr y el programa sirven para un 328P?
    Gracias Mario

    ResponderEliminar
    Respuestas
    1. Básicamente debería funcionar con cualquier AVR8. Quizá tengas que cambiar algún nombre de registro.

      Eliminar
  12. Muchas gracias, voy a intentarlo.

    ResponderEliminar