Skip to content
Snippets Groups Projects
Select Git revision
  • dfd79ce0996e48f823e6015eb357456d91b25e1e
  • master default protected
2 results

rtic_bare3.rs

Blame
  • Forked from Per Lindgren / e7020e_2021
    Source project has a limited visibility.
    rtic_bare3.rs 3.98 KiB
    //! rtic_bare3.rs
    //!
    //! Measuring execution time
    //!
    //! What it covers
    //! - Reading Rust documentation
    //! - Timing abstractions and semantics
    //! - Understanding Rust abstractions
    
    #![no_main]
    #![no_std]
    
    use cortex_m_semihosting::hprintln;
    use panic_semihosting as _;
    use rtic::cyccnt::Instant;
    use stm32f4;
    
    #[rtic::app(device = stm32f4)]
    const APP: () = {
        #[init]
        fn init(mut cx: init::Context) {
            cx.core.DWT.enable_cycle_counter();
    
            let start = Instant::now();
            wait(1_000_000);
            let end = Instant::now();
    
            // notice all printing outside of the section to measure!
            hprintln!("Start {:?}", start).ok();
            hprintln!("End {:?}", end).ok();
            // hprintln!("Diff {:?}", (end - start) ).ok();
        }
    };
    
    // burns CPU cycles by just looping `i` times
    #[inline(never)]
    #[no_mangle]
    fn wait(i: u32) {
        for _ in 0..i {
            // no operation (ensured not optimized out)
            cortex_m::asm::nop();
        }
    }
    
    // 0. Setup
    //
    //    > cargo doc --open
    //
    //    In the docs, search (`S`) for `Monotonic` and read the API docs.
    //    Also search for `Instant`, and `Duration`.
    //
    //    Together these provide timing semantics.
    //
    //    - `Monotonic` is a "trait" for a timer implementation.
    //    - `Instant` is a point in time.
    //    - `Duration` is a range in time.
    //
    //    By default RTIC uses the `Systic` and the `DWT` cycle counter
    //    to provide a `Monotonic` timer.
    //
    // 1. Build and run the application in vscode using (Cortex Release).
    //
    //    What is the output in the Adapter Output console?
    //
    //    ** your answer here **
    //
    //    As you see line 31 is commented out (we never print the difference).
    //
    //    Now uncomment line 31, and try to run the program. You will see
    //    that it fails to compile right as `Duration` does not implement `Debug`
    //    (needed for formatting the printout.)
    //
    //    This is on purpose as `Duration` is abstract (opaque). You need to
    //    turn it into a concrete value. Look at the documentation, to find out
    //    a way to turn it into clock cycles (which are printable).
    //
    //    What is now the output in the Adapter Output console?
    //
    //    ** your answer here **
    //
    //    Commit your answers (bare3_1)
    //
    // 2. Look at the `Instant` documentation.
    //
    //    Alter the code so that you use `duration_since`, instead of manual subtraction.
    //
    //    What is now the output in the Adapter Output console?
    //
    //    ** your answer here **
    //
    //    Commit your answers (bare3_2)
    //
    // 3. Look at the `Instant` documentation.
    //    Now alter the code so that it uses `elapsed` instead.
    //
    //    What is now the output in the Adapter Output console?
    //
    //    ** your answer here **
    //
    //    Commit your answers (bare3_3)
    //
    // 4. Discussion.
    //
    //    If you did implement the above exercises correctly you should get exactly the same
    //    result (in clock cycles) for all cases as you got in the bare2 exercise.
    //    (If not, go back and revise your code.)
    //
    //    What this shows, is that we can step away from pure hardware accesses
    //    and deal with time in a more convenient and "abstract" fashion.
    //
    //    `Instant` and `Duration` are associated with semantics (meaning).
    //    `Monotonic` is associated the implementation.
    //
    //    This is an example of separation of concerns!
    //
    //    If you implement your application based on Instant and Duration, your code
    //    will be "portable" across all platforms (that implement Monotonic).
    //
    //    The implementation of Monotonic is done only once for each platform, thus
    //    bugs related to low level timer access will occur only at one place,
    //    not scattered across thousands of manually written applications.
    //
    //    However, as you have already seen, the current time abstraction (API) is
    //    is rather "thin" (provided just a bare minimum functionality).
    //
    //    We are working to further generalize timing semantics, by building
    //    on a richer abstraction `https://docs.rs/embedded-time/0.10.1/embedded_time/`.
    //
    //    Support for embedded time is projected for next RTIC release.