Skip to content

Commit

Permalink
Add tiny_blink example which has a minimal binary size
Browse files Browse the repository at this point in the history
  • Loading branch information
kilograham committed Sep 8, 2024
1 parent 40d2476 commit caa97ea
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 0 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ add_subdirectory(rtc)
add_subdirectory(spi)
add_subdirectory(system)
add_subdirectory(timer)
add_subdirectory(tiny)
add_subdirectory(uart)
add_subdirectory(universal)
add_subdirectory(usb)
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,11 @@ App|Description
[periodic_sampler](timer/periodic_sampler) | Sample GPIOs in a timer callback, and push the samples into a concurrency-safe queue. Pop data from the queue in code running in the foreground.
[timer_lowlevel](timer/timer_lowlevel) | Example of direct access to the timer hardware. Not generally recommended, as the SDK may use the timer for IO timeouts.

### Tiny (code)
App|Description
---|---
[tiny_blink](tiny/tiny_blink) | Shows how to minimize the runtime by disabling runtime features via `CMakeLists.txt` to make a very small GPIO 'blink' binary.

### UART

App|Description
Expand Down
56 changes: 56 additions & 0 deletions tiny/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
add_executable(blink_tiny
blink_tiny.c
)

# pull in common dependencies
target_link_libraries(blink_tiny pico_stdlib)

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

# call pico_set_program_url to set path to example on github, so users can find the source for an example via picotool
example_auto_set_url(blink_tiny)

# Useful CMKake function to help minimize the runtime; we are disabling everything - be careful as disabled things obviously wont work
#
# pico_minimize_runtime(blink_tiny) is equivalent (i.e. everything defaults to off)
#
# you could do something like the following to include standard stuff except the default alarm pool, single precision
# floating point support and double precision floating point support.
# pico_minimize_runtime(blink_tiny INCLUDE ALL EXCLUDE DEFAULT_ALARM_POOL FLOAT DOUBLE)
pico_minimize_runtime(blink_tiny EXCLUDE ALL)

# More space savings can be made by skipping various bits of the runtime_init (you could alternatively replace the
# implementations as needed either via a non weak function of the appropriate name - note you can omit the default
# weak implementation via PICO_RUNTIME_NO_INIT_XXX=1)
#
# you should be even more careful here skipping bits of runtime initialization code
target_compile_definitions(blink_tiny PRIVATE
PICO_RUNTIME_SKIP_INIT_CLOCKS=1 # we can run with the bootrom clock setup
PICO_RUNTIME_SKIP_POST_CLOCK_RESETS=1 # hangs without init clocks - means we get no clocked peripherals
PICO_RUNTIME_SKIP_INIT_USB_POWER_DOWN=1 # don't care about USB power usage
PICO_RUNTIME_SKIP_INIT_PER_CORE_ENABLE_COPROCESSORS=1 # don't need any coprocessors (float, DCP, or GPIO)
PICO_USE_GPIO_COPROCESSOR=0 # we'd have to init it if we used it
PICO_RUNTIME_SKIP_INIT_RP2040_GPIO_IE_DISABLE=1 # really don't care
PICO_RUNTIME_SKIP_INIT_SPIN_LOCKS_RESET=1 # we don't use spin locks so resetting them is not necessary
PICO_USE_SW_SPIN_LOCKS=0 # no need to sw spin locks on RP2350 as we don;t use them or the affected SIO regions
PICO_RUNTIME_SKIP_INIT_BOOT_LOCKS_RESET=1 # we don't use boot locks so resetting them is not necessary
PICO_RUNTIME_SKIP_INIT_BOOTROM_LOCKING_ENABLE=1 # we don't call bootrom functions requiring locking
PICO_RUNTIME_SKIP_INIT_PER_CORE_IRQ_PRIORITIES=1 # no IRQ use
PICO_NO_RAM_VECTOR_TABLE=1 # so no need for ram vector table
PICO_RUNTIME_SKIP_INIT_PER_CORE_H3_IRQ_REGISTERS=1 # no need to setup RISC-V IRQ handling
)

if (PICO_C_COMPILER_IS_GNU AND PICO_ON_DEVICE)
# pending resolution of https://github.com/raspberrypi/pico-sdk/issues/1368 we can save space by explicitly
# disabling startfiles at least for tiny_blink
target_link_options(blink_tiny PRIVATE "-nostartfiles")
endif()

# we can save more by disabling BINARY_INFO if you don't want it, however we leave binary_info on by default
# pass -DBLINK_TINY_NO_BINARY_INFO=1 to CMake to disable it
if (BLINK_TINY_NO_BINARY_INFO)
target_compile_definitions(blink_tiny PRIVATE
PICO_NO_BINARY_INFO=1
)
endif()
46 changes: 46 additions & 0 deletions tiny/blink_tiny.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/

#include "pico/stdlib.h"

#ifndef LED_DELAY_MS
#define LED_DELAY_MS 250
#endif

// Initialize the GPIO for the LED
void pico_led_init(void) {
#ifdef PICO_DEFAULT_LED_PIN
// A device like Pico that uses a GPIO for the LED will define PICO_DEFAULT_LED_PIN
// so we can use normal GPIO functionality to turn the led on and off
gpio_init(PICO_DEFAULT_LED_PIN);
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
#endif
}

// Turn the LED on or off
void pico_set_led(bool led_on) {
#if defined(PICO_DEFAULT_LED_PIN)
// Just set the GPIO on or off
gpio_put(PICO_DEFAULT_LED_PIN, led_on);
#endif
}

int main() {
pico_led_init();
// note these frequencies are approximate
#if PICO_RP2040
const int cpu_freq = 6500000;
#else
const int cpu_freq = 12000000;
#endif
while (true) {
pico_set_led(true);
// don't have clocks initialized wo wait based on CPU cycles
busy_wait_at_least_cycles((cpu_freq / 1000) * LED_DELAY_MS);
pico_set_led(false);
busy_wait_at_least_cycles((cpu_freq / 1000) * LED_DELAY_MS);
}
}

0 comments on commit caa97ea

Please sign in to comment.