Firmware

20/12/2021

# Introducción

En este documento vamos a introducir el concepto de firmware. PiConsole como sabemos está basada en un microcontrolador, lo que entre otras cosas significa que no dispone de grandes recursos en cuestión de memoria y capacidad de proceso. Por este motivo no va a ser posible utilizar una arquitectura de software pesada como la que habitualmente se relaciona con el concepto de sistema operativo. En este caso vamos a hablar más bien del concepto de firmware, que suele referirse a un programa que se instala en la memoria interna del microcontrolador y que contiene las instrucciones justas y necesarias para que éste desempeñe la función que nos interesa. Esta función suele ser la de controlar algún proceso físico, como gestionar los motores de un robot, la apertura de una puerta automática o la medición de varios sensores para almacenar sus medidas o controlar algún tipo de mecanismo. En nuestro caso, dados los elementos que hemos dispuesto alrededor del microcontrolador Pico y de la forma que hemos dado a PiConsole, lo habitual será que el firmware implemente algún tipo de videojuego, aunque no estamos limitados en absoluto a esta función.

# Flasheo de firmware en Raspberry Pi Pico

Al proceso de escritura o grabación de un determinado firmware en la memoria interna estática (es decir que no pierde su contenido cuando se desconecta la alimentación) se le denomina flasheo. El término procede de que uno de los tipos de memoria utilizados para mantener el firmware en los microcontroladores es la memoria flash (opens new window).

En los microcontroladores suele ser habitual que se disponga un puerto especial para facilitar su programación sin la necesidad de extraer el chip programable del mismo para flashear un firmware con un programador (opens new window) especial. Este puerto se suele llamar ISP o ICSP (opens new window). La llegada de Arduino cambió esta situación, al incorporar un segundo microcontrolador en la placa que se ocupaba de programar el microcontrolador principal desde un PC a través de un simple puerto USB.

En la foto anterior podemos ver el microcontrolador principal ATMega328 (el alargado en la parte inferior izquierda) junto a su puerto ICSP de programación tradicional. También encontramos el microcontrolador secundario especializado en la programación del primero desde el puerto USB ATMega16U2 (el cuadrado en la parte superior derecha) junto a su puerto ICSP.

Raspberry Pi Pico ha cambiado un poco la forma de programar el microcontrolador, pero sus diseñadores también se han preocupado de que se pueda hacer fácilmente a través de un puerto USB. En este caso todo el trabajo lo hace el mismo microcontrolador (el chip RP2040), ahorrándose costes. Además el firmware que se encarga de la comunicación USB se encuentra en el propio chip y no puede ser modificado, por lo que no se pueden producir problemas (brickeos) como sí puede ocurrir en Arduino si por algún motivo se altera el firmware del microcontrolador ATMega16U2 (opens new window) secundario.

El procedimiento para flashear un nuevo firmware en Raspberry Pi Pico consiste en conectar la placa con el cable microUSB al PC mientras se mantiene pulsada la tecla BOOTSEL que se señala en la siguiente imagen.

En PiConsole esta tecla está accesible a través de un agujero hecho en la carcasa.

Cuando conectamos el cable USB mientras pulsamos BOOTSEL, en el PC se monta una unidad extraíble de nombre RPI-RP2. La extensión de un firmware compilado para Raspberry Pi Pico es .uf2. Más adelante se ofrecerán distintos firmwares, sobre todo con algunos videojuegos, pero para flashear por primera vez, se recomienda descargar el siguiente que implementa un test de los controles y sensores instalados en PiConsole:

Si copiamos el fichero .uf2 descargado a la unidad extraíble, veremos cómo PiConsole se reinicia y se desmonta la unidad. A partir de entonces, si todo ha ido bien, nuestra PiConsole estará flasheada con el programa de test y veremos lo siguiente en pantalla tras la aparición durante un par de segundos del logo de Adafruit:

Los controles de este firmware son los siguientes:

  • Arriba => Enciende LED IR (visualizarlo a través de la cámara de un teléfono móvil)
  • Izquierda => Enciende LED rojo
  • Derecha => Enciende LED amarillo
  • Abajo => Enciende LED verde
  • Controles A y B => Hace sonar el buzzer
  • Potenciómetro => Controla barra superior en pantalla
  • Fotorresistencia LDR => Controla barra inferior en pantalla

