-
-
Save taunusflieger/77c7e46907d366b7f6fdbf1742e6f3bf to your computer and use it in GitHub Desktop.
Proof of concept of RTIC + Embassy on a Thingy:52
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![no_std] | |
#![no_main] | |
#![feature(type_alias_impl_trait)] | |
#![feature(alloc_error_handler)] | |
#![allow(incomplete_features)] | |
#![macro_use] | |
use alloc_cortex_m::CortexMHeap; | |
use core::alloc::Layout; | |
use core::mem; | |
use core::sync::atomic::{AtomicUsize, Ordering}; | |
use defmt::{info, panic, unreachable, *}; | |
use embassy::executor::Executor; | |
use embassy::util::Forever; | |
use embassy_nrf as _; | |
use nrf_softdevice::ble::peripheral; | |
use nrf_softdevice::{raw, Softdevice}; | |
use nrf_softdevice_defmt_rtt as _; // global logger | |
use panic_probe as _; | |
// this is the allocator the application will use | |
#[global_allocator] | |
static ALLOCATOR: CortexMHeap = CortexMHeap::empty(); | |
// define what happens in an Out Of Memory (OOM) condition | |
#[alloc_error_handler] | |
fn alloc_error(_layout: Layout) -> ! { | |
panic!("Alloc error"); | |
} | |
// used by global logger to add timestamps | |
defmt::timestamp! {"{=u64}", { | |
static COUNT: AtomicUsize = AtomicUsize::new(0); | |
// NOTE(no-CAS) `timestamps` runs with interrupts disabled | |
let n = COUNT.load(Ordering::Relaxed); | |
COUNT.store(n + 1, Ordering::Relaxed); | |
n as u64 | |
} | |
} | |
// declare global embassy executor | |
static EXECUTOR: Forever<Executor> = Forever::new(); | |
#[embassy::task] | |
async fn embassy_task() { | |
info!("hello from embassy_task"); | |
} | |
#[embassy::task] | |
async fn softdevice_task(sd: &'static Softdevice) { | |
sd.run().await; | |
} | |
#[embassy::task] | |
async fn bluetooth_task(sd: &'static Softdevice) { | |
#[rustfmt::skip] | |
let adv_data = &[ | |
0x02, 0x01, raw::BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE as u8, | |
0x03, 0x03, 0x09, 0x18, | |
0x0a, 0x09, b'H', b'e', b'l', b'l', b'o', b'R', b'u', b's', b't', | |
]; | |
#[rustfmt::skip] | |
let scan_data = &[ | |
0x03, 0x03, 0x09, 0x18, | |
]; | |
let mut config = peripheral::Config::default(); | |
config.interval = 50; | |
let adv = peripheral::NonconnectableAdvertisement::ScannableUndirected { | |
adv_data, | |
scan_data, | |
}; | |
unwrap!(peripheral::advertise(sd, adv, &config).await); | |
// advertise never returns | |
unreachable!(); | |
} | |
#[rtic::app(device = nrf52832_hal::pac, peripherals = true)] | |
const APP: () = { | |
struct Resources { | |
#[init(0)] | |
shared: u32, | |
} | |
#[init(resources=[shared])] | |
fn init(cx: init::Context) { | |
info!("Starting Init function"); | |
let shared: &mut u32 = cx.resources.shared; | |
info!("intial shared value is {:?}", shared); | |
*shared += 1; | |
info!( | |
"shared value after incrementaion is {}", | |
cx.resources.shared | |
); | |
} | |
#[idle(spawn=[foo])] | |
fn idle(cx: idle::Context) -> ! { | |
info!("Starting Idle function"); | |
let config = nrf_softdevice::Config { | |
clock: Some(raw::nrf_clock_lf_cfg_t { | |
source: raw::NRF_CLOCK_LF_SRC_RC as u8, | |
rc_ctiv: 4, | |
rc_temp_ctiv: 2, | |
accuracy: 7, | |
}), | |
conn_gap: Some(raw::ble_gap_conn_cfg_t { | |
conn_count: 6, | |
event_length: 24, | |
}), | |
conn_gatt: Some(raw::ble_gatt_conn_cfg_t { att_mtu: 256 }), | |
gatts_attr_tab_size: Some(raw::ble_gatts_cfg_attr_tab_size_t { | |
attr_tab_size: 8192, | |
}), | |
gap_role_count: Some(raw::ble_gap_cfg_role_count_t { | |
adv_set_count: 1, | |
periph_role_count: 3, | |
central_role_count: 3, | |
central_sec_count: 0, | |
_bitfield_1: raw::ble_gap_cfg_role_count_t::new_bitfield_1(0), | |
}), | |
gap_device_name: Some(raw::ble_gap_cfg_device_name_t { | |
p_value: b"HelloRust" as *const u8 as _, | |
current_len: 9, | |
max_len: 9, | |
write_perm: unsafe { mem::zeroed() }, | |
_bitfield_1: raw::ble_gap_cfg_device_name_t::new_bitfield_1( | |
raw::BLE_GATTS_VLOC_STACK as u8, | |
), | |
}), | |
..Default::default() | |
}; | |
let sd = Softdevice::enable(&config); | |
cx.spawn.foo().unwrap(); | |
let executor = EXECUTOR.put(Executor::new()); | |
executor.run(|spawner| { | |
unwrap!(spawner.spawn(embassy_task())); | |
unwrap!(spawner.spawn(softdevice_task(sd))); | |
unwrap!(spawner.spawn(bluetooth_task(sd))); | |
}); | |
} | |
#[task(resources=[shared])] | |
fn foo(cx: foo::Context) { | |
info!("hello from rtic"); | |
info!("shared value seen by foo is {:?}", cx.resources.shared); | |
} | |
extern "C" { | |
fn SWI0_EGU0(); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment