Primeros pasos con Raspberry Pi Pico

Raspberry Pi Pico

Hace pocos días la fundación Raspberry Pi sacaba al mercado una curiosa plaquita llamada Raspberry Pi Pico. Curiosa porque se separa de lo que venían haciendo. Es decir, nos encontramos ante una placa al estilo del Arduino nano, pero comandada por el microcontrolador RP4020, basado en el ARM Cortex M0+ de doble núcleo, que ha sido también diseñado por ellos. En la placa de desarrollo nos ofrecen 26 GPIOs con soporte para SPI, I2C, ADC, UART y PWM. Acompañado de una completísima documentación y un entorno de desarrollo basado en Visual Studio Code. Y lo que es mejor, sólo por 4 dólares.

Rasperry Pi Pico pinout

La instalación del entorno de desarrollo oficial es muy sencilla y viene bien explicada en la documentación. Aunque si, como yo, prefieres la línea de comando, en este artículo os explicaré como poner en marcha un proyecto para este microcontrolador y programarlo con vuestro editor favorito. En este caso, para equipos con Debian y derivados. Antes de nada necesitaremos instalar el toolchain para ARM, git para obtener el SDK y los ejemplos del repositorio de Raspberry, y cmake, que es la herramienta en la que está basada el proceso de compilación en el entorno de desarrollo.

sudo apt install cmake gcc-arm-none-eabi build-essential git

Creamos un directorio que contendrá el SDK y los ejemplos, siempre útiles a la hora de afrontar un proyecto propio.

mkdir pico
cd pico
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

El directorio pico-sdk contiene las librerías necesarias para la programación del microcontrolador, y la carpeta pico-examples, unos cuantos ejemplos. En la documentación oficial y en los miles de tutoriales que aparecerán estos días puedes ver cómo compilar y ejecutar los ejemplos, pero yo voy a ir directo a explicar como crear un proyecto desde cero. He creado una carpeta llamada proyectos dentro del directorio pico, pero esto ya es cuestión de gustos y de la forma que tengas de organizarte.

mkdir proyectos
cd proyectos
mkdir blinky
cd blinky

En este caso, el proyecto que vamos a crear se llama blinky, y como adivinarás por el nombre, lo que vamos a hacer es hacer parpadear un LED, el hola mundo de los microcontroladores. De hecho el código C es el mismo que viene en los ejemplos, así que simplemente crea un archivo llamado blink.c e introduce el siguiente código, que lo que hace parpadear el LED que hay conectado al GPIO25 de la placa.

