aboutsummaryrefslogtreecommitdiffstats
path: root/examples/dummy.rs
blob: cfcd7178825df917415f0b95f8678391f934be37 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
use clint::Handler;

#[macro_use]
extern crate lazy_static;

// Wrapper used to call through to `example_handler` via `closure` in
// `main`. `Handler::new()` places a do-nothing handler in this at
// compile-time, in case the interrupt using this handler is fired
// before being `replace`d in `main`.
lazy_static! {
    static ref HANDLER: Handler<'static> = Handler::new();
}

fn main() {
    let mut x: u32 = 0;

    // Create a closure to take a mutable reference to `x` for use in
    // `example_handler`.
    let mut closure = move || example_handler(&mut x);

    // Swap out the do-nothing handler with our closure that calls
    // through to `example_handler`. Ideally, the interrupt which uses
    // this handler would be disabled while this happens, but as this
    // is a demo, and there aren't any actual interrupts firing, this
    // is left as an exercise to the reader.
    unsafe { HANDLER.replace(&mut closure) };

    // Simulate firing the interrupt.
    dummy_interrupt();
    dummy_interrupt();

    // Because `x` is `Copy`, we still have access to the symbol,
    // although its value won't be changed by `closure`.
    println!("x(o): {}", x);
}

// Not a real interrupt handler, but called like one. i.e.: simple
// function with no arguments.
//
// Calls through `HANDLER` to do its actual work.
fn dummy_interrupt() {
    unsafe { HANDLER.call() };
}

// The meat of the interrupt handler, which does work with whatever
// params were passed in via `closure` in `main`.
fn example_handler(x: &mut u32) {
    // Update our dummy value, just to show it works.
    *x += 2;
    println!("x: {}", x);
}