aboutsummaryrefslogtreecommitdiff
path: root/examples/complex.rs
blob: 73df025d2fcb9146d87dcb217eb247b977e666a0 (plain) (blame)
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//! examples/complex.rs

#![deny(unsafe_code)]
#![deny(warnings)]
#![deny(missing_docs)]
#![no_main]
#![no_std]

use panic_semihosting as _;

#[rtic::app(device = lm3s6965)]
mod app {

    use cortex_m_semihosting::{debug, hprintln};
    use lm3s6965::Interrupt;

    #[shared]
    struct Shared {
        s2: u32, // shared with ceiling 2
        s3: u32, // shared with ceiling 3
        s4: u32, // shared with ceiling 4
    }

    #[local]
    struct Local {}

    #[init]
    fn init(_: init::Context) -> (Shared, Local, init::Monotonics) {
        hprintln!("init");

        (
            Shared {
                s2: 0,
                s3: 0,
                s4: 0,
            },
            Local {},
            init::Monotonics(),
        )
    }

    #[idle(shared = [s2, s3])]
    fn idle(mut cx: idle::Context) -> ! {
        hprintln!("idle p0 started");
        rtic::pend(Interrupt::GPIOC);
        cx.shared.s3.lock(|s| {
            hprintln!("idle enter lock s3 {}", s);
            hprintln!("idle pend t0");
            rtic::pend(Interrupt::GPIOA); // t0 p2, with shared ceiling 3
            hprintln!("idle pend t1");
            rtic::pend(Interrupt::GPIOB); // t1 p3, with shared ceiling 3
            hprintln!("idle pend t2");
            rtic::pend(Interrupt::GPIOC); // t2 p4, no sharing
            hprintln!("idle still in lock s3 {}", s);
        });
        hprintln!("\nback in idle");

        cx.shared.s2.lock(|s| {
            hprintln!("enter lock s2 {}", s);
            hprintln!("idle pend t0");
            rtic::pend(Interrupt::GPIOA); // t0 p2, with shared ceiling 2
            hprintln!("idle pend t1");
            rtic::pend(Interrupt::GPIOB); // t1 p3, no sharing
            hprintln!("idle pend t2");
            rtic::pend(Interrupt::GPIOC); // t2 p4, no sharing
            hprintln!("idle still in lock s2 {}", s);
        });
        hprintln!("\nidle exit");

        debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator

        loop {
            cortex_m::asm::nop();
        }
    }

    #[task(binds = GPIOA, priority = 2, local = [times: u32 = 0], shared = [s2, s3])]
    fn t0(cx: t0::Context) {
        // Safe access to local `static mut` variable
        *cx.local.times += 1;

        hprintln!(
            "t0 p2 called {} time{}",
            *cx.local.times,
            if *cx.local.times > 1 { "s" } else { "" }
        );
        hprintln!("t0 p2 exit");
    }

    #[task(binds = GPIOB, priority = 3, local = [times: u32 = 0], shared = [s3, s4])]
    fn t1(mut cx: t1::Context) {
        // Safe access to local `static mut` variable
        *cx.local.times += 1;

        hprintln!(
            "t1 p3 called {} time{}",
            *cx.local.times,
            if *cx.local.times > 1 { "s" } else { "" }
        );

        cx.shared.s4.lock(|s| {
            hprintln!("t1 enter lock s4 {}", s);
            hprintln!("t1 pend t0");
            rtic::pend(Interrupt::GPIOA); // t0 p2, with shared ceiling 2
            hprintln!("t1 pend t2");
            rtic::pend(Interrupt::GPIOC); // t2 p4, no sharing
            hprintln!("t1 still in lock s4 {}", s);
        });

        hprintln!("t1 p3 exit");
    }

    #[task(binds = GPIOC, priority = 4, local = [times: u32 = 0], shared = [s4])]
    fn t2(mut cx: t2::Context) {
        // Safe access to local `static mut` variable
        *cx.local.times += 1;

        hprintln!(
            "t2 p4 called {} time{}",
            *cx.local.times,
            if *cx.local.times > 1 { "s" } else { "" }
        );

        cx.shared.s4.lock(|s| {
            hprintln!("enter lock s4 {}", s);
            *s += 1;
        });
        hprintln!("t3 p4 exit");
    }
}