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
|
//! Nesting claims and how the preemption threshold works
//!
//! If you run this program you'll hit the breakpoints as indicated by the
//! letters in the comments: A, then B, then C, etc.
//!
//! ```
//! #![deny(unsafe_code)]
//! #![deny(warnings)]
//! #![feature(proc_macro)]
//! #![no_std]
//!
//! extern crate cortex_m_rtfm as rtfm;
//! extern crate stm32f103xx;
//!
//! use stm32f103xx::Interrupt;
//! use rtfm::{app, Resource, Threshold};
//!
//! app! {
//! device: stm32f103xx,
//!
//! resources: {
//! static LOW: u64 = 0;
//! static HIGH: u64 = 0;
//! },
//!
//! tasks: {
//! EXTI0: {
//! path: exti0,
//! priority: 1,
//! resources: [LOW, HIGH],
//! },
//!
//! EXTI1: {
//! path: exti1,
//! priority: 2,
//! resources: [LOW],
//! },
//!
//! EXTI2: {
//! path: exti2,
//! priority: 3,
//! resources: [HIGH],
//! },
//! },
//! }
//!
//! fn init(_p: init::Peripherals, _r: init::Resources) {}
//!
//! fn idle() -> ! {
//! // A
//! rtfm::bkpt();
//!
//! // Sets task `exti0` as pending
//! //
//! // Because `exti0` has higher priority than `idle` it will be executed
//! // immediately
//! rtfm::set_pending(Interrupt::EXTI0); // ~> exti0
//!
//! loop {
//! rtfm::wfi();
//! }
//! }
//!
//! #[allow(non_snake_case)]
//! fn exti0(
//! t: &mut Threshold,
//! EXTI0::Resources { mut LOW, mut HIGH }: EXTI0::Resources,
//! ) {
//! // Because this task has a priority of 1 the preemption threshold `t` also
//! // starts at 1
//!
//! // B
//! rtfm::bkpt();
//!
//! // Because `exti1` has higher priority than `exti0` it can preempt it
//! rtfm::set_pending(Interrupt::EXTI1); // ~> exti1
//!
//! // A claim creates a critical section
//! LOW.claim_mut(t, |_low, t| {
//! // This claim increases the preemption threshold to 2
//! //
//! // 2 is just high enough to not race with task `exti1` for access to the
//! // `LOW` resource
//!
//! // D
//! rtfm::bkpt();
//!
//! // Now `exti1` can't preempt this task because its priority is equal to
//! // the current preemption threshold
//! rtfm::set_pending(Interrupt::EXTI1);
//!
//! // But `exti2` can, because its priority is higher than the current
//! // preemption threshold
//! rtfm::set_pending(Interrupt::EXTI2); // ~> exti2
//!
//! // F
//! rtfm::bkpt();
//!
//! // Claims can be nested
//! HIGH.claim_mut(t, |_high, _| {
//! // This claim increases the preemption threshold to 3
//!
//! // Now `exti2` can't preempt this task
//! rtfm::set_pending(Interrupt::EXTI2);
//!
//! // G
//! rtfm::bkpt();
//! });
//!
//! // Upon leaving the critical section the preemption threshold drops back
//! // to 2 and `exti2` immediately preempts this task
//! // ~> exti2
//! });
//!
//! // Once again the preemption threshold drops but this time to 1. Now the
//! // pending `exti1` task can preempt this task
//! // ~> exti1
//! }
//!
//! fn exti1(_t: &mut Threshold, _r: EXTI1::Resources) {
//! // C, I
//! rtfm::bkpt();
//! }
//!
//! fn exti2(_t: &mut Threshold, _r: EXTI2::Resources) {
//! // E, H
//! rtfm::bkpt();
//! }
//! ```
// Auto-generated. Do not modify.
|