El funcionamiento de la propia pantalla se prueba si vemos las dos barras controladas por Potenciómetro y LDR.

# Colección de firmwares

Hemos reunido una colección de firmwares, la mayoría de ellos videojuegos, que hemos subido al siguiente repositorio Github y al que incorporaremos más en el futuro:

En el archivo README (opens new window) del propio repositorio se encuentra el directorio de su contenido, con una descripción de los tipos de firmware que encontraremos, la lista de controles y en caso de existir, la localización del código fuente original para su consulta (hay que tener en cuenta que la mayoría han sido adaptados para ser ejecutados en PiConsole, por lo que deberemos utilizar las versiones que hay en nuestro repositorio (opens new window)). Aquí vamos a centrarnos en explicar los dos tipos de firmware que hay en el repositorio.

# Firmware tipo MicroPython

MicroPython fue la primera implementación de un intérprete de Python 3 para microcontroladores. No es que sea oficial, pero se puede considerar la implementación principal de la comunidad. Es un compilador completo y un motor e intérprete en tiempo real. Al usuario se le presenta una línea de comando interactiva (el REPL (opens new window)) para que pueda ejecutar directamente órdenes Python de la misma forma que el intérprete interactivo de una instalación Python normal de PC. Incluye también una selección de librerías fundamentales de Python. En esta página (opens new window) podemos consultar la documentación general y la específica de la implementación para Raspberry Pi Pico.

Cualquier firmware en Raspberry Pi Pico se almacena, no en el encapsulado del propio microcontrolador como suele ser habitual, sino en una memora externa de tipo Flash de 2MB de capacidad. Es el pequeño chip que hay encima y a la izquierda del procesador principal en la siguiente foto:

Para ejecutar todos los programas del repositorio (opens new window) en los que se indica MicroPython como valor de Entorno, será necesario realizar los siguientes dos pasos en secuencia:

  1. Flashear el firmware que contiene el intérprete de MicroPython que puede descargarse desde este sitio (opens new window). El procedimiento será el mismo que hemos descrito en el apartado Flasheo de firmware en Raspberry Pi Pico.
  2. Una vez flasheado el firmware anterior, parte del espacio disponible en la memoria Flash de Pico se convertirá en un sistema de archivos en el que almacenaremos todo el código Python (ficheros .py) que queramos mientras haya espacio. Para acceder a este espacio de almacenamiento hay que utilizar programas compatibles como Thumby IDE (opens new window) o los dos descritos en la siguiente unidad didáctica que trata sobre los IDEs. En estas unidades didácticas, como veremos, vamos a utilizar exclusivamente el primero, es decir Thumby IDE (opens new window). Será en este sistema de archivos especial donde copiaremos los ficheros Python del programa o juego que encontraremos en el repositorio. Si uno de esos ficheros se llama main.py y se encuentra en la raíz, se ejecutará automáticamente al alimentar PiConsole.

# Firmware tipo CircuitPython

CircuitPython es una reimplementación o fork de MicroPython hecha por Adafruit (opens new window). La diferencia más apreciable es que el espacio del almacenamiento interno disponible para guardar el código Python se monta como una unidad extraíble, por lo que no necesitaremos utilizar un IDE compatible como sí sucede con MicroPython. Nos servirá un simple editor de texto para escribir, modificar y probar nuestros programas. En general nos convendrá utilizar CircuitPython si necesitamos conectar Pico a un módulo fabricado por Adafruit.

CircuitPython incluye de serie los módulos o librerías que se indican en la lista Built-in modules available en la página de descarga del firmware (opens new window). Existen además una gran cantidad de librerías adicionales que pueden localizarse a través de esta página (opens new window). La documentación general de CircuitPython la encontramos en este sitio (opens new window).

Para ejecutar los programas del repositorio en los que se indica CircuitPython como Entorno, sólo será necesario flashear el firmware (opens new window) que contiene el intérprete de CircuitPython. Una vez flasheado veremos cómo Pico se monta como una unidad extraíble de nombre CIRCUITPY sobre la que podremos copiar los ficheros Python del programa o juego que encontraremos en el repositorio. Si en la unidad CIRCUITPY hay un fichero con nombre main.py y se encuentra en la raíz, se ejecutará automáticamente al alimentar PiConsole.

