• Autor de la entrada:
  • Tiempo de lectura:9 minutos de lectura

Integrar un bootloader en un PIC de 8-bit y MCC Classic debería ser una tarea sencilla, pero presenta algunos problemas que se cubrirán en esta entrada.

Introducción

Los bootloader alargan el ciclo de vida de una solución al facilitar actualizaciones de firmware.

Concepto de solución con bootloader
Concepto de solución con bootloader

La idea del bootloader es simple: capacidad de auto-programarse. Casi parece histórico el hardware donde era absolutamente obligatorio conectar un programador o sustituir memorias para actualizar firmware (aunque aún está más presente de lo que Arduino® nos ha hecho creer).

Mientras algunas tecnologías implementan algún bootloader mediante hardware, como Infineon® o Texas Instruments®, en otras ocasiones será el usuario quien lo tenga que implementar mediante software. Este último es el caso de los PIC de 8 bit de Microchip®.

Esta entrada es un How-to práctico donde al final se tendrá una base para una solución con un PIC de 8-bit y bootloader mediante UART.

Soporte de Microchip® al bootloader del MCC Classic

Toda la información y software de partida se encuentra en: Microchip®: 8-bit Bootloader.

El plugin MCC Classic debería facilitar esta integración, y aunque lo hace, lo cierto es que presenta problemas desde prácticamente su lanzamiento. La última actualización de esta librería es del 2016, por lo que se intuye que Microchip® habría dejado de dar soporte a esta librería (si es que alguna vez lo tuvo).

Librerías mínimas para implementar un Bootloader en PIC 8-bit y MCC
Librerías mínimas para implementar un Bootloader en PIC 8-bit y MCC

Creación del bootloader

Crear un Standalone Project y abrir el MCC, para este tutorial se utilizará el PIC16F1825. Aquí se podrá encontrar el primer warning con las últimas versiones de MPLAB (6.05) y MCC (5.2.2) que existen.

MCC Library Update Warning
MCC Library Update Warning

Este aviso no tiene que ver con el bootloader, ignorarlo pulsando cualquiera de las opciones. En las siguientes ventanas seleccionar MCC Classic. Debido al warning anterior el proyecto comienza con un recordatorio del mismo, aunque pueda ignorarse es cierto que cosas así menoscaban la reputación de cualquier compañía.

WARNING: Some MCC Classic GUIs may not display correctly in MPLAB X 6.05/MCC 5.2.x.
Warning MCC Classic MPLAB X 6.05/MCC 5.2.x.

Antes de continuar con el PIC bootloader 8-bit y MCC se debe configurar el reloj, esto es algo particular de cada implementación y no se entra en detalle. Simplemente y como curiosidad se utiliza el reloj interno de 8MHz y el PLL x4 para conseguir una frecuencia de 32MHz.

Configuración del bootlaoder PIC 8-bit en MCC Classic

Agregar las siguientes librerías al proyecto

Librerías mínimas para implementar un Bootloader en PIC 8-bit y MCC
Librerías mínimas para implementar un Bootloader en PIC 8-bit y MCC
  • EUSART: Elegir una configuración lo más simple posible, las interrupciones no serán necesarias
  • MEMORY: Añadir las rutinas DataEE si queremos que el bootloader pueda manipular la EEPROM (si el PIC disposueira de ella)
  • Bootloader Generator:

Existen varias posibilidades, por ahora se busca que la implementación sea lo menos intrusiva posible, sin gastar pines del PIC, protección de software, etc.

User defined options bootloader en PIC 8-bit y MCC
User defined bootload options

En este punto aparecen los siguientes Warning, los cuales de nuevo no tienen mucho sentido y deben ignorarse.

Warnings en MCC al implementar el bootloader en PIC 8-bit y MCC
Warnings en MCC al implementar el bootloader

Nota: Es importante que en el apartado del MCC Pin module se active la opción Start High, en ocasiones aparecerá un warning advirtiendo esto, pero otras veces no.

Una vez configuradas las librerías generar el código mediante el MCC Classic.

Configurar el linker del proyecto bootloader