/**
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "pico/stdlib.h"

int main() {
    const uint LED_PIN = 25;
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PIN, GPIO_OUT);
    while (true) {
        gpio_put(LED_PIN, 1);
        sleep_ms(250);
        gpio_put(LED_PIN, 0);
        sleep_ms(250);
    }
}

Como ya se ha dicho, el entorno de desarrollo está basado en cmake, así que necesitamos crear un archivo llamado CMakeLists.txt donde se configura el proyecto. En este caso es el siguiente.

cmake_minimum_required(VERSION 3.12)
include(~/pico/pico-sdk/external/pico_sdk_import.cmake)

project(blink C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

pico_sdk_init()
add_executable(blink blink.c)
target_link_libraries(blink pico_stdlib)
pico_add_extra_outputs(blink)

En la línea del include debéis poner la ruta donde instalasteis el SDK, que puede no coincidir con la mía. Sin entrar en mucho detalle, porque cmake es un universo en sí mismo, en la línea project, pondremos el nombre de nuestro proyecto.

En add_executable indicamos el nombre del ejecutable que se va a generar y el archivo con el código fuente. También hay que añadir este nombre en larget_link_libraries, para que se enlace con las librerías que vayamos a usar del SDK, en este caso sólo pico_stdlib, pero su fuéramos a usar otras, como, por ejemplo, las de i2c, añadiríamos también hardware_i2c detrás de pico_stdlib.

Con pico_add_extra_outputs, indicamos que queremos obtener el ejecutable, además de en formato elf, en formato .uf2, que es el que usa el microcontrolador.

Ahora le decimos a cmake que configure el proyecto y genere los archivos necesarios para poder compilar con make. Esto lo hacemos con cmake . (importante poner el . después de cmake). Pero antes tendremos que configurar la variable de entorno PICO_SDK_PATH con la ruta del SDK.

export PICO_SDK_PATH=~/pico/pico-sdk
cmake .

Deberíamos ver algo parecido a esto.

Using PICO_SDK_PATH from environment ('/home/alberto/tools/pico/pico-sdk')
Pico SDK is located at /home/alberto/tools/pico/pico-sdk
Defaulting PICO_PLATFORM to rp2040 since not specified.
Defaulting PICO platform compiler to pico_arm_gcc since not specified.
-- Defaulting build type to 'Release' since not specified.
PICO compiler is pico_arm_gcc
PICO_GCC_TRIPLE defaulted to arm-none-eabi
-- The C compiler identification is GNU 9.2.1
-- The CXX compiler identification is GNU 9.2.1
-- The ASM compiler identification is GNU
-- Found assembler: /usr/bin/arm-none-eabi-gcc
Defaulting PICO target board to pico since not specified.
Using board configuration from /home/alberto/tools/pico/pico-sdk/src/boards/include/boards/pico.h
-- Found Python3: /usr/bin/python3.8 (found version "3.8.5") found components: Interpreter 
TinyUSB available at /home/alberto/tools/pico/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040; adding USB support.
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE) 
ELF2UF2 will need to be built
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alberto/tools/pico/proyectos/blinky

Si nos fijamos ahora en el directorio, veremos que se han creado una serie de archivos nuevos, entre ellos, por ejemplo, un Makefile. Así que nos resta sólo ejecutar make para que nuestro proyecto se compile y genere un ejecutable.

make

Y deberíamos ver algo como lo siguiente.

Scanning dependencies of target ELF2UF2Build
[  1%] Creating directories for 'ELF2UF2Build'
[  3%] No download step for 'ELF2UF2Build'
[  5%] No patch step for 'ELF2UF2Build'
[  6%] No update step for 'ELF2UF2Build'
[  8%] Performing configure step for 'ELF2UF2Build'
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alberto/tools/pico/proyectos/blinky/elf2uf2
[ 10%] Performing build step for 'ELF2UF2Build'
Scanning dependencies of target elf2uf2
[ 50%] Building CXX object CMakeFiles/elf2uf2.dir/main.cpp.o
[100%] Linking CXX executable elf2uf2
[100%] Built target elf2uf2
[ 11%] No install step for 'ELF2UF2Build'
[ 13%] Completed 'ELF2UF2Build'
[ 13%] Built target ELF2UF2Build
Scanning dependencies of target bs2_default
[ 15%] Building ASM object pico_sdk/src/rp2_common/boot_stage2/CMakeFiles/bs2_default.dir/boot2_w25q080.S.obj
[ 16%] Linking ASM executable bs2_default.elf
[ 16%] Built target bs2_default
Scanning dependencies of target bs2_default_bin
[ 18%] Generating bs2_default.bin
[ 18%] Built target bs2_default_bin
Scanning dependencies of target bs2_default_padded_checksummed_asm
[ 20%] Generating bs2_default_padded_checksummed.S
[ 20%] Built target bs2_default_padded_checksummed_asm
Scanning dependencies of target blink
[ 22%] Building C object CMakeFiles/blink.dir/blink.c.obj
[ 23%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_stdlib/stdlib.c.obj
[ 25%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/hardware_gpio/gpio.c.obj
[ 27%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/hardware_claim/claim.c.obj
[ 28%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/hardware_sync/sync.c.obj
[ 30%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_platform/platform.c.obj
[ 32%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/hardware_uart/uart.c.obj
[ 33%] Building ASM object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/hardware_divider/divider.S.obj
[ 35%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/common/pico_time/time.c.obj
[ 37%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/common/pico_time/timeout_helper.c.obj
[ 38%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/hardware_timer/timer.c.obj
[ 40%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/common/pico_sync/sem.c.obj
[ 42%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/common/pico_sync/lock_core.c.obj
[ 44%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/common/pico_sync/mutex.c.obj
[ 45%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/common/pico_sync/critical_section.c.obj
[ 47%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/common/pico_util/datetime.c.obj
[ 49%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/common/pico_util/pheap.c.obj
[ 50%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/common/pico_util/queue.c.obj
[ 52%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_runtime/runtime.c.obj
[ 54%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/hardware_clocks/clocks.c.obj
[ 55%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/hardware_watchdog/watchdog.c.obj
[ 57%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/hardware_xosc/xosc.c.obj
[ 59%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/hardware_pll/pll.c.obj
[ 61%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/hardware_vreg/vreg.c.obj
[ 62%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/hardware_irq/irq.c.obj
[ 64%] Building ASM object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/hardware_irq/irq_handler_chain.S.obj
[ 66%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_printf/printf.c.obj
[ 67%] Building ASM object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S.obj
[ 69%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_bootrom/bootrom.c.obj
[ 71%] Building ASM object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_divider/divider.S.obj
[ 72%] Building ASM object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_double/double_aeabi.S.obj
[ 74%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_double/double_init_rom.c.obj
[ 76%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_double/double_math.c.obj
[ 77%] Building ASM object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_double/double_v1_rom_shim.S.obj
[ 79%] Building ASM object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_int64_ops/pico_int64_ops_aeabi.S.obj
[ 81%] Building ASM object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_float/float_aeabi.S.obj
[ 83%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_float/float_init_rom.c.obj
[ 84%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_float/float_math.c.obj
[ 86%] Building ASM object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_float/float_v1_rom_shim.S.obj
[ 88%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_malloc/pico_malloc.c.obj
[ 89%] Building ASM object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_mem_ops/mem_ops_aeabi.S.obj
[ 91%] Building ASM object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_standard_link/crt0.S.obj
[ 93%] Building CXX object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_standard_link/new_delete.cpp.obj
[ 94%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_standard_link/binary_info.c.obj
[ 96%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_stdio/stdio.c.obj
[ 98%] Building C object CMakeFiles/blink.dir/home/alberto/tools/pico/pico-sdk/src/rp2_common/pico_stdio_uart/stdio_uart.c.obj
[100%] Linking CXX executable blink.elf
[100%] Built target blink

Si al final vemos el mensaje Built target blink es que todo ha ido bien y estamos listos para pasar el ejecutable al microcontrolador. Aquí también han sido originales los chicos de Raspberry. Para mover el ejecutable a la placa hay que seguir este orden. Primero pulsamos el pequeño botón que hay en la placa (hay que mantenerlo pulsado).

Programar la Raspberry Pi Pico

Seguidamente se conecta al ordenador mediante el cable USB y, tras esto, se suelta el botón. La tarjeta se monta como si fuera una unidad más en la que encontramos dos archivos.

Programar Raspberry Pi Pico

El archivo INDEX.HTM nos lleva directos a la documentación y el archivo INFO_UF2.TXT contiene información sobre la versión de la tarjeta. Sólo tenemos que arrastrar el archivo blink.uf2 a esta ventana, e inmediatamente se desmontará la unidad y comenzará a ejecutarse. El LED de la placa debería empezar a parpadear como en el siguiente vídeo.

La intención de este artículo era simple, ver cómo poner en marcha un pequeño proyecto y programar la placa. Espero en un próximo artículo profundizar algo más y crear un proyecto algo más completo y realista. Hasta entonces, a disfrutar.

Sé el primero en comentar en «Primeros pasos con Raspberry Pi Pico»

Deja un comentario

Tu dirección de correo electrónico no será publicada.


*