# Firmware tipo Arduino IDE

Raspberry Pi Pico puede programarse desde el Arduino IDE. Para ello sólo hay que incorporar la descripción de las tarjetas basadas en el microcontrolador RP2040. Para ello proceder como sigue:

  1. Abrir el Arduino IDE (opens new window).

  2. Abrir Preferencias en el menú Archivo.

  3. Pegar en el campo Gestor de URLs Adicionales de Tarjetas lo siguiente:

    https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
    
    1
  4. Pulsar Ok en el cuadro de diálogo Preferencias.

  5. Abrir Placa > Gestor de tarjetas en el menú Herramientas.

  6. Buscar Raspberry Pi Pico/RP2040.

  7. Instalar la entrada con el mismo nombre que hemos buscado del autor Earle F. Philhower, III.

Tras realizar los pasos anteriores, deberíamos ver una nueva sección de nombre Raspberry Pi RP2040 Boards(versión) en el menú Herramientas > Placa. De entre las placas que encontraremos en la lista, seleccionaremos Generic RP2040. Con esto ya tendremos preparado el entorno para trabajar con Raspberry Pi Pico. Podremos utilizar las librerías compatibles y el lenguaje y la estructura de código propia de Arduino. También podremos utilizar el Monitor Serie para depurar nuestros programas.

Si tras tener el entorno configurado queremos hacer una rápida prueba para comprobar que lo hemos preparado correctamente, podemos por ejemplo cargar el clásico sketch (así se llaman a los programas .ino de Arduino) de ejemplo para hacer parpadear el LED integrado en la placa. Para ello abrir Archivo > Ejemplos > 01.Basics > Blink. Se abrirá una ventana con el código de dicho sketch de ejemplo que sin necesitar modificación podremos compilar y enviar a Pico mediante el segundo botón por la izquierda de la botonera (el que tiene una flecha que apunta a la derecha). También podemos usar el menú Programa > Subir. Si todo ha ido bien, deberíamos ver a través de la carcasa un LED amarillo parpadeando entre la tecla BOOTSEL y el puerto microUSB de Pico. Si queremos hacer parpadear el LED rojo del frontal de PiConsole sólo tendremos que sustituir las tres entradas que hay en el código de la constante LED_BUILTIN por un 9 que es el número de GPIO de Pico al que se encuentra conectado el LED rojo (en el documento directorio de la colección de firmware encontramos los números de los pines GPIO de Pico donde están conectados todos los dispositivos de PiConsole).

En el repositorio (opens new window), en las carpetas correspondientes a los proyectos de tipo Arduino IDE (por ejemplo podemos fijarnos en el proyecto/directorio test_piconsole), normalmente encontraremos dos ficheros:

  • .ino: Es el código del proyecto para que podamos modificarlo/compilarlo nosotros mismos.
  • .uf2: Es el firmware ya compilado para facilitar el flasheo (como sabemos bastará con copiar el fichero en la unidad RPI-RP2 que se monta en el PC cuando conectamos el puerto USB mientras pulsamos la tecla BOOTSEL de Pico).

# Firmware tipo VS Code

Arduino IDE es el entorno más popular en la comunidad de desarrolladores de proyectos sobre microcontroladores en general. La fundación Raspberry Pi sin embargo ha elegido el entorno Visual Studio Code de Microsoft como entorno de desarrollo oficial para Pico. Por este motivo y porque algunos de los proyectos que encontremos en la red estarán gestionados con este IDE, vamos a ver cómo se instala y usa.

En la excelente guía Getting started with Pico (opens new window), se dedica el capítulo 7 a la instalación de este entorno en una Raspberry Pi, que lógicamente es el dispositivo recomendado por la fundación para trabajar con Pico. El capítulo 9 ofrece instrucciones para instalar el entorno en Windows y Mac (las instrucciones para instalar en Linux son asimilables a las del capítulo 7 para Raspberry Pi sin más que bajar el instalador correspondiente a la arquitectura de procesador de nuestro PC).

