From e9346773d51055ee330e5a9ede8cf72a08af5551 Mon Sep 17 00:00:00 2001 From: will-v-pi <108662275+will-v-pi@users.noreply.github.com> Date: Fri, 22 Nov 2024 19:37:10 +0000 Subject: [PATCH] Add binary info examples of configurable binaries (#567) --- CMakeLists.txt | 1 + README.md | 7 ++ binary_info/CMakeLists.txt | 2 + binary_info/README.md | 60 ++++++++++++++++ binary_info/blink_any/CMakeLists.txt | 20 ++++++ binary_info/blink_any/blink_any.c | 76 +++++++++++++++++++++ binary_info/hello_anything/CMakeLists.txt | 20 ++++++ binary_info/hello_anything/hello_anything.c | 40 +++++++++++ 8 files changed, 226 insertions(+) create mode 100644 binary_info/CMakeLists.txt create mode 100644 binary_info/README.md create mode 100644 binary_info/blink_any/CMakeLists.txt create mode 100644 binary_info/blink_any/blink_any.c create mode 100644 binary_info/hello_anything/CMakeLists.txt create mode 100644 binary_info/hello_anything/hello_anything.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 59c958630..416ac6780 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/README.md b/README.md index 33f372c63..59a75068a 100644 --- a/README.md +++ b/README.md @@ -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 ---|--- diff --git a/binary_info/CMakeLists.txt b/binary_info/CMakeLists.txt new file mode 100644 index 000000000..807120bed --- /dev/null +++ b/binary_info/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory_exclude_platforms(blink_any) +add_subdirectory_exclude_platforms(hello_anything) diff --git a/binary_info/README.md b/binary_info/README.md new file mode 100644 index 000000000..e443a226d --- /dev/null +++ b/binary_info/README.md @@ -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 +``` diff --git a/binary_info/blink_any/CMakeLists.txt b/binary_info/blink_any/CMakeLists.txt new file mode 100644 index 000000000..de0401993 --- /dev/null +++ b/binary_info/blink_any/CMakeLists.txt @@ -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) diff --git a/binary_info/blink_any/blink_any.c b/binary_info/blink_any/blink_any.c new file mode 100644 index 000000000..5c033207f --- /dev/null +++ b/binary_info/blink_any/blink_any.c @@ -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); + } +} diff --git a/binary_info/hello_anything/CMakeLists.txt b/binary_info/hello_anything/CMakeLists.txt new file mode 100644 index 000000000..13aa84380 --- /dev/null +++ b/binary_info/hello_anything/CMakeLists.txt @@ -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() diff --git a/binary_info/hello_anything/hello_anything.c b/binary_info/hello_anything/hello_anything.c new file mode 100644 index 000000000..26772a684 --- /dev/null +++ b/binary_info/hello_anything/hello_anything.c @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#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); + } +}