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

hello.rs

Blame
  • rtic_bare3.rs 4.26 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();
    
            let diff = Instant::elapsed(&start);
    
            // notice all printing outside of the section to measure!
            hprintln!("Start {:?}", start).ok();
            hprintln!("End {:?}", end).ok();
            //let diff = Instant::duration_since(&end,start);
            hprintln!("Diff {:?}", diff.as_cycles()).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?
    //
    //    Start Instant(2694714472)
    //    End Instant(2698714489)
    //
    //    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?
    //
    //    Start Instant(2100880231)
    //    End Instant(2104880247)
    //    Diff 4000016
    //
    //    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?
    //
    //    Start Instant(20606036)
    //    End Instant(24606052)
    //    Diff 4000016
    //
    //    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?
    //
    //    Start Instant(2395620599)
    //    End Instant(2399620615)
    //    Diff 4000020
    
    //
    //    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.