Skip to content

Commit

Permalink
Merge pull request #68 from Glamhoth/ros-167/requirements-coverage
Browse files Browse the repository at this point in the history
ROS#167 - Requirements coverage
  • Loading branch information
Glamhoth authored Oct 9, 2023
2 parents 093adfc + 7749bd7 commit 6317da2
Show file tree
Hide file tree
Showing 70 changed files with 885 additions and 45 deletions.
2 changes: 1 addition & 1 deletion examples/samv71-basic-execution/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ fn main() -> ! {

logln!("Subscribing tasks...");

aerugo.subscribe_tasklet_to_cyclic(&dummy_task_handle, Some(Duration::secs(1)));
aerugo.subscribe_tasklet_to_cyclic(&dummy_task_handle, Some(Duration::secs(1)), None);

logln!("Starting the system!");

Expand Down
2 changes: 1 addition & 1 deletion examples/samv71-fizz-buzz/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ fn main() -> ! {

let producer_handle = PRODUCER_STORAGE.create_handle().unwrap();
aerugo.set_tasklet_conditions(&producer_handle, producer_condition_set);
aerugo.subscribe_tasklet_to_cyclic(&producer_handle, Some(Duration::secs(1)));
aerugo.subscribe_tasklet_to_cyclic(&producer_handle, Some(Duration::secs(1)), None);

let distributor_handle = DISTRIBUTOR_STORAGE.create_handle().unwrap();
aerugo.subscribe_tasklet_to_queue(&distributor_handle, &elem_queue_handle);
Expand Down
2 changes: 1 addition & 1 deletion examples/samv71-hal-interrupts/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ fn init_tasks(aerugo: &'static impl InitApi) {

let dummy_task_handle = DUMMY_TASK_STORAGE.create_handle().unwrap();

aerugo.subscribe_tasklet_to_cyclic(&dummy_task_handle, Some(Duration::secs(1)));
aerugo.subscribe_tasklet_to_cyclic(&dummy_task_handle, Some(Duration::secs(1)), None);
}

#[entry]
Expand Down
4 changes: 2 additions & 2 deletions examples/samv71-hal-pio/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ fn init_tasks(aerugo: &'static impl InitApi) {

logln!("Subscribing tasks...");

aerugo.subscribe_tasklet_to_cyclic(&pio_out_task_handle, Some(Duration::millis(1000)));
aerugo.subscribe_tasklet_to_cyclic(&pio_in_task_handle, Some(Duration::millis(1000)));
aerugo.subscribe_tasklet_to_cyclic(&pio_out_task_handle, Some(Duration::millis(1000)), None);
aerugo.subscribe_tasklet_to_cyclic(&pio_in_task_handle, Some(Duration::millis(1000)), None);
}

#[entry]
Expand Down
2 changes: 1 addition & 1 deletion examples/samv71-hal-systick/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ fn init_tasks(aerugo: &'static impl InitApi) {

let dummy_task_handle = DUMMY_TASK_STORAGE.create_handle().unwrap();

aerugo.subscribe_tasklet_to_cyclic(&dummy_task_handle, Some(Duration::secs(1)));
aerugo.subscribe_tasklet_to_cyclic(&dummy_task_handle, Some(Duration::secs(1)), None);
}

#[entry]
Expand Down
2 changes: 1 addition & 1 deletion examples/samv71-hal-timer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ fn init_tasks(aerugo: &'static impl InitApi) {

logln!("Subscribing tasks...");

aerugo.subscribe_tasklet_to_cyclic(&dummy_task_handle, Some(Duration::secs(1)));
aerugo.subscribe_tasklet_to_cyclic(&dummy_task_handle, Some(Duration::secs(1)), None);
}

#[entry]
Expand Down
2 changes: 1 addition & 1 deletion examples/samv71-system-time/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ fn main() -> ! {

logln!("Subscribing tasks...");

aerugo.subscribe_tasklet_to_cyclic(&dummy_task_handle, Some(Duration::secs(1)));
aerugo.subscribe_tasklet_to_cyclic(&dummy_task_handle, Some(Duration::secs(1)), None);

logln!("Starting the system!");

Expand Down
4 changes: 2 additions & 2 deletions examples/x86-basic-execution/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ fn main() -> ! {
let task_a_handle = TASK_A_STORAGE.create_handle().unwrap();
let task_b_handle = TASK_B_STORAGE.create_handle().unwrap();

aerugo.subscribe_tasklet_to_cyclic(&task_a_handle, Some(Duration::secs(1)));
aerugo.subscribe_tasklet_to_cyclic(&task_b_handle, Some(Duration::secs(1)));
aerugo.subscribe_tasklet_to_cyclic(&task_a_handle, Some(Duration::secs(1)), None);
aerugo.subscribe_tasklet_to_cyclic(&task_b_handle, Some(Duration::secs(1)), None);

aerugo.start();
}
2 changes: 1 addition & 1 deletion examples/x86-boolean-condition/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ fn main() -> ! {
let task_a_handle = TASK_A_STORAGE.create_handle().unwrap();
let task_b_handle = TASK_B_STORAGE.create_handle().unwrap();

aerugo.subscribe_tasklet_to_cyclic(&task_a_handle, Some(Duration::secs(1)));
aerugo.subscribe_tasklet_to_cyclic(&task_a_handle, Some(Duration::secs(1)), None);
aerugo.subscribe_tasklet_to_queue(&task_b_handle, &queue_x_handle);

let task_a_condition_set = BooleanConditionSet::from(enable_condition_handle);
Expand Down
4 changes: 2 additions & 2 deletions examples/x86-cyclic-execution/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ fn main() -> ! {
aerugo.create_tasklet_with_context(task_b_config, task_b, task_b_context, &TASK_B_STORAGE);

let task_a_handle = TASK_A_STORAGE.create_handle().unwrap();
aerugo.subscribe_tasklet_to_cyclic(&task_a_handle, Some(Duration::secs(1)));
aerugo.subscribe_tasklet_to_cyclic(&task_a_handle, Some(Duration::secs(1)), None);

let task_b_handle = TASK_B_STORAGE.create_handle().unwrap();
aerugo.subscribe_tasklet_to_cyclic(&task_b_handle, Some(Duration::secs(5)));
aerugo.subscribe_tasklet_to_cyclic(&task_b_handle, Some(Duration::secs(5)), None);

aerugo.start();
}
2 changes: 1 addition & 1 deletion examples/x86-events-scheduled/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ fn main() -> ! {
aerugo.create_tasklet(task_b_config, task_b, &TASK_B_STORAGE);

let task_a_handle = TASK_A_STORAGE.create_handle().unwrap();
aerugo.subscribe_tasklet_to_cyclic(&task_a_handle, Some(Duration::secs(2)));
aerugo.subscribe_tasklet_to_cyclic(&task_a_handle, Some(Duration::secs(2)), None);

let task_b_handle = TASK_B_STORAGE.create_handle().unwrap();
aerugo.subscribe_tasklet_to_events(
Expand Down
2 changes: 1 addition & 1 deletion examples/x86-events/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ fn main() -> ! {
let task_b_handle = TASK_B_STORAGE.create_handle().unwrap();
let task_c_handle = TASK_C_STORAGE.create_handle().unwrap();

aerugo.subscribe_tasklet_to_cyclic(&task_a_handle, Some(Duration::secs(1)));
aerugo.subscribe_tasklet_to_cyclic(&task_a_handle, Some(Duration::secs(1)), None);

let task_b_events = [MyEvents::Event1.into(), MyEvents::Event42.into()];
aerugo.subscribe_tasklet_to_events(&task_b_handle, task_b_events);
Expand Down
2 changes: 1 addition & 1 deletion examples/x86-fizz-buzz/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ fn main() -> ! {

let producer_handle = PRODUCER_STORAGE.create_handle().unwrap();
aerugo.set_tasklet_conditions(&producer_handle, producer_condition_set);
aerugo.subscribe_tasklet_to_cyclic(&producer_handle, Some(Duration::secs(1)));
aerugo.subscribe_tasklet_to_cyclic(&producer_handle, Some(Duration::secs(1)), None);

let distributor_handle = DISTRIBUTOR_STORAGE.create_handle().unwrap();
aerugo.subscribe_tasklet_to_queue(&distributor_handle, &elem_queue_handle);
Expand Down
8 changes: 5 additions & 3 deletions src/aerugo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,8 @@ impl InitApi for Aerugo {
///
/// # Parameters
/// * `tasklet` - Handle to the target tasklet.
/// * `period` - Time period of the execution.
/// * `period` - Period of execution, `None` if should be woke whenever possible.
/// * `offset` - Offset of first execution after scheduled start, `None` if should be executed instantly.
///
/// # Return
/// `()` if successful, `InitError` otherwise.
Expand All @@ -862,20 +863,21 @@ impl InitApi for Aerugo {
/// #
/// let task_handle = TASK_STORAGE.create_handle().unwrap();
///
/// aerugo.subscribe_tasklet_to_cyclic(&task_handle, None);
/// aerugo.subscribe_tasklet_to_cyclic(&task_handle, None, None);
/// }
/// ```
fn subscribe_tasklet_to_cyclic<C, const COND_COUNT: usize>(
&'static self,
tasklet_handle: &TaskletHandle<(), C, COND_COUNT>,
period: Option<Duration>,
offset: Option<Duration>,
) {
let tasklet = tasklet_handle.tasklet();

// SAFETY: This is safe as long as this function is called only during system initialization.
unsafe {
let cyclic_execution = CYCLIC_EXECUTION_MANAGER
.create_cyclic_execution(tasklet.ptr(), period)
.create_cyclic_execution(tasklet.ptr(), period, offset)
.expect("Failed to create a cyclic execution");

tasklet
Expand Down
4 changes: 3 additions & 1 deletion src/api/init_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,14 +160,16 @@ pub trait InitApi {
///
/// # Parameters
/// * `tasklet` - Handle to the target tasklet.
/// * `period` - Time period of the execution.
/// * `period` - Period of execution, `None` if should be woke whenever possible.
/// * `offset` - Offset of first execution after scheduled start, `None` if should be executed instantly.
///
/// # Return
/// `()` if successful, `InitError` otherwise.
fn subscribe_tasklet_to_cyclic<C, const COND_COUNT: usize>(
&'static self,
tasklet_handle: &TaskletHandle<(), C, COND_COUNT>,
period: Option<Duration>,
offset: Option<Duration>,
);

/// Sets tasklet condition set.
Expand Down
4 changes: 4 additions & 0 deletions src/boolean_condition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,7 @@ impl DataProvider<bool> for BooleanCondition {
false
}
}

/// SAFETY: This is safe, because that structure is only stored by the [BooleanConditionStorage]
/// which ensures safe access.
unsafe impl Sync for BooleanCondition {}
2 changes: 2 additions & 0 deletions src/boolean_condition/boolean_condition_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ impl BooleanConditionStorage {
}
}

/// SAFETY: This is safe, because mutable access (initialization) can be performed only once, and
/// then access to the stored BooleanCondition can be only done with [BooleanConditionHandle].
unsafe impl Sync for BooleanConditionStorage {}

#[cfg(test)]
Expand Down
19 changes: 17 additions & 2 deletions src/cyclic_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,24 @@ pub(crate) struct CyclicExecution {

impl CyclicExecution {
/// Creates new instance.
pub(crate) fn new(tasklet: TaskletPtr, period: Option<Duration>) -> Self {
///
/// # Parameters
/// * `tasklet` - Tasklet which should be executed cyclically.
/// * `period` - Period of execution, `None` if should be awaken whenever possible.
/// * `offset` - Offset of first execution after scheduled start, `None` if should be executed instantly.
pub(crate) fn new(
tasklet: TaskletPtr,
period: Option<Duration>,
offset: Option<Duration>,
) -> Self {
let next_execution_time = match offset {
Some(offset) => Instant::from_ticks(offset.ticks()),
None => Instant::from_ticks(0),
}
.into();

CyclicExecution {
next_execution_time: Instant::from_ticks(0).into(),
next_execution_time,
period,
tasklet,
}
Expand Down
8 changes: 7 additions & 1 deletion src/cyclic_execution_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ impl CyclicExecutionManager {
/// * `tasklet`: Tasklet that will be executed
/// * `period`: Period for execution, `None` if tasklet shall be executed without waits
///
/// # Parameters
/// * `tasklet` - Tasklet which should be executed cyclically.
/// * `period` - Period of execution, `None` if should be awaken whenever possible.
/// * `offset` - Offset of first execution after scheduled start, `None` if should be executed instantly.
///
/// # Return
/// Reference to the cyclic execution data if successful, `SystemError` otherwise.
///
Expand All @@ -54,8 +59,9 @@ impl CyclicExecutionManager {
&'static self,
tasklet: TaskletPtr,
period: Option<Duration>,
offset: Option<Duration>,
) -> Result<&'static CyclicExecution, SystemError> {
let cyclic_execution = CyclicExecution::new(tasklet, period);
let cyclic_execution = CyclicExecution::new(tasklet, period, offset);

match self.cyclic_executions.add(cyclic_execution) {
Ok(_) => (),
Expand Down
4 changes: 4 additions & 0 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,7 @@ impl PartialEq for Event {
self.id.eq(&other.id)
}
}

/// SAFETY: This is safe, because that structure is only stored by the [EventStorage]
/// which ensures safe access.
unsafe impl Sync for Event {}
2 changes: 2 additions & 0 deletions src/event/event_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ impl EventStorage {
}
}

/// SAFETY: This is safe, because mutable access (initialization) can be performed only once, and
/// then access to the stored Event can be only done with [EventHandle] or via [InitApi](crate::api::InitApi)
unsafe impl Sync for EventStorage {}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub use self::api::{InitApi, RuntimeApi};
pub use self::boolean_condition::{
BooleanConditionHandle, BooleanConditionSet, BooleanConditionSetType, BooleanConditionStorage,
};
pub use self::event::{EventId, EventStorage};
pub use self::event::{EventHandle, EventId, EventStorage};
pub use self::message_queue::{MessageQueueHandle, MessageQueueStorage};
pub use self::mutex::Mutex;
pub use self::tasklet::{TaskletConfig, TaskletStorage};
Expand Down
23 changes: 16 additions & 7 deletions src/message_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,6 @@ impl<T, const N: usize> MessageQueue<T, N> {
}
}

/// Wakes tasklets registered to this queue.
fn wake_tasklets(&self) {
for t in &self.registered_tasklets {
Aerugo::wake_tasklet(t);
}
}

/// Sends given data to this queue.
///
/// # Parameters
Expand All @@ -82,6 +75,18 @@ impl<T, const N: usize> MessageQueue<T, N> {

Ok(())
}

/// Clears this queue.
pub(crate) fn clear(&self) {
self.data_queue.lock(|q| while q.dequeue().is_some() {})
}

/// Wakes tasklets registered to this queue.
fn wake_tasklets(&self) {
for t in &self.registered_tasklets {
Aerugo::wake_tasklet(t);
}
}
}

impl<T, const N: usize> DataProvider<T> for MessageQueue<T, N> {
Expand All @@ -101,6 +106,10 @@ impl<T, const N: usize> DataProvider<T> for MessageQueue<T, N> {
}
}

/// SAFETY: This is safe, because that structure is only stored by the [MessageQueueStorage]
/// which ensures safe access.
unsafe impl<T, const N: usize> Sync for MessageQueue<T, N> {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
5 changes: 5 additions & 0 deletions src/message_queue/message_queue_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ impl<T, const N: usize> MessageQueueHandle<T, N> {
self.queue.send_data(data)
}

/// Clears stored queue.
pub fn clear(&self) {
self.queue.clear()
}

/// Returns reference to the queue.
pub(crate) fn queue(&self) -> &'static MessageQueue<T, N> {
self.queue
Expand Down
2 changes: 2 additions & 0 deletions src/message_queue/message_queue_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ impl<T, const N: usize> MessageQueueStorage<T, N> {
}
}

/// SAFETY: This is safe, because mutable access (initialization) can be performed only once, and
/// then access to the stored MessageQueue can be only done with [MessageQueueHandle].
unsafe impl<T, const N: usize> Sync for MessageQueueStorage<T, N> {}

#[cfg(test)]
Expand Down
4 changes: 2 additions & 2 deletions testbins/test-basic-execution/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ fn main() -> ! {
let task_a_handle = TASK_A_STORAGE.create_handle().unwrap();
let task_b_handle = TASK_B_STORAGE.create_handle().unwrap();

aerugo.subscribe_tasklet_to_cyclic(&task_a_handle, None);
aerugo.subscribe_tasklet_to_cyclic(&task_b_handle, None);
aerugo.subscribe_tasklet_to_cyclic(&task_a_handle, None, None);
aerugo.subscribe_tasklet_to_cyclic(&task_b_handle, None, None);

aerugo.start();
}
11 changes: 11 additions & 0 deletions testbins/test-boolean-condition-interrupt/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[build]
target = "thumbv7em-none-eabihf"

[env]
AERUGO_TASKLET_COUNT = { value = "1" }

[target.thumbv7em-none-eabihf]
rustflags = [
"-C", "link-arg=--nmagic", # Disable page alignment of sections (to prevent issues with binary size)
"-C", "link-arg=-Tlink.x", # Use cortex-m-rt's linker script
]
23 changes: 23 additions & 0 deletions testbins/test-boolean-condition-interrupt/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "test-boolean-condition-interrupt"
authors = ["Filip Demski <glamhoth@protonmail.com>"]
edition = "2021"
version = "1.0.0"

[dependencies]
aerugo = { version = "0.1.0", path = "../..", features = [
"use-aerugo-cortex-m",
"rt"
], default-features = false }
calldwell = { version = "0.1.0", path = "../../calldwell/calldwell-rs" }
cortex-m = { version = "0.7.7", features = ["critical-section-single-core"] }
cortex-m-rt = { version = "0.7.3", features = ["device"] }
lazy_static = { version = "1.4.0", features = ["spin_no_std"] }

[features]
rt = ["aerugo/rt"]

[profile.release]
codegen-units = 1
lto = true
debug = true
14 changes: 14 additions & 0 deletions testbins/test-boolean-condition-interrupt/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;

fn main() {
// Put the linker script somewhere the linker can find it
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
File::create(out.join("memory.x"))
.unwrap()
.write_all(include_bytes!("memory.x"))
.unwrap();
println!("cargo:rustc-link-search={}", out.display());
}
Loading

0 comments on commit 6317da2

Please sign in to comment.