Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,48 @@ jobs:
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-
- run: ./msrv-all.sh

build_riscv:
runs-on: ubuntu-latest
strategy:
matrix:
toolchain:
- nightly
target:
- riscv32imac-unknown-none-elf
- riscv64gc-unknown-none-elf
steps:
- uses: actions/checkout@v4
- run: rm rust-toolchain.toml
- run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} && rustup target add ${{ matrix.target }} && rustup component add rust-src --toolchain ${{ matrix.toolchain }}-x86_64-unknown-linux-gnu
- run: ./testsuite/riscv-virt/build.sh ${{ matrix.target }}
- name: Archive riscv-virt-${{ matrix.target}} image
uses: actions/upload-artifact@v4
with:
name: riscv-image-${{ matrix.toolchain }}-${{ matrix.target }}
path: |
target/${{ matrix.target }}/debug/lilos-testsuite-riscv-virt


test_qemu_riscv:
needs: build_riscv
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
- name: Install qemu riscv simulators
run: |
sudo apt-get update
sudo apt-get install qemu-system-misc
- run: >
qemu-system-riscv32
-machine virt
-nographic
-semihosting-config enable=on,target=native
-bios riscv-image-nightly-riscv32imac-unknown-none-elf/lilos-testsuite-riscv-virt
- run: >
qemu-system-riscv64
-machine virt
-nographic
-semihosting-config enable=on,target=native
-bios riscv-image-nightly-riscv64gc-unknown-none-elf/lilos-testsuite-riscv-virt

76 changes: 75 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ members = [
"testsuite/stm32f4",
"testsuite/stm32g0",
"testsuite/lm3s6965",
"testsuite/riscv-virt",
]

[workspace.package]
Expand Down Expand Up @@ -41,6 +42,14 @@ stm32-metapac = {version = "15.0", features = ["rt", "pac"]}
rp2040-pac = {version = "0.3", features = ["rt"]}
rp2040-boot2 = "0.2"
scopeguard = { version = "1.2.0", default-features = false }
# Note: we use github versions of riscv crates to get this changeset:
# https://github.com/rust-embedded/riscv/commit/ff4dc30bf74a4ec16370f12be9c6e45306efd5d0
#
# Should switch to stable versions when a new release is available.
riscv = { git = "https://github.com/rust-embedded/riscv.git", features = ["critical-section-single-hart"] }
riscv-rt = { git = "https://github.com/rust-embedded/riscv.git" }
riscv-semihosting = { git = "https://github.com/rust-embedded/riscv.git" }
riscv-peripheral = { git = "https://github.com/rust-embedded/riscv.git" }

#
# Before you get excited about turning on the workspace.lints table here, note
Expand Down
4 changes: 2 additions & 2 deletions doc/intro.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ fn main() {
p.LASER_SHARK,
));

