Skip to content

Commit

Permalink
Add binary info examples of configurable binaries (#567)
Browse files Browse the repository at this point in the history
  • Loading branch information
will-v-pi authored Nov 22, 2024
1 parent deeb6d8 commit e934677
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 0 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ endif()

# Hardware-specific examples in subdirectories:
add_subdirectory(adc)
add_subdirectory(binary_info)
add_subdirectory(bootloaders)
add_subdirectory(clocks)
add_subdirectory(cmake)
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ App|Description
[dma_capture](adc/dma_capture) | Use the DMA to capture many samples from the ADC.
[read_vsys](adc/read_vsys) | Demonstrates how to read VSYS to get the voltage of the power supply.

### Binary Info

App|Description
---|---
[blink_any](binary_info/blink_any) | Uses `bi_ptr` variables to create a configurable blink binary - see the separate [README](binary_info/README.md) for more details
[hello_anything](binary_info/hello_anything) | Uses `bi_ptr` variables to create a configurable hello_world binary - see the separate [README](binary_info/README.md) for more details

### Bootloaders (RP2350 Only)
App|Description
---|---
Expand Down
2 changes: 2 additions & 0 deletions binary_info/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
add_subdirectory_exclude_platforms(blink_any)
add_subdirectory_exclude_platforms(hello_anything)
60 changes: 60 additions & 0 deletions binary_info/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
These programs demonstrate use of `bi_ptr` variables, which can be configured in a binary post-compilation using the `picotool config` command.

You can view the configurable variables with
```
$ picotool blink_any.uf2
File blink_any.uf2:
LED Configuration:
LED_PIN = 25
LED_TYPE = 0
$ picotool config hello_anything.uf2
File hello_anything.uf2:
text = "Hello, world!"
Enabled Interfaces:
use_usb = 1
use_uart = 1
UART Configuration:
uart_baud = 115200
uart_rx = 1
uart_tx = 0
uart_num = 0
```

For example, to blink the LED on pin 7 instead of 25 use
```
$ picotool config blink_any.uf2 -s LED_PIN 7
File blink_any.uf2:
LED_PIN = 25
setting LED_PIN -> 7
```

Or to change the printed string use
```
$ picotool config hello_anything.uf2 -s text "Goodbye, world!"
File hello_anything.uf2:
text = "Hello, world!"
setting text -> "Goodbye, world!"
```

The binaries can also be configured after being loaded onto the device with
```
$ picotool config
text = "Hello, world!"
Enabled Interfaces:
use_usb = 1
use_uart = 1
UART Configuration:
uart_baud = 115200
uart_rx = 1
uart_tx = 0
uart_num = 0
$ picotool config -s use_uart 0
use_uart = 1
setting use_uart -> 0
```
20 changes: 20 additions & 0 deletions binary_info/blink_any/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
if (NOT PICO_CYW43_SUPPORTED)
message("Only building blink_any for non W boards as PICO_CYW43_SUPPORTED is not set")
endif()

add_executable(blink_any
blink_any.c
)

# pull in common dependencies
target_link_libraries(blink_any pico_stdlib)

if (PICO_CYW43_SUPPORTED)
target_link_libraries(blink_any pico_cyw43_arch_none)
endif()

# create map/bin/hex file etc.
pico_add_extra_outputs(blink_any)

# add url via pico_set_program_url
example_auto_set_url(blink_any)
76 changes: 76 additions & 0 deletions binary_info/blink_any/blink_any.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/

#include "pico/stdlib.h"
#include "pico/binary_info.h"

#ifdef CYW43_WL_GPIO_LED_PIN
#include "pico/cyw43_arch.h"
#endif

// Set an LED_TYPE variable - 0 is default, 1 is connected to WIFI chip
// Note that LED_TYPE == 1 is only supported when initially compiled for
// a board with PICO_CYW43_SUPPORTED (eg pico_w), else the required
// libraries won't be present
bi_decl(bi_program_feature_group(0x1111, 0, "LED Configuration"));
#if defined(PICO_DEFAULT_LED_PIN)
// the tag and id are not important as picotool filters based on the
// variable name, so just set them to 0
bi_decl(bi_ptr_int32(0x1111, 0, LED_TYPE, 0));
bi_decl(bi_ptr_int32(0x1111, 0, LED_PIN, PICO_DEFAULT_LED_PIN));
#elif defined(CYW43_WL_GPIO_LED_PIN)
bi_decl(bi_ptr_int32(0x1111, 0, LED_TYPE, 1));
bi_decl(bi_ptr_int32(0x1111, 0, LED_PIN, CYW43_WL_GPIO_LED_PIN));
#else
bi_decl(bi_ptr_int32(0x1111, 0, LED_TYPE, 0));
bi_decl(bi_ptr_int32(0x1111, 0, LED_PIN, 25));
#endif

#ifndef LED_DELAY_MS
#define LED_DELAY_MS 250
#endif

// Perform initialisation
int pico_led_init(void) {
if (LED_TYPE == 0) {
// A device like Pico that uses a GPIO for the LED so we can
// use normal GPIO functionality to turn the led on and off
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
return PICO_OK;
#ifdef CYW43_WL_GPIO_LED_PIN
} else if (LED_TYPE == 1) {
// For Pico W devices we need to initialise the driver etc
return cyw43_arch_init();
#endif
} else {
return PICO_ERROR_INVALID_DATA;
}
}

// Turn the led on or off
void pico_set_led(bool led_on) {
if (LED_TYPE == 0) {
// Just set the GPIO on or off
gpio_put(LED_PIN, led_on);
#ifdef CYW43_WL_GPIO_LED_PIN
} else if (LED_TYPE == 1) {
// Ask the wifi "driver" to set the GPIO on or off
cyw43_arch_gpio_put(LED_PIN, led_on);
#endif
}
}

int main() {
int rc = pico_led_init();
hard_assert(rc == PICO_OK);
while (true) {
pico_set_led(true);
sleep_ms(LED_DELAY_MS);
pico_set_led(false);
sleep_ms(LED_DELAY_MS);
}
}
20 changes: 20 additions & 0 deletions binary_info/hello_anything/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
if (TARGET tinyusb_device)
add_executable(hello_anything
hello_anything.c
)

# pull in common dependencies
target_link_libraries(hello_anything pico_stdlib)

# enable usb and uart output
pico_enable_stdio_usb(hello_anything 1)
pico_enable_stdio_uart(hello_anything 1)

# create map/bin/hex/uf2 file etc.
pico_add_extra_outputs(hello_anything)

# add url via pico_set_program_url
example_auto_set_url(hello_anything)
elseif(PICO_ON_DEVICE)
message("Skipping hello_anything because TinyUSB submodule is not initialized in the SDK")
endif()
40 changes: 40 additions & 0 deletions binary_info/hello_anything/hello_anything.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "hardware/uart.h"

int main() {
// create feature groups to group configuration settings
// these will also show up in picotool info, not just picotool config
bi_decl(bi_program_feature_group(0x1111, 0, "UART Configuration"));
bi_decl(bi_program_feature_group(0x1111, 1, "Enabled Interfaces"));
// stdio_uart configuration and initialisation
bi_decl(bi_ptr_int32(0x1111, 1, use_uart, 1));
bi_decl(bi_ptr_int32(0x1111, 0, uart_num, 0));
bi_decl(bi_ptr_int32(0x1111, 0, uart_tx, 0));
bi_decl(bi_ptr_int32(0x1111, 0, uart_rx, 1));
bi_decl(bi_ptr_int32(0x1111, 0, uart_baud, 115200));
if (use_uart) {
stdio_uart_init_full(UART_INSTANCE(uart_num), uart_baud, uart_tx, uart_rx);
}

// stdio_usb initialisation
bi_decl(bi_ptr_int32(0x1111, 1, use_usb, 1));
if (use_usb) {
stdio_usb_init();
}

// default printed string
bi_decl(bi_ptr_string(0, 0, text, "Hello, world!", 256));

while (true) {
printf("%s\n", text);
sleep_ms(1000);
}
}

0 comments on commit e934677

Please sign in to comment.