En capítulos anteriores…
En el anterior post de esta serie (si no lo has leído, ES AQUI) te desvelé la tarjeta que vamos a utilizar y nos hicimos con dos cosas importantes para alcanzar nuestro objetivo: El esquema electrónico de la placa y el manual del *microcontrolador.
*NOTA IMPORTANTE: A lo largo de la serie posiblemente utilice los términos «Microcontrolador», «SoC» (system on chip), «CPU» o «Chip» indistintamente. SE QUE TECNICAMENTE NO ES LO MISMO pero seguro que me perdonas.
Ahora es momento de hablar sobre las herramientas que necesitamos para llegar al «ambicioso» objetivo de hacer parpadear un LED.
Salvo que hables «maquina» necesitas un compilador
Puede que esto que te voy a decir ahora te sorprenda, pero…
Las CPUs basicamente ejecutan instrucciones que leen de una memoria.
¿Que instrucciones? pues simple y llanamente las que el fabricante de esa CPU ha introducido en su diseño.
En el caso concreto del SoC nRF52840, la CPU que tiene dentro es un ARM Cortex-M4F**.

**Nota aclaratoria: El fabricante del SoC (Nordic Semiconductor) ha incluido dentro de su diseño una CPU de marca ARM.
Aunque no lo sepas ARM no fabrica ni un solo semiconductor.
¿Pero si todos los móviles y otros muchos dispositivos llevan CPUs ARM, quien los fabrica?
Pues bien, ARM solo diseña CPUs. Y luego cobra una licencia a los fabricantes de semiconductores por usar sus diseños.
En este caso Nordic Semiconductor estará pagando unos royalties para poder incluir dentro de su chip esa CPU.
Vale y después de este paréntesis, continuamos…
Como la CPU es ARM, las instrucciones que puede ejecutar esa CPU estarán especificadas por el fabricante (ARM).
En el caso concreto del ARM Cortex-M4F las instrucciones disponibles están descritas AQUI.
Si has echado un vistazo al enlace igual no has entendido nada.
Pero aquí estoy yo para explicártelo.
Para programar una CPU puedes hacer 3 cosas
a) Escribir las instrucciones en código máquina. Técnicamente se podría, pero sería básicamente como «ver matrix» porque tendrías que escribir codigos binarios en un fichero con todas las instrucciones de tu programa. DESCARTADO!!
b) Escribir las instrucciones en ensamblador. El ensamblador es un lenguaje más «amigable» para un humano (aunque no mucho) y facilita la tarea (todas las instrucciones que aparecen en el enlace de arriba son en ensamblador).
Eso si, tienes que tener en cuenta que para traducir ese código ensamblador en código máquina necesitas un traductor (AKA: Compilador)
c) Escribir tu programa en un lenguaje de alto nivel como C/C++ o «the new kid on the block» Rust. Obviamente para obtener código máquina a partir de este programa escrito en alguno de estos lenguajes también necesitas un compilador.
Y tras estos prolegómenos vamos a lo importante.
¿QUE COMPILADOR ELEGIMOS?
Para saber eso necesitamos dos datos
a) que CPU vamos a usar
En nuestro caso un ARM Cortex-M4F
b) Para que tipo de sistema vamos a generar código
Aquí hay dos opciones. Bare-Metal (Sin sistema operativo) o sobre un sistema operativo (tipicamente linux).
En nuestro caso, la opción será bare-metal porque no vamos a tener sistema operativo.
Si accedemos a la página de ARM donde están sus *toolchains AQUI veremos dos opciones de toolchain. Y la que obviamente la que nos interesa es la siguiente:

*Toolchain es el término que se emplea para referirse al compilador y a otras herramientas necesarias para generar nuestros binarios y también para analizarlos y depurarlos.
COMO GRABAMOS EL CÓDIGO
Vale, ya tenemos la toolchain que nos permitirá compilar nuestro código (cuando tengamos algo de código) en un fichero (también conocido como binario).
Pero, ¿Como grabo ese binario en mi tarjeta?
La primera opción es utilizando un debugger que se conectará a nuestro SoC usando el puerto JTAG y nos permitirá escribir en la memoria flash del dispositivo.

Vale, se lo que estas pensando. Que tu no tienes un trasto de esos.
Pues la segunda opción es grabar la memoria flash a través del puerto USB de la tarjeta.
IMPORTANTE: Para que puedas hacer eso, tu tarjeta tiene que tener pregrabado un bootloader.
Y antes de que me preguntes, te cuento lo que es un bootloader.
Un bootloader es un pequeño programa que se graba al inicio de la memoria flash, de tal modo que siempre lo primero que se ejecuta al arrancar el chip es ese programa.
¿Y que hace ese programa? Pues basicamente 2 cosas
a) Escuchar en el puerto USB por si hay una petición para escribir una nueva aplicación y si es así recibir los datos e irlos grabando en la zona de memoria flash permitida
b) Si no hay peticion para grabar datos saltar a la dirección de memoria donde está la aplicación y ejecutarla.

Si miras en la tabla de arriba aparte del bootloader y la aplicación hay algunas cosas más.
Te las cuento muy por encima:
MBR (Master boot Record): En realidad esto es lo primero que se ejecuta al encender nuestra placa y se encarga de hacer algunas inicializaciones y salta al bootloader.
SoftDevice: El stack de Bluetooth y algunas cosas más que nuestros amigos de Nordic nos da ya compiladas (pero sin código fuente).
Bootloader settings & MBR parameter storage: Zonas donde se almacenan datos de configuración para el MBR y el bootloader.
No voy a comentar mucho más porque entraremos en más detalles en siguientes posts.
RESUMIENDO
En la primera entrega nos hicimos con algunos documentos que necesitaremos para llevar a cabo nuestra misión.
En esta segunda entrega hemos visto que compilador utilizaremos y como grabaremos nuestra aplicación en nuestra tarjeta.
…Y EN EL PROXIMO POST?
En el próximo post entraremos a ver el SDK del microcontrolador, como tunearlo para nuestra placa específica (usando el esquemático y el manual de referencia) y alguna cosa más que aún no he decidido…
2 respuestas a «El ladrillo que se convierte en un LED que brilla (parte 2)»
Hola, he llegado hasta aquí después de de la entevista con Luis del Valle.
Y mi duda es, se puede hacer lo mismo con arduino, o estamos hablando de cosas muy distintas.
Yo de programar, ni idea. Estoy en ello.
Hola Alfonso,
Se puede 100%. Cualquier placa con un microcontrolador puede programarse igual que yo he programado la placa Argon. Pero obviamente, la diferencia estará en el microcontrolador que tenga la placa.
Gran parte de las placas Arduino tienen microcontroladores Atmel (p.ej. Arduino Uno tiene un Atmel 328P). Entonces tendrías que consultar el manual de ese microcontrolador. Y otro tema importante sería grabar la placa sin usar el bootloader de Arduino. En el caso de Atmel en lugar de tener un conector JTAG tiene un conector ICSP (In Circuit Serial Programming) que es específico de Atmel y necesitarías un programador de Atmel.
Para acabar un último apunte. Arduino digamos que son dos cosas. La parte del HW (todas las tarjetas que vende Arduino) y la parte de SW que es todo el código que hace que independientemente de la tarjeta que estes usando siempre utilices las mismas funciones (digitalWrite, digitalRead, etc, etc, etc). Entonces, si a una tarjeta de arduino le quitamos ese SW (borrando completamente la memoria flash) tendríamos simplemente una tarjeta electrónica con un microcontrolador (Atmel seguramente) donde podríamos programar todo de 0.