lilos::time::initialize_sys_tick(
lilos::cortex_m_timer::initialize_sys_tick(
&mut cp.SYST,
16_000_000, <7>
);
Expand Down Expand Up @@ -1057,7 +1057,7 @@ which uses the SysTick timer common to all ARM Cortex-M CPUs.
TIP: `lilos::time` is available if {os} was built with the `systick` feature,
which is on by default.

To use this module, make sure you're calling `lilos::time::initialize_sys_tick`
To use this module, make sure you're calling `lilos::cortex_m_timer::initialize_sys_tick`
in your `main` function!

For precisely timing a periodic task in a loop, use `lilos::time::PeriodicGate`.
Expand Down
2 changes: 1 addition & 1 deletion examples/rp2040/minimal/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ fn main() -> ! {

// Configure the systick timer for 1kHz ticks at the default ROSC speed of
// _roughly_ 6 MHz.
lilos::time::initialize_sys_tick(&mut cp.SYST, 6_000_000);
lilos::cortex_m_timer::initialize_sys_tick(&mut cp.SYST, 6_000_000);
// Set up and run the scheduler with a single task.
lilos::exec::run_tasks(
&mut [blink], // <-- array of tasks
Expand Down
2 changes: 1 addition & 1 deletion examples/stm32f4/blinky/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ fn main() -> ! {

// Set up the OS timer. This can be done before or after starting the
// scheduler, but must be done before using any timer features.
lilos::time::initialize_sys_tick(&mut cp.SYST, 16_000_000);
lilos::cortex_m_timer::initialize_sys_tick(&mut cp.SYST, 16_000_000);

// Run our four tasks in parallel. The final parameter specifies which tasks
// to poll on the first iteration.
Expand Down
2 changes: 1 addition & 1 deletion examples/stm32f4/minimal/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fn main() -> ! {
});

// Configure the systick timer for 1kHz ticks at 16MHz.
lilos::time::initialize_sys_tick(&mut cp.SYST, 16_000_000);
lilos::cortex_m_timer::initialize_sys_tick(&mut cp.SYST, 16_000_000);
// Set up and run the scheduler with a single task.
lilos::exec::run_tasks(
&mut [blink], // <-- array of tasks
Expand Down
2 changes: 1 addition & 1 deletion examples/stm32f4/uart-echo/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ fn main() -> ! {
device::GPIOD.moder().modify(|w| w.set_moder(15, Moder::OUTPUT));

// Set up and run the scheduler.
lilos::time::initialize_sys_tick(&mut cp.SYST, CLOCK_HZ);
lilos::cortex_m_timer::initialize_sys_tick(&mut cp.SYST, CLOCK_HZ);
lilos::exec::run_tasks_with_idle(
&mut [heartbeat, echo],
lilos::exec::ALL_TASKS,
Expand Down
2 changes: 1 addition & 1 deletion examples/stm32g031/minimal/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ fn main() -> ! {
});

// Configure the systick timer for 1kHz ticks at 16MHz.
lilos::time::initialize_sys_tick(&mut cp.SYST, 16_000_000);
lilos::cortex_m_timer::initialize_sys_tick(&mut cp.SYST, 16_000_000);
// Set up and run the scheduler with a single task.
lilos::exec::run_tasks(
&mut [blink], // <-- array of tasks
Expand Down
2 changes: 1 addition & 1 deletion examples/stm32h7/minimal/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ fn main() -> ! {

// Configure the systick timer for 1kHz ticks at 64MHz (the speed the CPU is
// running at when it leaves reset).
lilos::time::initialize_sys_tick(&mut cp.SYST, 64_000_000);
lilos::cortex_m_timer::initialize_sys_tick(&mut cp.SYST, 64_000_000);
// Set up and run the scheduler with a single task.
lilos::exec::run_tasks(
&mut [blink], // <-- array of tasks
Expand Down
2 changes: 1 addition & 1 deletion examples/stm32h7/uart-echo/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ fn main() -> ! {
));

// Set up and run the scheduler.
lilos::time::initialize_sys_tick(&mut cp.SYST, CLOCK_HZ);
lilos::cortex_m_timer::initialize_sys_tick(&mut cp.SYST, CLOCK_HZ);
lilos::exec::run_tasks_with_idle(
&mut [heartbeat, echo],
lilos::exec::ALL_TASKS,
Expand Down
12 changes: 10 additions & 2 deletions os/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,18 @@ mutex = []
spsc = []
systick = []

[dependencies]
cfg-if.workspace = true
[target.'cfg(target_arch = "arm")'.dependencies]
cortex-m = {workspace = true, features = ["critical-section-single-core"]}
cortex-m-rt.workspace = true

[target.'cfg(any(target_arch = "riscv64", target_arch="riscv32"))'.dependencies]
riscv.workspace = true
riscv-rt.workspace = true
riscv-semihosting.workspace = true
riscv-peripheral.workspace = true

[dependencies]
cfg-if.workspace = true
lilos-list.workspace = true
pin-project.workspace = true

Expand Down
6 changes: 5 additions & 1 deletion os/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ fn main() {
println!(r#"cargo:rustc-check-cfg=cfg(lilos_has_native_rmw)"#);

match std::env::var("TARGET").unwrap().as_str() {
"thumbv7m-none-eabi" | "thumbv7em-none-eabi" | "thumbv7em-none-eabihf" => {
"thumbv7m-none-eabi"
| "thumbv7em-none-eabi"
| "thumbv7em-none-eabihf" => {
// Turn on BASEPRI support for interrupt priority filtering.
println!("cargo:rustc-cfg=lilos_has_basepri");
// Use native atomic RMW operations
Expand All @@ -16,6 +18,8 @@ fn main() {
"thumbv6m-none-eabi" => {
// Don't turn anything on.
}
"riscv64gc-unknown-none-elf" => {}
"riscv32imac-unknown-none-elf" => {}
t => {
panic!("unknown target {}, update build.rs", t);
}
Expand Down
32 changes: 32 additions & 0 deletions os/src/clint.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//! Support for the riscv CLINT mtimer peripheral.
use crate::time::TickTime;

/// Starts the system clock.
pub fn initialize_sys_tick() {
timer_isr(); // set mtimecmp
unsafe {
riscv::register::mie::set_mtimer();
riscv::interrupt::enable();
}
}

extern "Rust" {
/// Application must implement this function, which returns the
/// timer instance and the system clock frequency, expressed in
/// clock ticks
fn _get_sysclk() -> (riscv_peripheral::aclint::mtimer::MTIMER, u64);
}

#[export_name = "MachineTimer"]
#[doc(hidden)]
fn timer_isr() {
TickTime::increment();
let (mtimer, freq) = unsafe { _get_sysclk() };
let now = mtimer.mtime.read();
let next = now + freq;
mtimer.mtimecmp0.write(next);
}
33 changes: 33 additions & 0 deletions os/src/cortex_m_timer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//! Cortex-M implemention of timer interface.

use cortex_m::peripheral::{syst::SystClkSource, SYST};
use cortex_m_rt::exception;

use crate::time::TickTime;

/// Sets up the tick counter for 1kHz operation, assuming a CPU core clock of
/// `clock_hz`.
///
/// If you use this module in your application, call this before
/// [`run_tasks`][crate::exec::run_tasks] (or a fancier version of `run_tasks`)
/// to set up the timer for monotonic operation.
pub fn initialize_sys_tick(syst: &mut SYST, clock_hz: u32) {
let cycles_per_millisecond = clock_hz / 1000;
syst.set_reload(cycles_per_millisecond - 1);
syst.clear_current();
syst.set_clock_source(SystClkSource::Core);
syst.enable_interrupt();
syst.enable_counter();
}

/// System tick ISR. Advances the tick counter. This doesn't wake any tasks; see
/// code in `exec` for that.
#[doc(hidden)]
#[exception]
fn SysTick() {
TickTime::increment();
}
Loading