diff --git a/examples/timing_exam.rs b/examples/timing_exam.rs index 6d3f2645f7cb65878342cf6b8bd68c057ff3f85e..29d6ba289183ca1e20b778a902fd51bdffb884ac 100644 --- a/examples/timing_exam.rs +++ b/examples/timing_exam.rs @@ -9,6 +9,7 @@ use cortex_m::{asm, peripheral::DWT}; use panic_halt as _; use rtic::cyccnt::{Duration, Instant, U32Ext}; use stm32f4::stm32f411; +use core::convert::TryInto; #[no_mangle] static mut T1_MAX_RP: u32 = 0; @@ -40,6 +41,7 @@ const APP: () = { #[inline(never)] #[task(schedule = [t1], priority = 1)] fn t1(cx: t1::Context) { + let start = cx.scheduled; asm::bkpt(); cx.schedule.t1(cx.scheduled + 100_000.cycles()).unwrap(); asm::bkpt(); @@ -50,12 +52,23 @@ const APP: () = { // 2) your code here to update T1_MAX_RP and // break if deadline missed + let end = Instant::now(); + let response_time: u32 = (end - start).try_into().unwrap(); + unsafe { + if T1_MAX_RP < response_time { + T1_MAX_RP = response_time; + } + if T1_MAX_RP > 100_000 { + asm::bkpt(); + } + } } // Deadline 200, Inter-arrival 200 #[inline(never)] #[task(schedule = [t2], resources = [R1, R2], priority = 2)] fn t2(cx: t2::Context) { + let start = cx.scheduled; asm::bkpt(); cx.schedule.t2(cx.scheduled + 200_000.cycles()).unwrap(); asm::bkpt(); @@ -66,12 +79,23 @@ const APP: () = { // 2) your code here to update T2_MAX_RP and // break if deadgine missed + let end = Instant::now(); + let response_time: u32 = (end - start).try_into().unwrap(); + unsafe { + if T2_MAX_RP < response_time { + T2_MAX_RP = response_time; + } + if T2_MAX_RP > 200_000 { + asm::bkpt(); + } + } } // Deadline 50, Inter-arrival 50 #[inline(never)] #[task(schedule = [t3], resources = [R2], priority = 3)] fn t3(cx: t3::Context) { + let start = cx.scheduled; asm::bkpt(); cx.schedule.t3(cx.scheduled + 50_000.cycles()).unwrap(); asm::bkpt(); @@ -82,6 +106,16 @@ const APP: () = { // 2) your code here to update T3_MAX_RP and // break if deadline missed + let end = Instant::now(); + let response_time: u32 = (end - start).try_into().unwrap(); + unsafe { + if T3_MAX_RP < response_time { + T3_MAX_RP = response_time; + } + if T3_MAX_RP > 100_000 { + asm::bkpt(); + } + } } // RTIC requires that unused interrupts are declared in an extern block when @@ -124,6 +158,16 @@ const APP: () = { // `cx.schedule.t1(cx.scheduled + 100_000.cycles()).unwrap();` // // [Your answer here] +// The line: +// `cx.schedule.t1(cx.scheduled + 100_000.cycles()).unwrap();` +// schedules task t1 to be executed at instant(timestamp) cx.scheduled + 100 000 cycles = now plus +// ca 100 sec. The 100 000 cycles in this case is the inter arrival time of task t1. +// +// All the tasks are scheduled like this at the start of the program and when the tasks starts +// executing, thus the tasks will execute periodically. +// +// Source: https://rtic.rs/0.5/book/en/by-example/timer-queue.html +// // // Explain in your own words the difference between: // @@ -132,11 +176,21 @@ const APP: () = { // `cx.schedule.t1(cx.scheduled + 100_000.cycles()).unwrap();` // // [Your answer here] +// Instant::now() may have drift/jitter, meaning that it is not completely accurate. +// cx.scheduled has zero drift/jitter, thus it is accurate. +// +// +// Source: https://rtic.rs/0.5/book/en/by-example/timer-queue.html +// // // Explain in your own words why we use the latter // in order to generate a periodic task. // // [Your answer here] +// If we would use Instant::now() the timing of the periodic tasks would be a little inaccurate +// because Instant::now() has a little drift/jitter. cx.scheduled has zero drift/jitter and thus +// will have accurate timing of the periodic tasks. +// // // Hint, look at https://rtic.rs/0.5/book/en/by-example/timer-queue.html // @@ -157,6 +211,9 @@ const APP: () = { // Explain why this is needed (there is a good reason for it). // // [Your answer here] +// The global variables can be accessed by multiple processes and thus there is the problem of two +// or more processes accessing the same global variable at the same time. +// // // Implement this functionality for all tasks. //