diff --git a/examples/rust-examples/mips64/scheduler/cooperative/.cargo/config.toml b/examples/rust-examples/mips64/scheduler/cooperative/.cargo/config.toml new file mode 100644 index 0000000..4ee6110 --- /dev/null +++ b/examples/rust-examples/mips64/scheduler/cooperative/.cargo/config.toml @@ -0,0 +1,13 @@ +[build] +rustflags = [ + "-C", "link-arg=-Ttext=0x80010000", + "-C", "link-arg=-emain", +] + +target = "mips64el-unknown-linux-gnuabi64" + +[unstable] +build-std = ["core", "alloc"] + +[target.mips64el-unknown-linux-gnuabi64] +linker = "lld" diff --git a/examples/rust-examples/mips64/scheduler/cooperative/Cargo.toml b/examples/rust-examples/mips64/scheduler/cooperative/Cargo.toml new file mode 100644 index 0000000..c4b9af9 --- /dev/null +++ b/examples/rust-examples/mips64/scheduler/cooperative/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "example_mips64_cooperative_scheduler" +version = "0.4.0" +edition = "2021" + +[profile.release] +panic = "abort" +debug = true + +[dependencies] +# Specifying Martos version +#martos = "0.4.0" +# Specifying current Martos version path for ci +martos = { path = "../../../../../", features = ["cooperative"] } diff --git a/examples/rust-examples/mips64/scheduler/cooperative/README.md b/examples/rust-examples/mips64/scheduler/cooperative/README.md new file mode 100644 index 0000000..7aa61cd --- /dev/null +++ b/examples/rust-examples/mips64/scheduler/cooperative/README.md @@ -0,0 +1,38 @@ +# Rust example for mips64 architecture + +Presented here is a straightforward Rust example utilizing Martos with a cooperative scheduler. + +The program begins with a main task that increments a shared counter on each iteration. +Once the counter reaches the value of 25, the main task dynamically adds an inner task to the task manager. +The inner task also increments the shared counter on each iteration and stops execution when the counter becomes +divisible by 10. This setup showcases Martos' flexibility in managing tasks, including adding new tasks dynamically +during execution. + +## How to install dependencies + +Below is an illustrative example demonstrating the installation of building toolchains on a Linux (Ubuntu/Debian): + +``` +apt update && apt install curl build-essential lld +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y +rustup toolchain install nightly +rustup default 1.71 +rustup target add mips64el-unknown-linux-gnuabi64 +rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu +``` + +## How to build the example + +Below, you will find an illustrative example showcasing the building process on a Linux system (Ubuntu/Debian): + +``` +cargo +nightly build --release +``` + +## How to run the example + +Below, you will find an illustrative example showcasing the running on a Linux system (Ubuntu/Debian): + +``` +cargo +nightly run +``` diff --git a/examples/rust-examples/mips64/scheduler/cooperative/rust-toolchain.toml b/examples/rust-examples/mips64/scheduler/cooperative/rust-toolchain.toml new file mode 100644 index 0000000..5d56faf --- /dev/null +++ b/examples/rust-examples/mips64/scheduler/cooperative/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" diff --git a/examples/rust-examples/mips64/scheduler/cooperative/src/main.rs b/examples/rust-examples/mips64/scheduler/cooperative/src/main.rs new file mode 100644 index 0000000..bc24a3a --- /dev/null +++ b/examples/rust-examples/mips64/scheduler/cooperative/src/main.rs @@ -0,0 +1,63 @@ +#![no_std] +#![no_main] + +use core::sync::atomic::{AtomicU32, Ordering}; +use martos::{ + init_system, + task_manager::{TaskManager, TaskManagerTrait}, +}; + +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + loop {} +} + +static COUNTER: AtomicU32 = AtomicU32::new(1); + +/// Setup function for the main task. +fn main_task_setup_fn() {} + +/// Loop function for the main task. +fn main_task_loop_fn() { + let count = COUNTER.fetch_add(1, Ordering::Relaxed); + if count == 25 { + TaskManager::add_task( + inner_task_setup_fn, + inner_task_loop_fn, + inner_task_stop_condition_fn, + ); + } +} + +/// Stop condition for the main task. +fn main_task_stop_condition_fn() -> bool { + false +} + +/// Setup function for the inner task. +fn inner_task_setup_fn() {} + +/// Loop function for the inner task. +fn inner_task_loop_fn() { + COUNTER.fetch_add(1, Ordering::Relaxed); +} + +/// Stop condition for the inner task. +fn inner_task_stop_condition_fn() -> bool { + let value = unsafe { COUNTER.as_ptr().read() }; + value % 10 == 0 +} + +#[no_mangle] +pub extern "C" fn __start() -> ! { + // Initialize Martos. + init_system(); + // Add task to execute. + TaskManager::add_task( + main_task_setup_fn, + main_task_loop_fn, + main_task_stop_condition_fn, + ); + // Start task manager. + TaskManager::start_task_manager(); +} diff --git a/examples/rust-examples/risc-v-esp32-c6/scheduler/.cargo/config.toml b/examples/rust-examples/risc-v-esp32-c6/scheduler/cooperative/.cargo/config.toml similarity index 100% rename from examples/rust-examples/risc-v-esp32-c6/scheduler/.cargo/config.toml rename to examples/rust-examples/risc-v-esp32-c6/scheduler/cooperative/.cargo/config.toml diff --git a/examples/rust-examples/risc-v-esp32-c6/scheduler/Cargo.toml b/examples/rust-examples/risc-v-esp32-c6/scheduler/cooperative/Cargo.toml similarity index 79% rename from examples/rust-examples/risc-v-esp32-c6/scheduler/Cargo.toml rename to examples/rust-examples/risc-v-esp32-c6/scheduler/cooperative/Cargo.toml index 1246f4b..9aeb81a 100644 --- a/examples/rust-examples/risc-v-esp32-c6/scheduler/Cargo.toml +++ b/examples/rust-examples/risc-v-esp32-c6/scheduler/cooperative/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "example_risc_v_esp32c6_scheduler" +name = "example_risc_v_esp32c6_cooperative_scheduler" version = "0.3.0" edition = "2021" @@ -10,7 +10,7 @@ debug = true # Specifying Martos version #martos = "0.3.0" # Specifying current Martos version path for ci -martos = { path = "../../../../", features = ["preemptive"]} +martos = { path = "../../../../../", features = ["cooperative"] } esp-hal = "0.21.1" esp-backtrace = { version = "0.14.1", features = ["esp32c6", "panic-handler", "exception-handler", "println"] } esp-println = { version = "0.11.0", features = ["esp32c6"] } diff --git a/examples/rust-examples/risc-v-esp32-c6/scheduler/cooperative/README.md b/examples/rust-examples/risc-v-esp32-c6/scheduler/cooperative/README.md new file mode 100644 index 0000000..51293bc --- /dev/null +++ b/examples/rust-examples/risc-v-esp32-c6/scheduler/cooperative/README.md @@ -0,0 +1,45 @@ +# Rust example for risc-v esp32c6 architecture + +Presented here is a straightforward Rust example utilizing Martos with a cooperative scheduler. + +The example begins with a main task that handles a counter, incrementing it by 1 and printing the updated value. +An inner task is dynamically added once the counter reaches 25, and it increments the counter by 1. The inner task +periodically terminates itself when the counter is a multiple of 10, showcasing dynamic task creation and cooperative +task switching. + +## How to install dependencies + +For comprehensive guidance on installing the necessary dependencies for developing applications targeting the RISC-V +ESP32-C6 architecture, +please refer to [the official website](https://docs.esp-rs.org/book/installation/riscv-and-xtensa.html). +Below is an illustrative example demonstrating the installation of building toolchains on a Linux (Ubuntu/Debian): + +``` +apt-get -qq update +apt-get install -y -q build-essential curl +curl https://sh.rustup.rs -sSf | sh -s -- -y +cargo install espup +espup install +``` + +## How to build the example + +For a thorough guide on developing projects for the RISC-V ESP32-C6 architecture across various operating systems, +we recommend +consulting [the official website](https://docs.esp-rs.org/book/installation/riscv-and-xtensa.html#3-set-up-the-environment-variables). +Below, you will find an illustrative example showcasing the building process on a Linux system (Ubuntu/Debian): + +``` +. $HOME/export-esp.sh +cargo build +``` + +## How to run the example + +For detailed instructions on running projects for the RISC-V ESP32-C6 architecture across various operating systems, +we recommend consulting [the official website](https://docs.esp-rs.org/book/tooling/espflash.html). +Below, you will find an illustrative example showcasing the running on a Linux system (Ubuntu/Debian): + +``` +cargo run +``` diff --git a/examples/rust-examples/risc-v-esp32-c6/scheduler/rust-toolchain.toml b/examples/rust-examples/risc-v-esp32-c6/scheduler/cooperative/rust-toolchain.toml similarity index 100% rename from examples/rust-examples/risc-v-esp32-c6/scheduler/rust-toolchain.toml rename to examples/rust-examples/risc-v-esp32-c6/scheduler/cooperative/rust-toolchain.toml diff --git a/examples/rust-examples/risc-v-esp32-c6/scheduler/cooperative/src/main.rs b/examples/rust-examples/risc-v-esp32-c6/scheduler/cooperative/src/main.rs new file mode 100644 index 0000000..c721a30 --- /dev/null +++ b/examples/rust-examples/risc-v-esp32-c6/scheduler/cooperative/src/main.rs @@ -0,0 +1,71 @@ +#![no_std] +#![no_main] + +use core::sync::atomic::{AtomicU32, Ordering}; +use esp_hal::entry; +use esp_println::println; +use martos::{ + init_system, + task_manager::{TaskManager, TaskManagerTrait}, +}; + +/// Counter to work with in loop. +static COUNTER: AtomicU32 = AtomicU32::new(1); + +/// Setup function for the main task. +fn main_task_setup_fn() { + println!("Main task setup.\n"); +} + +/// Loop function for the main task. +fn main_task_loop_fn() { + let count = COUNTER.fetch_add(1, Ordering::Relaxed); + println!("Main task loop: Counter = {}.\n", unsafe { + COUNTER.as_ptr().read() + }); + if count == 25 { + TaskManager::add_task( + inner_task_setup_fn, + inner_task_loop_fn, + inner_task_stop_condition_fn, + ); + } +} + +/// Stop condition for the main task. +fn main_task_stop_condition_fn() -> bool { + false +} + +/// Setup function for the inner task. +fn inner_task_setup_fn() { + println!("Inner task setup.\n"); +} + +/// Loop function for the inner task. +fn inner_task_loop_fn() { + COUNTER.fetch_add(1, Ordering::Relaxed); + println!("Inner task loop: Counter = {}.\n", unsafe { + COUNTER.as_ptr().read() + }); +} + +/// Stop condition for the inner task. +fn inner_task_stop_condition_fn() -> bool { + let value = unsafe { COUNTER.as_ptr().read() }; + value % 10 == 0 +} + +#[entry] +fn main() -> ! { + // Initialize Martos. + init_system(); + // Add task to execute. + TaskManager::add_task( + main_task_setup_fn, + main_task_loop_fn, + main_task_stop_condition_fn, + ); + // Start task manager. + TaskManager::start_task_manager(); +} diff --git a/examples/rust-examples/risc-v-esp32-c6/scheduler/src/main.rs b/examples/rust-examples/risc-v-esp32-c6/scheduler/src/main.rs deleted file mode 100644 index c9da27f..0000000 --- a/examples/rust-examples/risc-v-esp32-c6/scheduler/src/main.rs +++ /dev/null @@ -1,49 +0,0 @@ -#![no_std] -#![no_main] - -use core::sync::atomic::{AtomicU32, Ordering}; -use esp_backtrace as _; -use esp_hal::{delay::Delay, entry, prelude::*}; -use esp_println::println; -use martos::{ - init_system, - task_manager::{TaskManager, TaskManagerTrait}, -}; - -/// Counter to work with in loop. -static COUNTER: AtomicU32 = AtomicU32::new(1); - -/// Loop function for task to execute. -fn loop_fn_1() { - let old = COUNTER.fetch_add(1, Ordering::Relaxed); - println!("Loop 0; Counter = {}", old); - Delay::new().delay(500u64.millis()); -} - -fn loop_fn_2() { - let old = COUNTER.fetch_add(1, Ordering::Relaxed); - println!("Loop 1; Counter = {}", old); - Delay::new().delay(500u64.millis()); -} - -fn setup() { - println!("Setup") -} -fn stop() -> bool { - if COUNTER.fetch_add(0, Ordering::Relaxed) > 20 { - true - } else { - false - } -} - -#[entry] -fn main() -> ! { - // Initialize Martos. - init_system(); - // Add task to execute. - TaskManager::add_task(setup, loop_fn_1, stop); - TaskManager::add_task(setup, loop_fn_2, stop); - // Start task manager. - TaskManager::start_task_manager(); -} diff --git a/examples/rust-examples/xtensa-esp32/scheduler/.cargo/config.toml b/examples/rust-examples/xtensa-esp32/scheduler/cooperative/.cargo/config.toml similarity index 100% rename from examples/rust-examples/xtensa-esp32/scheduler/.cargo/config.toml rename to examples/rust-examples/xtensa-esp32/scheduler/cooperative/.cargo/config.toml diff --git a/examples/rust-examples/xtensa-esp32/scheduler/cooperative/Cargo.toml b/examples/rust-examples/xtensa-esp32/scheduler/cooperative/Cargo.toml new file mode 100644 index 0000000..0ad1446 --- /dev/null +++ b/examples/rust-examples/xtensa-esp32/scheduler/cooperative/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "example_xtensa_esp32_cooperative_scheduler" +version = "0.3.0" +edition = "2021" + +[profile.release] +debug = true + +[dependencies] +# Specifying Martos version +#martos = "0.3.0" +# Specifying current Martos version path for ci +martos = { path = "../../../../../", features = ["cooperative"] } +esp-hal = "0.21.1" +esp-backtrace = { version = "0.14.1", features = ["esp32", "panic-handler", "exception-handler", "println"] } +esp-println = { version = "0.11.0", features = ["esp32"] } + +[features] +default = ["esp-hal/esp32", "esp-backtrace/esp32", "esp-println/esp32"] diff --git a/examples/rust-examples/xtensa-esp32/scheduler/cooperative/README.md b/examples/rust-examples/xtensa-esp32/scheduler/cooperative/README.md new file mode 100644 index 0000000..9319028 --- /dev/null +++ b/examples/rust-examples/xtensa-esp32/scheduler/cooperative/README.md @@ -0,0 +1,45 @@ +# Rust example for xtensa esp32 architecture + +Presented here is a straightforward Rust example utilizing Martos with a cooperative scheduler. + +The example begins with a main task that handles a counter, incrementing it by 1 and printing the updated value. +An inner task is dynamically added once the counter reaches 25, and it increments the counter by 1. The inner task +periodically terminates itself when the counter is a multiple of 10, showcasing dynamic task creation and cooperative +task switching. + +## How to install dependencies + +For comprehensive guidance on installing the necessary dependencies for developing applications targeting the Xtensa +ESP32 architecture, +please refer to [the official website](https://docs.esp-rs.org/book/installation/riscv-and-xtensa.html). +Below is an illustrative example demonstrating the installation of building toolchains on a Linux (Ubuntu/Debian): + +``` +apt-get -qq update +apt-get install -y -q build-essential curl +curl https://sh.rustup.rs -sSf | sh -s -- -y +cargo install espup +espup install +``` + +## How to build the example + +For a thorough guide on developing projects for the Xtensa ESP32 architecture across various operating systems, +we recommend +consulting [the official website](https://docs.esp-rs.org/book/installation/riscv-and-xtensa.html#3-set-up-the-environment-variables). +Below, you will find an illustrative example showcasing the building process on a Linux system (Ubuntu/Debian): + +``` +. $HOME/export-esp.sh +cargo build --release +``` + +## How to run the example + +For detailed instructions on running projects for the Xtensa ESP32 architecture across various operating systems, +we recommend consulting [the official website](https://docs.esp-rs.org/book/tooling/espflash.html). +Below, you will find an illustrative example showcasing the running on a Linux system (Ubuntu/Debian): + +``` +cargo run +``` diff --git a/examples/rust-examples/xtensa-esp32/scheduler/rust-toolchain.toml b/examples/rust-examples/xtensa-esp32/scheduler/cooperative/rust-toolchain.toml similarity index 100% rename from examples/rust-examples/xtensa-esp32/scheduler/rust-toolchain.toml rename to examples/rust-examples/xtensa-esp32/scheduler/cooperative/rust-toolchain.toml diff --git a/examples/rust-examples/xtensa-esp32/scheduler/cooperative/src/main.rs b/examples/rust-examples/xtensa-esp32/scheduler/cooperative/src/main.rs new file mode 100644 index 0000000..c721a30 --- /dev/null +++ b/examples/rust-examples/xtensa-esp32/scheduler/cooperative/src/main.rs @@ -0,0 +1,71 @@ +#![no_std] +#![no_main] + +use core::sync::atomic::{AtomicU32, Ordering}; +use esp_hal::entry; +use esp_println::println; +use martos::{ + init_system, + task_manager::{TaskManager, TaskManagerTrait}, +}; + +/// Counter to work with in loop. +static COUNTER: AtomicU32 = AtomicU32::new(1); + +/// Setup function for the main task. +fn main_task_setup_fn() { + println!("Main task setup.\n"); +} + +/// Loop function for the main task. +fn main_task_loop_fn() { + let count = COUNTER.fetch_add(1, Ordering::Relaxed); + println!("Main task loop: Counter = {}.\n", unsafe { + COUNTER.as_ptr().read() + }); + if count == 25 { + TaskManager::add_task( + inner_task_setup_fn, + inner_task_loop_fn, + inner_task_stop_condition_fn, + ); + } +} + +/// Stop condition for the main task. +fn main_task_stop_condition_fn() -> bool { + false +} + +/// Setup function for the inner task. +fn inner_task_setup_fn() { + println!("Inner task setup.\n"); +} + +/// Loop function for the inner task. +fn inner_task_loop_fn() { + COUNTER.fetch_add(1, Ordering::Relaxed); + println!("Inner task loop: Counter = {}.\n", unsafe { + COUNTER.as_ptr().read() + }); +} + +/// Stop condition for the inner task. +fn inner_task_stop_condition_fn() -> bool { + let value = unsafe { COUNTER.as_ptr().read() }; + value % 10 == 0 +} + +#[entry] +fn main() -> ! { + // Initialize Martos. + init_system(); + // Add task to execute. + TaskManager::add_task( + main_task_setup_fn, + main_task_loop_fn, + main_task_stop_condition_fn, + ); + // Start task manager. + TaskManager::start_task_manager(); +} diff --git a/examples/rust-examples/xtensa-esp32/scheduler/preemptive/.cargo/config.toml b/examples/rust-examples/xtensa-esp32/scheduler/preemptive/.cargo/config.toml new file mode 100644 index 0000000..4a7232a --- /dev/null +++ b/examples/rust-examples/xtensa-esp32/scheduler/preemptive/.cargo/config.toml @@ -0,0 +1,13 @@ +[build] +rustflags = [ + "-C", "link-arg=-Tlinkall.x", + "-C", "link-arg=-nostartfiles", +] + +target = "xtensa-esp32-none-elf" + +[unstable] +build-std = ["core", "alloc"] + +[target.'cfg(any(target_arch = "riscv32", target_arch = "xtensa"))'] +runner = "espflash flash --monitor" diff --git a/examples/rust-examples/xtensa-esp32/scheduler/Cargo.toml b/examples/rust-examples/xtensa-esp32/scheduler/preemptive/Cargo.toml similarity index 88% rename from examples/rust-examples/xtensa-esp32/scheduler/Cargo.toml rename to examples/rust-examples/xtensa-esp32/scheduler/preemptive/Cargo.toml index e1acf3a..bca2100 100644 --- a/examples/rust-examples/xtensa-esp32/scheduler/Cargo.toml +++ b/examples/rust-examples/xtensa-esp32/scheduler/preemptive/Cargo.toml @@ -10,7 +10,7 @@ debug = true # Specifying Martos version #martos = "0.3.0" # Specifying current Martos version path for ci -martos = { path = "../../../../", features = ["preemptive"]} +martos = { path = "../../../../../", features = ["preemptive"] } esp-hal = "0.21.1" esp-backtrace = { version = "0.14.1", features = ["esp32", "panic-handler", "exception-handler", "println"] } esp-println = { version = "0.11.0", features = ["esp32"] } diff --git a/examples/rust-examples/xtensa-esp32/scheduler/preemptive/README.md b/examples/rust-examples/xtensa-esp32/scheduler/preemptive/README.md new file mode 100644 index 0000000..b2e1e2c --- /dev/null +++ b/examples/rust-examples/xtensa-esp32/scheduler/preemptive/README.md @@ -0,0 +1,43 @@ +# Rust example for xtensa esp32 architecture + +Presented here is a straightforward Rust example utilizing Martos with preemptive scheduler. + +Two tasks are created. They take turns increasing the counter value and printing it out until it reaches 20. +Periodically, one preempts the other + +## How to install dependencies + +For comprehensive guidance on installing the necessary dependencies for developing applications targeting the Xtensa +ESP32 architecture, +please refer to [the official website](https://docs.esp-rs.org/book/installation/riscv-and-xtensa.html). +Below is an illustrative example demonstrating the installation of building toolchains on a Linux (Ubuntu/Debian): + +``` +apt-get -qq update +apt-get install -y -q build-essential curl +curl https://sh.rustup.rs -sSf | sh -s -- -y +cargo install espup +espup install +``` + +## How to build the example + +For a thorough guide on developing projects for the Xtensa ESP32 architecture across various operating systems, +we recommend +consulting [the official website](https://docs.esp-rs.org/book/installation/riscv-and-xtensa.html#3-set-up-the-environment-variables). +Below, you will find an illustrative example showcasing the building process on a Linux system (Ubuntu/Debian): + +``` +. $HOME/export-esp.sh +cargo build --release +``` + +## How to run the example + +For detailed instructions on running projects for the Xtensa ESP32 architecture across various operating systems, +we recommend consulting [the official website](https://docs.esp-rs.org/book/tooling/espflash.html). +Below, you will find an illustrative example showcasing the running on a Linux system (Ubuntu/Debian): + +``` +cargo run +``` diff --git a/examples/rust-examples/xtensa-esp32/scheduler/preemptive/rust-toolchain.toml b/examples/rust-examples/xtensa-esp32/scheduler/preemptive/rust-toolchain.toml new file mode 100644 index 0000000..a2f5ab5 --- /dev/null +++ b/examples/rust-examples/xtensa-esp32/scheduler/preemptive/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "esp" diff --git a/examples/rust-examples/xtensa-esp32/scheduler/src/main.rs b/examples/rust-examples/xtensa-esp32/scheduler/preemptive/src/main.rs similarity index 100% rename from examples/rust-examples/xtensa-esp32/scheduler/src/main.rs rename to examples/rust-examples/xtensa-esp32/scheduler/preemptive/src/main.rs