rtic/examples/hifive1/examples/prio_inheritance.rs
Román Cárdenas Rodríguez 4060c3def8
RISC-V support over CLINT (#815)
* Rebase to master

* using interrupt_mod

* bug fixes

* fix other backends

* Add changelog

* forgot about rtic-macros

* backend-specific configuration

* core peripherals optional over macro argument

* pre_init_preprocessing binding

* CI for RISC-V (WIP)

* separation of concerns

* add targets for RISC-V examples

* remove qemu feature

* prepare examples folder

* move examples all together

* move ci out of examples

* minor changes

* add cortex-m

* new xtask: proof of concept

* fix build.yml

* feature typo

* clean rtic examples

* reproduce weird issue

* remove unsafe code in user app

* update dependencies

* allow builds on riscv32imc

* let's fix QEMU

* Update .github/workflows/build.yml

Co-authored-by: Henrik Tjäder <henrik@tjaders.com>

* New build.rs

* removing test features

* adapt ui test to new version of clippy

* add more examples to RISC-V backend

* proper configuration of heapless for riscv32imc

* opt-out examples for riscv32imc

* point to new version of riscv-slic

* adapt new macro bindings

* adapt examples and CI to stable

* fix cortex-m CI

* Review

---------

Co-authored-by: Henrik Tjäder <henrik@tjaders.com>
2024-03-20 20:06:47 +00:00

140 lines
4.2 KiB
Rust

#![no_main]
#![no_std]
use riscv_rt as _;
#[rtic::app(device = e310x, backend = HART0)]
mod app {
use core::{future::Future, pin::Pin, task::Context, task::Poll};
use hifive1::hal::prelude::*;
use semihosting::{println, process::exit};
/// Dummy asynchronous function to showcase SW tasks
pub async fn yield_now(task: &str) {
/// Yield implementation
struct YieldNow {
yielded: bool,
}
println!(" [{}]: Yield", task);
impl Future for YieldNow {
type Output = ();
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
if self.yielded {
return Poll::Ready(());
}
self.yielded = true;
cx.waker().wake_by_ref();
Poll::Pending
}
}
YieldNow { yielded: false }.await
}
#[shared]
struct Shared {
counter: u32,
}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
// Pends the SoftLow interrupt but its handler won't run until *after*
// `init` returns because interrupts are disabled
let resources = unsafe { hifive1::hal::DeviceResources::steal() };
let peripherals = resources.peripherals;
let clocks =
hifive1::configure_clocks(peripherals.PRCI, peripherals.AONCLK, 64.mhz().into());
let gpio = resources.pins;
// Configure UART for stdout
hifive1::stdout::configure(
peripherals.UART0,
hifive1::pin!(gpio, uart0_tx),
hifive1::pin!(gpio, uart0_rx),
115_200.bps(),
clocks,
);
(Shared { counter: 0 }, Local {})
}
#[idle(shared = [counter])]
fn idle(mut cx: idle::Context) -> ! {
println!("[Idle]: Started");
// pend the medium priority SW task only once
soft_medium::spawn().unwrap();
cx.shared.counter.lock(|counter| {
println!("[Idle]: Shared: {}", *counter);
});
// exit QEMU simulator
println!("[Idle]: Finished");
exit(0);
}
/// Medium priority SW task. It is triggered by the idle and spawns the rest of the SW tasks
#[task(shared = [counter], priority = 2)]
async fn soft_medium(mut cx: soft_medium::Context) {
// Safe access to local `static mut` variable
println!(" [SoftMedium]: Started");
cx.shared.counter.lock(|counter| {
// Spawn the other SW tasks INSIDE the critical section (just for showing priority inheritance)
soft_low_1::spawn().unwrap();
soft_high::spawn().unwrap();
soft_low_2::spawn().unwrap();
*counter += 1;
println!(" [SoftMedium]: Shared: {}", *counter);
});
println!(" [SoftMedium]: Finished");
}
/// Low priority SW task. It runs cooperatively with soft_low_2
#[task(shared = [counter], priority = 1)]
async fn soft_low_1(mut cx: soft_low_1::Context) {
println!(" [SoftLow1]: Started");
cx.shared.counter.lock(|counter| {
*counter += 1;
println!(" [SoftLow1]: Shared: {}", *counter);
});
// Yield to the other SW task
yield_now("SoftLow1").await;
println!(" [SoftLow1]: Finished");
}
/// Low priority SW task. It runs cooperatively with soft_low_2
#[task(shared = [counter], priority = 1)]
async fn soft_low_2(mut cx: soft_low_2::Context) {
println!(" [SoftLow2]: Started");
cx.shared.counter.lock(|counter| {
*counter += 1;
println!(" [SoftLow2]: Shared: {}", *counter);
});
// Yield to the other SW task
yield_now("SoftLow2").await;
println!(" [SoftLow2]: Finished");
}
/// High priority SW task
#[task(shared = [counter], priority = 3)]
async fn soft_high(mut cx: soft_high::Context) {
println!(" [SoftHigh]: Started");
cx.shared.counter.lock(|counter| {
*counter += 1;
println!(" [SoftHigh]: Shared: {}", counter);
});
println!(" [SoftHigh]: Finished");
}
}