I am a very heavy user of the Raspberry Pi Pico 2040. It is my go-to chip for any designs, including my Creature Controller. There’s a feature in the RP2040 that allows you to leave markers in the binary for picotool
to read, and I’ve found that a lot of folks aren’t taking advantage of it.
This blog post can hopefully show you how it works!
If you’d like to just jump straight to a working example, look at main.c in my Creature Controller firmware. Or, if you’d rather go to a first party source, this information is also in the Pi Pico SDK documentation.
If you’re not sure what picotool
is, it’s a utility that Raspberry Pi provides for getting information about Pi Pico applications.
Setting up Your Source Code
There’s two things you need to do. First, you need to include the macros that the RP2040 SDK provides. They’re in the pico/binary_info.h
file.
#include "pico/binary_info.h"
You shouldn’t have to add anything to your CMakeLists.txt
to enable this library.
Annotating Your Source
Once you’ve got the macros defined, you can use them to define information about your binary that will be visible to picotool
. Here’s an example out of my Creature Controller:
bi_decl(bi_program_name("controller-firmware"))
bi_decl(bi_program_description("April's Creature Workshop Controller"))
bi_decl(bi_program_version_string("3"))
bi_decl(bi_program_feature("FreeRTOS version " tskKERNEL_VERSION_NUMBER))
bi_decl(bi_program_feature("Baud: 115200,N,8,1"))
bi_decl(bi_program_url("https://creature.engineering/hardware/creature-controller/"))
bi_decl(bi_1pin_with_name(POWER_PIN, "Power Relay"))
bi_decl(bi_1pin_with_name(STATUS_LIGHTS_LOGIC_BOARD_PIN, "Status Lights for Logic Board"))
bi_decl(bi_1pin_with_name(STATUS_LIGHTS_MOD_A_PIN, "Status Lights Module A"))
bi_decl(bi_1pin_with_name(STATUS_LIGHTS_MOD_B_PIN, "Status Lights Module B"))
bi_decl(bi_1pin_with_name(STATUS_LIGHTS_MOD_C_PIN, "Status Lights Module C"))
bi_decl(bi_2pins_with_func(UART_TX_PIN, UART_RX_PIN, GPIO_FUNC_UART))
bi_decl(bi_2pins_with_func(SENSORS_I2C_SDA_PIN, SENSORS_I2C_SCL_PIN, GPIO_FUNC_I2C))
bi_decl(bi_1pin_with_name(SERVO_0_GPIO_PIN, "Servo 0"))
bi_decl(bi_1pin_with_name(SERVO_1_GPIO_PIN, "Servo 1"))
bi_decl(bi_1pin_with_name(SERVO_2_GPIO_PIN, "Servo 2"))
bi_decl(bi_1pin_with_name(SERVO_3_GPIO_PIN, "Servo 3"))
bi_decl(bi_1pin_with_name(SERVO_4_GPIO_PIN, "Servo 4"))
bi_decl(bi_1pin_with_name(SERVO_5_GPIO_PIN, "Servo 5"))
bi_decl(bi_1pin_with_name(SERVO_6_GPIO_PIN, "Servo 6"))
bi_decl(bi_1pin_with_name(SERVO_7_GPIO_PIN, "Servo 7"))
bi_decl(bi_1pin_with_name(CONTROLLER_RESET_PIN, "Controller Reset"))
What this is doing is setting up some metadata about the version of the firmware that’s running on a device. It also provides a helpful map of where to connect each pin.
Viewing the Output
Once you’ve got your binary annotated, you can use picotool
to view it:
picotool info -a firmware.uf2
Here’s what the output of my Creature Controller firmware shows as of the time I’m writing this:
april@lop:~/code/creature-controller/firmware/build$ picotool info -a firmware.uf2
File firmware.uf2:
Program Information
name: firmware
version: 3
web site: https://creature.engineering/hardware/creature-controller/
description: April's Creature Workshop Controller
features: Baud: 115200,N,8,1
FreeRTOS version V11.1.0+
UART stdin / stdout
binary start: 0x10000000
binary end: 0x10010434
Fixed Pin Information
0: UART0 TX, UART0 TX
1: UART0 RX
2: Controller Reset
4: UART1 TX
5: UART1 RX
6: Servo 0
7: Servo 1
8: Servo 2
9: Servo 3
10: Servo 4
11: Servo 5
12: Servo 6
13: Servo 7
14: Status Lights Module A
15: Status Lights Module B
16: Status Lights Module C
17: Status Lights for Logic Board
20: I2C0 SDA
21: I2C0 SCL
25: LED
28: Power Relay
Build Information
sdk version: 1.5.1
pico_board: pico
boot2_name: boot2_w25q080
build date: Jun 13 2024
build attributes: Release
Pretty cool, uh?
I picked things to list in it that are useful for me, like the version of the protocol spoken (3, in this case), and the version of FreeRTOS it was compiled against.
I hope this information helps you make your binaries more discoverable! I couldn’t find much information on this in an Internet search, so I figured I would be the blog post writer I wanted to see! 😍