From c029601b7c55a64af6af8c544ddcffabc55a7f1d Mon Sep 17 00:00:00 2001 From: Per Date: Wed, 25 Sep 2019 18:39:32 +0200 Subject: [PATCH] wip, gen_ok, handwritten POC --- examples/gen_ok.rs | 352 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 352 insertions(+) create mode 100644 examples/gen_ok.rs diff --git a/examples/gen_ok.rs b/examples/gen_ok.rs new file mode 100644 index 0000000000..076bb81557 --- /dev/null +++ b/examples/gen_ok.rs @@ -0,0 +1,352 @@ +#![feature(prelude_import)] +//! examples/idle.rs +#![feature(generator_trait)] +#![feature(generators)] +#![feature(never_type)] +#![feature(type_alias_impl_trait)] +#![feature(const_fn)] +#![feature(fmt_internals)] +#![feature(compiler_builtins_lib)] +#![no_main] +#![no_std] +#[rustfmt::skip] +#[prelude_import] +use core::prelude::v1::*; +#[macro_use] +extern crate core; +#[macro_use] +extern crate compiler_builtins; + +use core::ops::Generator; +use cortex_m_semihosting::{debug, hprintln}; +use lm3s6965::Interrupt; +use panic_semihosting as _; +use rtfm::{Exclusive, Mutex}; + +#[allow(non_snake_case)] +fn init(_: init::Context) { + // #[task(binds = GPIOA, resources = [shared2])] + // // fn foo1(ctx: &'static mut foo1::Context) -> impl Generator { + // fn foo1(mut ctx: foo1::Context) -> impl Generator { + // let mut local = 0; + // //let shared_res = Exclusive(ctx.resources.shared); + // // static shared_res : &mut u32 = ctx.resources.shared; + // // hprintln!("init foo1: {}", ctx.resources.shared); + // static mut X: u32 = 0; + // // let mut e = Exclusive(unsafe { &mut X }); + // // //let mut e = Exclusive(ctx.resources.shared); + // // hprintln!( + // // "ex {:?}", + // // e.lock(|v| { + // // *v += 1; + // // *v + // // }) + // // ) + // // .unwrap(); + // hprintln!("{}", ctx.resources.shared2.lock(|v| *v)); + // move || loop { + // hprintln!("foo1_1 {} {}", local, unsafe { X }).unwrap(); + // // hprintln!( + // // "ex {}", + // // e.lock(|v| { + // // *v += 1; + // // *v + // // }) + // // ) + // // .unwrap(); + + // local += 1; + // // shared_res.lock(|s| hprintln!("s {}", s)); + // // *shared_res += 1; + // // *ctx.resources.shared += 1; + // unsafe { X += 1 }; + // yield; + // hprintln!("foo1_2 {} {}", local, unsafe { X }).unwrap(); + // local += 1; + // // unsafe { X += 1 }; + // yield; + // } + // } + + // ctx.resources.shared2.lock(|v| *v); + // hprintln!("{}", ctx.resources.shared2.lock(|v| *v)).unwrap(); + + ::cortex_m_semihosting::export::hstdout_str("init\n").unwrap(); + rtfm::pend(Interrupt::GPIOA); +} +#[allow(non_snake_case)] +fn idle(_: idle::Context) -> ! { + use rtfm::Mutex as _; + ::cortex_m_semihosting::export::hstdout_str("idle\n").unwrap(); + rtfm::pend(Interrupt::GPIOA); + ::cortex_m_semihosting::export::hstdout_str("idle1\n").unwrap(); + rtfm::pend(Interrupt::GPIOA); + debug::exit(debug::EXIT_SUCCESS); + loop {} +} +#[rustfmt::skip] +type Generatorfoo1= impl Generator; +static mut GENERATOR_FOO1: core::mem::MaybeUninit = + core::mem::MaybeUninit::uninit(); +#[allow(non_snake_case)] +fn foo1(mut ctx: foo1::Context) -> Generatorfoo1 { + use rtfm::Mutex as _; + // ctx.resources.shared2.lock(|v| *v); + move || loop { + ctx.resources.shared2.lock(|v| { + *v += 1; + hprintln!("{}", v) + }); + ::cortex_m_semihosting::export::hstdout_str("foo1_1\n").unwrap(); + yield; + ctx.resources.shared2.lock(|v| { + *v += 1; + hprintln!("{}", v) + }); + ::cortex_m_semihosting::export::hstdout_str("foo1_2\n").unwrap(); + yield; + } +} +#[allow(non_snake_case)] +fn foo2(mut ctx: foo2::Context) { + use rtfm::Mutex as _; + ctx.resources.shared2.lock(|v| *v += 1); +} +#[allow(non_snake_case)] +fn foo3(mut ctx: foo3::Context) { + use rtfm::Mutex as _; + ctx.resources.shared2.lock(|v| *v += 1); +} +#[allow(non_snake_case)] +#[doc = "Initialization function"] +pub mod init { + fn plepps() {} + #[doc = r" Execution context"] + pub struct Context { + #[doc = r" Core (Cortex-M) peripherals"] + pub core: rtfm::export::Peripherals, + } + impl Context { + #[inline(always)] + pub unsafe fn new(core: rtfm::export::Peripherals) -> Self { + Context { core } + } + } +} +#[allow(non_snake_case)] +#[doc = "Idle loop"] +pub mod idle { + fn plepps() {} + #[doc = r" Execution context"] + pub struct Context {} + impl Context { + #[inline(always)] + pub unsafe fn new(priority: rtfm::export::Priority) -> Self { + Context {} + } + } +} +mod resources { + use rtfm::export::Priority; + #[allow(non_camel_case_types)] + pub struct shared2 { + priority: Priority, + } + impl shared2 { + #[inline(always)] + pub unsafe fn new(priority: Priority) -> Self { + shared2 { priority } + } + #[inline(always)] + pub unsafe fn priority(&self) -> Priority { + self.priority.clone() + } + } +} +#[allow(non_snake_case)] +#[doc = "Resources `foo1` has access to"] +pub struct foo1Resources { + pub shared2: resources::shared2, +} +#[allow(non_snake_case)] +#[doc = "Hardware task"] +pub mod foo1 { + fn plepps() {} + #[doc(inline)] + pub use super::foo1Resources as Resources; + #[doc = r" Execution context"] + pub struct Context { + #[doc = r" Resources this task has access to"] + pub resources: Resources, + } + impl<'a> Context { + #[inline(always)] + pub unsafe fn new(priority: rtfm::export::Priority) -> Self { + Context { + resources: Resources::new(priority), + } + } + } +} +#[allow(non_snake_case)] +#[doc = "Resources `foo2` has access to"] +pub struct foo2Resources { + pub shared2: resources::shared2, +} +#[allow(non_snake_case)] +#[doc = "Hardware task"] +pub mod foo2 { + fn plepps() {} + #[doc(inline)] + pub use super::foo2Resources as Resources; + #[doc = r" Execution context"] + pub struct Context { + #[doc = r" Resources this task has access to"] + pub resources: Resources, + } + impl Context { + #[inline(always)] + pub unsafe fn new(priority: rtfm::export::Priority) -> Self { + Context { + resources: Resources::new(priority), + } + } + } +} +#[allow(non_snake_case)] +#[doc = "Resources `foo3` has access to"] +pub struct foo3Resources { + pub shared2: resources::shared2, +} +#[allow(non_snake_case)] +#[doc = "Hardware task"] +pub mod foo3 { + fn plepps() {} + #[doc(inline)] + pub use super::foo3Resources as Resources; + #[doc = r" Execution context"] + pub struct Context { + #[doc = r" Resources this task has access to"] + pub resources: Resources, + } + impl Context { + #[inline(always)] + pub unsafe fn new(priority: rtfm::export::Priority) -> Self { + Context { + resources: Resources::new(priority), + } + } + } +} +#[doc = r" Implementation details"] +const APP: () = { + #[doc = r" Always include the device crate which contains the vector table"] + use lm3s6965 as _; + #[allow(non_upper_case_globals)] + static mut shared2: u32 = 1; + impl<'a> rtfm::Mutex for resources::shared2 { + type T = u32; + #[inline(always)] + fn lock(&mut self, f: impl FnOnce(&mut u32) -> R) -> R { + #[doc = r" Priority ceiling"] + const CEILING: u8 = 3u8; + unsafe { + rtfm::export::lock( + &mut shared2, + &self.priority(), + CEILING, + lm3s6965::NVIC_PRIO_BITS, + f, + ) + } + } + } + #[allow(non_snake_case)] + #[no_mangle] + unsafe fn GPIOA() { + const PRIORITY: u8 = 1u8; + rtfm::export::run(PRIORITY, || { + ::cortex_m_semihosting::export::hstdout_str("interrupt dispatch\n") + .unwrap(); + let mut g: &mut dyn Generator = + &mut *GENERATOR_FOO1.as_mut_ptr(); + core::pin::Pin::new_unchecked(&mut *g).resume(); + }); + } + impl foo1Resources { + #[inline(always)] + unsafe fn new(priority: rtfm::export::Priority) -> Self { + foo1Resources { + shared2: resources::shared2::new(priority), + } + } + } + #[allow(non_snake_case)] + #[no_mangle] + unsafe fn GPIOB() { + const PRIORITY: u8 = 2u8; + rtfm::export::run(PRIORITY, || { + crate::foo2(foo2::Context::new(rtfm::export::Priority::new( + PRIORITY, + ))) + }); + } + impl<'a> foo2Resources { + #[inline(always)] + unsafe fn new(priority: rtfm::export::Priority) -> Self { + foo2Resources { + shared2: resources::shared2::new(priority), + } + } + } + #[allow(non_snake_case)] + #[no_mangle] + unsafe fn GPIOC() { + const PRIORITY: u8 = 3u8; + rtfm::export::run(PRIORITY, || { + crate::foo3(foo3::Context::new(rtfm::export::Priority::new( + PRIORITY, + ))) + }); + } + impl foo3Resources { + #[inline(always)] + unsafe fn new(priority: rtfm::export::Priority) -> Self { + foo3Resources { + shared2: resources::shared2::new(priority), + } + } + } + #[no_mangle] + unsafe extern "C" fn main() -> ! { + rtfm::export::interrupt::disable(); + let mut core: rtfm::export::Peripherals = core::mem::transmute(()); + let _ = [(); ((1 << lm3s6965::NVIC_PRIO_BITS) - 1u8 as usize)]; + core.NVIC.set_priority( + lm3s6965::Interrupt::GPIOA, + rtfm::export::logical2hw(1u8, lm3s6965::NVIC_PRIO_BITS), + ); + rtfm::export::NVIC::unmask(lm3s6965::Interrupt::GPIOA); + let _ = [(); ((1 << lm3s6965::NVIC_PRIO_BITS) - 2u8 as usize)]; + core.NVIC.set_priority( + lm3s6965::Interrupt::GPIOB, + rtfm::export::logical2hw(2u8, lm3s6965::NVIC_PRIO_BITS), + ); + rtfm::export::NVIC::unmask(lm3s6965::Interrupt::GPIOB); + let _ = [(); ((1 << lm3s6965::NVIC_PRIO_BITS) - 3u8 as usize)]; + core.NVIC.set_priority( + lm3s6965::Interrupt::GPIOC, + rtfm::export::logical2hw(3u8, lm3s6965::NVIC_PRIO_BITS), + ); + rtfm::export::NVIC::unmask(lm3s6965::Interrupt::GPIOC); + let late = init(init::Context::new(core.into())); + const PRIORITY: u8 = 1u8; + unsafe { + GENERATOR_FOO1.as_mut_ptr().write(foo1(foo1::Context::new( + rtfm::export::Priority::new(PRIORITY), + ))); + }; + rtfm::export::interrupt::enable(); + idle(idle::Context::new(rtfm::export::Priority::new(0))) + } +};