Esta es una acción necesaria a futuro, para evitar errores en el linkado del archivo de producción.

  1. Abrir las propiedades del proyecto
  2. Configurar en XC8 Linker el ROM ranges del menú Memory Model a 0-2ff
  3. En Manage Configurations… renombrar la configuración a «With_Configurations»
  4. Duplicar la configuración y renombrarla a «No_Configurations»
  5. En XC8 Compiler de «No_configurations» crear la macro OMIT_CONFIGURATIONS
  6. Desmarcar la opción Program the device with default config words
  7. Crear las directivas de compilación condicional en «device_config.c» o donde se hayan generado los #pragma de los fusibles de configuración

Creando un proyecto con bootloader

Mediante un proyecto sencillo tipo «Hola mundo» se muestra cómo interactuar con el bootloader en una aplicación real.

Se crea un Standalone Project, para este ejemplo la aplicación enviará mediante UART un «Hola bootloader APP» al iniciar y posteriormente el valor de una variable que se incrementará o decrementará cada segundo. Sin embargo, lo que haga la aplicación a priori no es relevante para integrarse con el bootloader.

void main(void){
    // Initialize the device
    SYSTEM_Initialize();
    INTERRUPT_GlobalInterruptEnable();
    INTERRUPT_PeripheralInterruptEnable();
    __delay_ms(200);
    printf("\r\nHola Bootloader APP\r\n");

    uint16_t i = 0;
    
    while (1){
#ifdef OFFSET
        printf("%05d\r", i++);
#else
        printf("%05d\r", i--);
#endif
        if(EUSART_is_rx_ready()){
            switch(EUSART_Read()){
                case 'F':       //Si recive una 'F'
                                //lanza el bootloader
                    printf("\r\nGO");
                    uint16_t    Buf[ERASE_FLASH_BLOCKSIZE];
                    FLASH_WriteWord(0x300, Buf, 0x3FFF);
                    NOP();
                    NOP();
                    RESET();
                    break;
                default:
                    break;
            }
        }
        __delay_ms(1000);
    }
}

Al incluir compilación condicional es posible generar distintos binarios en función de la configuración utilizada, para que esto funcione es obligatorio añadir la macro OFFSET tal como se hizo anteriormente para las Config Word.

Por otro lado la forma de lanzar el bootloader en el PIC es que reciba ‘F’ en la UART.

Configurar linker de la aplicación final

Para que el proyecto sea práctico en la fase de desarrollo deberían crearse tres configuraciones, tal y como recomienda la propia Microchip®. Aquí se usarán las mismas nomenclaturas:

Configuraciones de compilación y linkado en integración bootloader y aplicación final
Configuraciones de compilación y linkado en integración bootloader y aplicación final

Standalone

Cuando sea necesario depurar la aplicación principal será más sencillo sin la interacción del bootloader. Con esta configuración se trabajará únicamente en la aplicación principal y no existirá el bootloader.

Offset

Con esta configuración se generará el archivo para ser cargado por el bootloader. Se utilizará cuando sea necesario actualizar el firmware sin conectar el programador.

Offset en memoria de la aplicación final
Offset en memoria de la aplicación final

Esta configuración también es necesario realizarla en el siguiente caso.

Combined

Al finalizar del desarrollo de la aplicación se necesitará un archivo de producción que incluya la aplicación final y el bootloader. Para conseguirlo debe combinarse en un único archivo el proyecto del bootloader y el de la aplicación final. En el apartado Loading debe introducirse

Integración de bootloader y la aplicación final
Integración de bootloader y la aplicación final

Error fusionando proyectos. (1600) data in (…) conflicts with existing data at address

Si has seguido el User’s Guide de Microchip® al pie de la letra tendrás un mensaje de error en el linkado como el siguiente:

(1600) «../Bootloader16F1825.X/dist/No_Configurations/production/Bootloader16F1825.X.production.hex» argument : data in «../Bootloader16F1825.X/dist/No_Configurations/production/Bootloader16F1825.X.production.hex» conflicts with existing data at address 0x1000E

El error es provocado por el argumento que se pasa por defecto al linker -mdefault-config-bits, el cual debe desaparecer para que no entre en conflicto con las config word de la aplicación final.

Probando el bootloader

La aplicación Host se puede crear estudiando el protocolo del bootloader e integrarse en cualquier software vinculado a la solución. Por otro lado, Microchip® provee una aplicación en Java que ya hace esto: UnifiedHost-1.19.0.

Ubicación de descarga del Bootloader Host App de Microchip
Ubicación de descarga del Bootloader Host App de Microchip

Descargar la que especifica (MCC Classic), ya que la otra da errores con el bootloader de 8-bit.

Bootloader Host App configurado para bootloader en PIC 8-bit y MCC
Bootloader Host App configurado para PIC 8-bit

Es una aplicación de escritorio bastante intuitiva que dispone de una consola para ver información relevante.

Bootloader Offset (Byte Address): Los PIC16 son word-oriented, mientras que los archivos Intel-HEX son byte-oriented, se debe tener en cuenta para configurar las direcciones de inicio. Como en este caso, si se ha configurado la librería para que el offset se encuentre en 0x300, habrá que multiplicar por 2 las direcciones del Intel-HEX para relativizarlas al PIC.

Cargar únicamente el bootloader en el microcontrolador

El proyecto del bootloader y la configuración: With Configurations sirve para generar un firmware de preproducción. Con esto el PIC se quedará esperando a que un Host envíe la aplicación, lo cual es interesante si es necesario lanzar la fabricación del hardware mientras se trabaja en el software.

Cuando la aplicación final esté lista, basta con abrir el .hex generado mediante la configuración Offset y que el bootloader lo programe en el PIC.

Offset Firmware para cargar mediante el bootloader
Offset Firmware para cargar mediante el bootloader

Failure Hint UnifiedHost

Es posible que en la consola se vean varios Failure Hint, es algo que puede ignorarse siempre que aparezca el mensaje: FULL Bootloader SUCCESSFUL.

Failure Hint de la App de Microchip
Failure Hint de la App de Microchip

Este aviso apareció a partir de alguna actualización, por ejemplo no aparecerá usando el UnifiedHost-0.1.14. Es posible que simplemente se haya modificado el tipo de mensajes que aparecen con el .level = FINEST en archivo logging.properties de la aplicación.

El archivo de producción

Es el firmware con bootloader y aplicación final integradas para cargar en el PIC. Si en el futuro es necesaria una actualización bastará utilizar el bootloader sin tener que conectar un programador, es lo que se conoce como firmware de producción.

La verificación se hace cargando un archivo de producción (contaje hacia atrás) y mediante el bootloader se actualiza el código (contaje hacia delante).

Error compilando y linkando Bootloader en PIC 8-bit y MCC con la opción free

Una de las sorpresas más desagradables utilizando la librería Bootloader de Microchip® es el gasto en espacio de programa. Algo sorprendente es que a día de hoy no será posible seguir el User Guide oficial sin comprar la licencia del compilador XC8.

Comparación uso de memoria del bootloader en PIC 8-bit y MCC
Comparación uso de memoria del bootloader en PIC 8-bit y MCC

En la imagen anterior se muestra el espacio utilizado por el bootloader en función del optimizador respecto a toda la memoria del PIC16F1825. De izquierda a derecha: sin optimizar, nivel 2 y priorizando espacio.

Si no se dispone del optimizador, una opción es aumentar el rango del Linker en Memory Model, al final este rango tiene el objetivo de que el firmware del bootloader esté contenido, avisando en caso contrario. ¿Cuánto aumentarlo? Lo mínimo posible.

Utilizando la configuración «With configurations» del proyecto del bootloader, se puede eliminar el rango del Linker en Memory Model y observar cuánto espacio consume. La imagen anterior muestra que sin optimización el bootloader necesita 0x38D words, por tanto podría configurarse el rango 0-400. Recordar modificar en la aplicación Host el Bootloader Offset a 0x800.

Distintas Word Configuration en bootloader y aplicación final

Dependiendo del PIC puede ser necesario prever las Word Configuration desde la concepción misma del bootloader. No todo se puede cambiar en tiempo de ejecución o, como diría algún Gestor fanático de los FaultyProject: «Eso se trabajará en post-producción».