Vamos a resumir a continuación las instrucciones para instalar el entorno en un PC con Windows:

  1. Instalar ARM GCC Compiler descargando de este sitio (opens new window) la versión win32.exe. Al final del asistente de instalación marcamos la opción Add path to environment variable.

  2. Instalar CMake descargando de este sitio (opens new window) la versión Windows x64 Installer. Durante el asistente de instalación marcamos la opción Add CMake to the system PATH for all users.

  3. Instalar Build Tools for Visual Studio 2022 desde este sitio (opens new window) marcando únicamente el módulo Desarrollo para el escritorio con C.

  4. Instalar Python 3.10 descargando de este sitio (opens new window) el paquete de tipo Windows installer (64-bit) marcando la opción Add Python 3.10 to PATH al principio del asistente.

  5. Instalar git descargando de este sitio (opens new window) el paquete de tipo 64-bit Git for Windows Setup y seleccionando Notepad o Notepad++ como editor predeterminado durante el asistente.

  6. Instalar Visual Studio Code descargando de este sitio (opens new window) el paquete de tipo Windows > User Installer > 64 bit.

  7. Tras haber instalado todo, abrir un Developer Command Prompt Window desde Inicio > Visual Studio 2022 > Developer Command Prompt for VS 2022 y teclear code. De esta forma se abrirá Visual Studio Code con el entorno correctamente configurado.

  8. En la ventana de Visual Studio Code (es probable que la primera vez que la abramos tengamos que seguir los pasos de una especie de asistente de configuración inicial) pulsar el botón Extensions (icono con cuatro sectores cuadrados, uno de ellos desgajado) de la barra lateral izquierda.

  9. Buscar CMake Tools, hacer clic en la entrada con ese nombre y pulsar Install.

  10. Pulsar el botón Manage (icono de engranaje) de la barra lateral izquierda y seleccionar Settings.

  11. En el panel de ajustes navegar a Extensions > CMake Tools y hacer scroll hasta encontrar la sección Cmake: Configure Environment.

  12. Pulsar Add Item y añadir la siguiente clave/valor pulsando el botón OK al finalizar:

    • Key: PICO_SDK_PATH
    • Value: ..\..\pico-sdk
  13. Seguir haciendo scroll hacia abajo hasta encontrar la sección Cmake: Generator. Allí teclear NMake Makefiles en el campo vacío.

  14. Cerrar la solapa Settings en la que hemos estado trabajando.

  15. Instalar el repositorio con el SDK de Pico ejecutando en un terminal:

    cd Downloads
    git clone -b master https://github.com/raspberrypi/pico-sdk.git
    cd pico-sdk
    git submodule update --init
    cd ..
    git clone -b master https://github.com/raspberrypi/pico-examples.git
    
    1
    2
    3
    4
    5
    6

Con esto habríamos instalado todo el ecosistema para trabajar con Pico desde Visual Studio Code. Vamos a probar a compilar un programa y flashear Pico desde este entorno. Para ello procedemos como sigue:

  1. Usar el menú File > Open Folder de Visual Studio Code y localizar la carpeta que contenga los archivos del repositorio pico-examples que hemos clonado con git en el último paso (15) de la secuencia anterior.
  2. Nada más hacerlo aparecerá un pequeño popup abajo a la derecha pidiéndonos si queremos configurar el proyecto. Responderemos Yes.
  3. Pulsar el botón Build en la barra horizontal inferior (con el icono de engranaje). Aparecerá una lista de kits de compilación de la que seleccionaremos GCC version arm-none-eabi.
  4. Al terminar la compilación (que llevará bastante tiempo), encontraremos un nuevo directorio build dentro de pico-examples donde se habrán generado todos los ficheros producto de la compilación, entre ellos el .uf2 que podremos flashear en Pico. Por ejemplo el fichero pico-examples\build\blink\blink.uf2 que hace parpadear el LED integrado en Pico de forma parecida al sketch de ejemplo que cargamos con el Arduino IDE.

Como vemos este entorno es ciertamente engorroso y complejo. Se usa en el ambiente profesional para desarrollar. Aquí lo hemos incluido únicamente para compilar los proyectos que encontremos en este formato.

Última actualización: 13/4/2022, 10:46:53