Skip to content

Instantly share code, notes, and snippets.

@jessebraham
Created July 24, 2024 23:03
Show Gist options
  • Save jessebraham/e825f8e7825aa8926254796d642b8a62 to your computer and use it in GitHub Desktop.
Save jessebraham/e825f8e7825aa8926254796d642b8a62 to your computer and use it in GitHub Desktop.
#![feature(prelude_import)]
#![no_main]
#![no_std]
#[prelude_import]
use core::prelude::rust_2021::*;
#[macro_use]
extern crate core;
extern crate compiler_builtins as _;
/// The RTIC application module
pub mod app {
/// Always include the device crate which contains the vector table
use esp32c3 as you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml;
/// Holds the maximum priority level for use by async HAL drivers.
#[no_mangle]
static RTIC_ASYNC_MAX_LOGICAL_PRIO: u8 = 2u8;
use esp_backtrace as _;
use esp_hal::{
gpio::{Event, GpioPin, Input, Io, Pull},
peripherals::Peripherals,
};
use esp_println::println;
/// User code end
///Shared resources
struct Shared {}
///Local resources
struct Local {
button: Input<'static, GpioPin<9>>,
}
/// Execution context
#[allow(non_snake_case)]
#[allow(non_camel_case_types)]
pub struct __rtic_internal_init_Context<'a> {
#[doc(hidden)]
__rtic_internal_p: ::core::marker::PhantomData<&'a ()>,
/// The space used to allocate async executors in bytes.
pub executors_size: usize,
/// Core peripherals
pub core: rtic::export::Peripherals,
/// Device peripherals (PAC)
pub device: esp32c3::Peripherals,
/// Critical section token for init
pub cs: rtic::export::CriticalSection<'a>,
}
impl<'a> __rtic_internal_init_Context<'a> {
#[inline(always)]
#[allow(missing_docs)]
pub unsafe fn new(
core: rtic::export::Peripherals,
executors_size: usize,
) -> Self {
__rtic_internal_init_Context {
__rtic_internal_p: ::core::marker::PhantomData,
core: core,
device: esp32c3::Peripherals::steal(),
cs: rtic::export::CriticalSection::new(),
executors_size,
}
}
}
#[allow(non_snake_case)]
///Initialization function
pub mod init {
#[doc(inline)]
pub use super::__rtic_internal_init_Context as Context;
}
#[inline(always)]
#[allow(non_snake_case)]
fn init(_: init::Context) -> (Shared, Local) {
{
{
use core::fmt::Write;
::esp_println::Printer.write_fmt(format_args!("init\n")).ok();
}
};
let peripherals = Peripherals::take();
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let mut button = Input::new(io.pins.gpio9, Pull::Up);
button.listen(Event::FallingEdge);
foo::spawn().unwrap();
(Shared {}, Local { button })
}
/// Execution context
#[allow(non_snake_case)]
#[allow(non_camel_case_types)]
pub struct __rtic_internal_idle_Context<'a> {
#[doc(hidden)]
__rtic_internal_p: ::core::marker::PhantomData<&'a ()>,
}
impl<'a> __rtic_internal_idle_Context<'a> {
#[inline(always)]
#[allow(missing_docs)]
pub unsafe fn new() -> Self {
__rtic_internal_idle_Context {
__rtic_internal_p: ::core::marker::PhantomData,
}
}
}
#[allow(non_snake_case)]
///Idle loop
pub mod idle {
#[doc(inline)]
pub use super::__rtic_internal_idle_Context as Context;
}
#[allow(non_snake_case)]
fn idle(_: idle::Context) -> ! {
use rtic::Mutex as _;
use rtic::mutex::prelude::*;
{
{
use core::fmt::Write;
::esp_println::Printer.write_fmt(format_args!("idle\n")).ok();
}
};
loop {}
}
#[allow(non_snake_case)]
#[no_mangle]
#[export_name = "interrupt18"]
unsafe fn GPIO() {
const PRIORITY: u8 = 3u8;
rtic::export::run(PRIORITY, || { gpio_handler(gpio_handler::Context::new()) });
}
impl<'a> __rtic_internal_gpio_handlerLocalResources<'a> {
#[inline(always)]
#[allow(missing_docs)]
pub unsafe fn new() -> Self {
__rtic_internal_gpio_handlerLocalResources {
button: &mut *(&mut *__rtic_internal_local_resource_button.get_mut())
.as_mut_ptr(),
__rtic_internal_marker: ::core::marker::PhantomData,
}
}
}
#[allow(non_snake_case)]
#[allow(non_camel_case_types)]
///Local resources `gpio_handler` has access to
pub struct __rtic_internal_gpio_handlerLocalResources<'a> {
#[allow(missing_docs)]
pub button: &'a mut Input<'static, GpioPin<9>>,
#[doc(hidden)]
pub __rtic_internal_marker: ::core::marker::PhantomData<&'a ()>,
}
/// Execution context
#[allow(non_snake_case)]
#[allow(non_camel_case_types)]
pub struct __rtic_internal_gpio_handler_Context<'a> {
#[doc(hidden)]
__rtic_internal_p: ::core::marker::PhantomData<&'a ()>,
/// Local Resources this task has access to
pub local: gpio_handler::LocalResources<'a>,
}
impl<'a> __rtic_internal_gpio_handler_Context<'a> {
#[inline(always)]
#[allow(missing_docs)]
pub unsafe fn new() -> Self {
__rtic_internal_gpio_handler_Context {
__rtic_internal_p: ::core::marker::PhantomData,
local: gpio_handler::LocalResources::new(),
}
}
}
#[allow(non_snake_case)]
///Hardware task
pub mod gpio_handler {
#[doc(inline)]
pub use super::__rtic_internal_gpio_handlerLocalResources as LocalResources;
#[doc(inline)]
pub use super::__rtic_internal_gpio_handler_Context as Context;
}
#[allow(non_snake_case)]
fn gpio_handler(cx: gpio_handler::Context) {
use rtic::Mutex as _;
use rtic::mutex::prelude::*;
cx.local.button.clear_interrupt();
{
{
use core::fmt::Write;
::esp_println::Printer.write_fmt(format_args!("button\n")).ok();
}
};
}
/// Execution context
#[allow(non_snake_case)]
#[allow(non_camel_case_types)]
pub struct __rtic_internal_foo_Context<'a> {
#[doc(hidden)]
__rtic_internal_p: ::core::marker::PhantomData<&'a ()>,
}
impl<'a> __rtic_internal_foo_Context<'a> {
#[inline(always)]
#[allow(missing_docs)]
pub unsafe fn new() -> Self {
__rtic_internal_foo_Context {
__rtic_internal_p: ::core::marker::PhantomData,
}
}
}
/// Spawns the task directly
#[allow(non_snake_case)]
#[doc(hidden)]
pub fn __rtic_internal_foo_spawn() -> Result<(), ()> {
unsafe {
let exec = rtic::export::executor::AsyncTaskExecutor::from_ptr_1_args(
foo,
&__rtic_internal_foo_EXEC,
);
if exec.try_allocate() {
exec.spawn(foo(unsafe { foo::Context::new() }));
rtic::export::pend(esp32c3::Interrupt::FROM_CPU_INTR1);
Ok(())
} else {
Err(())
}
}
}
#[allow(non_snake_case)]
///Software task
pub mod foo {
#[doc(inline)]
pub use super::__rtic_internal_foo_Context as Context;
#[doc(inline)]
pub use super::__rtic_internal_foo_spawn as spawn;
}
/// Execution context
#[allow(non_snake_case)]
#[allow(non_camel_case_types)]
pub struct __rtic_internal_bar_Context<'a> {
#[doc(hidden)]
__rtic_internal_p: ::core::marker::PhantomData<&'a ()>,
}
impl<'a> __rtic_internal_bar_Context<'a> {
#[inline(always)]
#[allow(missing_docs)]
pub unsafe fn new() -> Self {
__rtic_internal_bar_Context {
__rtic_internal_p: ::core::marker::PhantomData,
}
}
}
/// Spawns the task directly
#[allow(non_snake_case)]
#[doc(hidden)]
pub fn __rtic_internal_bar_spawn() -> Result<(), ()> {
unsafe {
let exec = rtic::export::executor::AsyncTaskExecutor::from_ptr_1_args(
bar,
&__rtic_internal_bar_EXEC,
);
if exec.try_allocate() {
exec.spawn(bar(unsafe { bar::Context::new() }));
rtic::export::pend(esp32c3::Interrupt::FROM_CPU_INTR0);
Ok(())
} else {
Err(())
}
}
}
#[allow(non_snake_case)]
///Software task
pub mod bar {
#[doc(inline)]
pub use super::__rtic_internal_bar_Context as Context;
#[doc(inline)]
pub use super::__rtic_internal_bar_spawn as spawn;
}
#[allow(non_snake_case)]
async fn foo<'a>(_: foo::Context<'a>) {
use rtic::Mutex as _;
use rtic::mutex::prelude::*;
bar::spawn().unwrap();
{
{
use core::fmt::Write;
::esp_println::Printer
.write_fmt(
format_args!("Inside high prio task, press button now!\n"),
)
.ok();
}
};
let mut x = 0;
while x < 5000000 {
x += 1;
esp_hal::riscv::asm::nop();
}
{
{
use core::fmt::Write;
::esp_println::Printer
.write_fmt(format_args!("Leaving high prio task.\n"))
.ok();
}
};
}
#[allow(non_snake_case)]
async fn bar<'a>(_: bar::Context<'a>) {
use rtic::Mutex as _;
use rtic::mutex::prelude::*;
{
{
use core::fmt::Write;
::esp_println::Printer
.write_fmt(format_args!("Inside low prio task, press button now!\n"))
.ok();
}
};
let mut x = 0;
while x < 5000000 {
x += 1;
esp_hal::riscv::asm::nop();
}
{
{
use core::fmt::Write;
::esp_println::Printer
.write_fmt(format_args!("Leaving low prio task.\n"))
.ok();
}
};
}
#[allow(non_camel_case_types)]
#[allow(non_upper_case_globals)]
#[doc(hidden)]
#[link_section = ".uninit.rtic0"]
static __rtic_internal_local_resource_button: rtic::RacyCell<
core::mem::MaybeUninit<Input<'static, GpioPin<9>>>,
> = rtic::RacyCell::new(core::mem::MaybeUninit::uninit());
#[allow(non_upper_case_globals)]
static __rtic_internal_foo_EXEC: rtic::export::executor::AsyncTaskExecutorPtr = rtic::export::executor::AsyncTaskExecutorPtr::new();
#[allow(non_upper_case_globals)]
static __rtic_internal_bar_EXEC: rtic::export::executor::AsyncTaskExecutorPtr = rtic::export::executor::AsyncTaskExecutorPtr::new();
#[allow(non_snake_case)]
///Interrupt handler to dispatch async tasks at priority 2
#[no_mangle]
#[export_name = "interrupt16"]
unsafe fn FROM_CPU_INTR0() {
rtic::export::unpend(rtic::export::Interrupt::FROM_CPU_INTR0);
/// The priority of this interrupt handler
const PRIORITY: u8 = 2u8;
rtic::export::run(
PRIORITY,
|| {
let exec = rtic::export::executor::AsyncTaskExecutor::from_ptr_1_args(
bar,
&__rtic_internal_bar_EXEC,
);
exec.poll(|| {
let exec = rtic::export::executor::AsyncTaskExecutor::from_ptr_1_args(
bar,
&__rtic_internal_bar_EXEC,
);
exec.set_pending();
rtic::export::pend(esp32c3::Interrupt::FROM_CPU_INTR0);
});
},
);
}
#[allow(non_snake_case)]
///Interrupt handler to dispatch async tasks at priority 5
#[no_mangle]
#[export_name = "interrupt17"]
unsafe fn FROM_CPU_INTR1() {
rtic::export::unpend(rtic::export::Interrupt::FROM_CPU_INTR1);
/// The priority of this interrupt handler
const PRIORITY: u8 = 5u8;
rtic::export::run(
PRIORITY,
|| {
let exec = rtic::export::executor::AsyncTaskExecutor::from_ptr_1_args(
foo,
&__rtic_internal_foo_EXEC,
);
exec.poll(|| {
let exec = rtic::export::executor::AsyncTaskExecutor::from_ptr_1_args(
foo,
&__rtic_internal_foo_EXEC,
);
exec.set_pending();
rtic::export::pend(esp32c3::Interrupt::FROM_CPU_INTR1);
});
},
);
}
#[doc(hidden)]
#[no_mangle]
unsafe extern "C" fn main() -> ! {
rtic::export::interrupt::disable();
let mut core: rtic::export::Peripherals = rtic::export::Peripherals::steal()
.into();
let _ = you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::Interrupt::FROM_CPU_INTR0;
let _ = you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::Interrupt::FROM_CPU_INTR1;
const _: () = if (15usize) <= 2u8 as usize {
{
::core::panicking::panic_fmt(
format_args!(
"Maximum priority used by interrupt vector \'FROM_CPU_INTR0\' is more than supported by hardware",
),
);
};
};
rtic::export::enable(
you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::Interrupt::FROM_CPU_INTR0,
2u8,
16u8,
);
const _: () = if (15usize) <= 5u8 as usize {
{
::core::panicking::panic_fmt(
format_args!(
"Maximum priority used by interrupt vector \'FROM_CPU_INTR1\' is more than supported by hardware",
),
);
};
};
rtic::export::enable(
you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::Interrupt::FROM_CPU_INTR1,
5u8,
17u8,
);
const _: () = if (15usize) <= 3u8 as usize {
{
::core::panicking::panic_fmt(
format_args!(
"Maximum priority used by interrupt vector \'GPIO\' is more than supported by hardware",
),
);
};
};
rtic::export::enable(
you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::Interrupt::GPIO,
3u8,
18u8,
);
#[inline(never)]
fn __rtic_init_resources<F>(f: F)
where
F: FnOnce(),
{
f();
}
let mut executors_size = 0;
let executor = ::core::mem::ManuallyDrop::new(
rtic::export::executor::AsyncTaskExecutor::new_1_args(foo),
);
executors_size += ::core::mem::size_of_val(&executor);
__rtic_internal_foo_EXEC.set_in_main(&executor);
let executor = ::core::mem::ManuallyDrop::new(
rtic::export::executor::AsyncTaskExecutor::new_1_args(bar),
);
executors_size += ::core::mem::size_of_val(&executor);
__rtic_internal_bar_EXEC.set_in_main(&executor);
extern "C" {
pub static _stack_start: u32;
pub static _bss_end: u32;
}
let stack_start = &_stack_start as *const _ as u32;
let ebss = &_bss_end as *const _ as u32;
if stack_start > ebss {
if rtic::export::read_sp() <= ebss {
{
::core::panicking::panic_fmt(
format_args!("Stack overflow after allocating executors"),
);
};
}
}
__rtic_init_resources(|| {
let (shared_resources, local_resources) = init(
init::Context::new(core.into(), executors_size),
);
__rtic_internal_local_resource_button
.get_mut()
.write(core::mem::MaybeUninit::new(local_resources.button));
rtic::export::interrupt::enable();
});
idle(idle::Context::new())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment