diff --git a/rp2040-hal/Cargo.toml b/rp2040-hal/Cargo.toml index bcd075b0c..bae64a811 100644 --- a/rp2040-hal/Cargo.toml +++ b/rp2040-hal/Cargo.toml @@ -64,6 +64,7 @@ futures = { version = "0.3.30", default-features = false, features = [ defmt-rtt = "0.4.0" panic-probe = { version = "0.3.1", features = ["print-defmt"] } defmt = "0.3" +embedded-alloc = "0.5.1" [features] # Minimal startup / runtime for Cortex-M microcontrollers @@ -141,6 +142,10 @@ required-features = ["critical-section-impl"] name = "adc_fifo_poll" required-features = ["critical-section-impl"] +[[example]] +name = "alloc" +required-features = ["critical-section-impl"] + [[example]] name = "blinky" required-features = ["critical-section-impl"] diff --git a/rp2040-hal/examples/alloc.rs b/rp2040-hal/examples/alloc.rs new file mode 100644 index 000000000..c7b151323 --- /dev/null +++ b/rp2040-hal/examples/alloc.rs @@ -0,0 +1,123 @@ +//! # Alloc Example +//! +//! Uses alloc to create a Vec. +//! +//! This will blink an LED attached to GP25, which is the pin the Pico uses for +//! the on-board LED. It may need to be adapted to your particular board layout +//! and/or pin assignment. +//! +//! While blinkin the LED, it will continuously push to a `Vec`, which will +//! eventually lead to a panic due to an out of memory condition. +//! +//! See the `Cargo.toml` file for Copyright and licence details. + +#![no_std] +#![no_main] + +extern crate alloc; + +use alloc::vec::Vec; +use embedded_alloc::Heap; + +// The macro for our start-up function +use cortex_m_rt::entry; + +#[global_allocator] +static ALLOCATOR: Heap = Heap::empty(); + +// Ensure we halt the program on panic (if we don't mention this crate it won't +// be linked) +use panic_halt as _; + +// Alias for our HAL crate +use rp2040_hal as hal; + +// A shorter alias for the Peripheral Access Crate, which provides low-level +// register access +use hal::pac; + +// Some traits we need +use embedded_hal::delay::DelayNs; +use embedded_hal::digital::OutputPin; + +/// The linker will place this boot block at the start of our program image. We +/// need this to help the ROM bootloader get our code up and running. +/// Note: This boot block is not necessary when using a rp-hal based BSP +/// as the BSPs already perform this step. +#[link_section = ".boot2"] +#[used] +pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER_GENERIC_03H; + +/// External high-speed crystal on the Raspberry Pi Pico board is 12 MHz. Adjust +/// if your board has a different frequency +const XTAL_FREQ_HZ: u32 = 12_000_000u32; + +/// Entry point to our bare-metal application. +/// +/// The `#[entry]` macro ensures the Cortex-M start-up code calls this function +/// as soon as all global variables are initialised. +/// +/// The function configures the RP2040 peripherals, then blinks the LED in an +/// infinite loop. +#[entry] +fn main() -> ! { + { + use core::mem::MaybeUninit; + const HEAP_SIZE: usize = 1024; + static mut HEAP: [MaybeUninit; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE]; + unsafe { ALLOCATOR.init(HEAP.as_ptr() as usize, HEAP_SIZE) } + } + + // Grab our singleton objects + let mut pac = pac::Peripherals::take().unwrap(); + + // Set up the watchdog driver - needed by the clock setup code + let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); + + // Configure the clocks + // + // The default is to generate a 125 MHz system clock + let clocks = hal::clocks::init_clocks_and_plls( + XTAL_FREQ_HZ, + pac.XOSC, + pac.CLOCKS, + pac.PLL_SYS, + pac.PLL_USB, + &mut pac.RESETS, + &mut watchdog, + ) + .ok() + .unwrap(); + + let mut timer = rp2040_hal::Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); + + // The single-cycle I/O block controls our GPIO pins + let sio = hal::Sio::new(pac.SIO); + + // Set the pins to their default state + let pins = hal::gpio::Pins::new( + pac.IO_BANK0, + pac.PADS_BANK0, + sio.gpio_bank0, + &mut pac.RESETS, + ); + + // Configure GPIO25 as an output + let mut led_pin = pins.gpio25.into_push_pull_output(); + + let mut xs = Vec::new(); + xs.push(1); + + // Blink the LED at 1 Hz + loop { + led_pin.set_high().unwrap(); + let len = xs.len() as u32; + timer.delay_ms(100 * len); + xs.push(1); + led_pin.set_low().unwrap(); + timer.delay_ms(100 * len); + xs.push(1); + } +} + +// End of file