// Embassy async loop. // Show timers, tasks, and printing together. // This is why a framework can beat a hand-written loop. #![allow(unsafe_code)] #![no_std] #![no_main] use cortex_m_semihosting::hprintln; use embassy_executor::Spawner; use embassy_time::{Duration, Ticker, Timer}; use panic_probe as _; // Stub out interrupts that the PAC expects but this chapter does not use. #[allow(non_snake_case)] #[unsafe(no_mangle)] pub extern "C" fn USB_HP_CAN1_TX() {} // Stub out interrupts that the PAC expects but this chapter does not use. #[allow(non_snake_case)] #[unsafe(no_mangle)] pub extern "C" fn USB_LP_CAN1_RX0() {} // Stub out interrupts that the PAC expects but this chapter does not use. #[allow(non_snake_case)] #[unsafe(no_mangle)] pub extern "C" fn CAN1_RX1() {} // Stub out interrupts that the PAC expects but this chapter does not use. #[allow(non_snake_case)] #[unsafe(no_mangle)] pub extern "C" fn CAN1_SCE() {} // Stub out interrupts that the PAC expects but this chapter does not use. #[allow(non_snake_case)] #[unsafe(no_mangle)] pub extern "C" fn RTC_ALARM() {} // Stub out interrupts that the PAC expects but this chapter does not use. #[allow(non_snake_case)] #[unsafe(no_mangle)] pub extern "C" fn USBWAKEUP() {} #[embassy_executor::task] async fn heartbeat() { let mut ticker = Ticker::every(Duration::from_secs(1)); loop { ticker.next().await; hprintln!("embassy heartbeat"); } } #[embassy_executor::main] async fn main(spawner: Spawner) { let _p = embassy_stm32::init(Default::default()); hprintln!("embassy boot"); spawner.spawn(heartbeat()).unwrap(); loop { Timer::after_secs(2).await; hprintln!("embassy main loop"); } }