Skip to content
This repository was archived by the owner on Aug 9, 2022. It is now read-only.

Commit 95c7596

Browse files
authored
Merge pull request #31 from arjanmels/feature-mutex-trait
Added Mutexes implemented in xtensa-lx6 to prelude & started using in timers example
2 parents 7e1953e + 26284c3 commit 95c7596

File tree

17 files changed

+549
-473
lines changed

17 files changed

+549
-473
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
procmacros/target
33
**/*.rs.bk
44
Cargo.lock
5-
.vscode/.cortex-debug*
5+
.vscode/.cortex-debug*
6+
core

Cargo.toml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,11 @@ rt = ["esp32/rt", "xtensa-lx6-rt"]
3232
[dependencies]
3333
esp32-hal-proc-macros = { path = "procmacros" }
3434

35-
xtensa-lx6-rt = { version = "0.2.0", optional = true }
36-
xtensa-lx6 = "0.1.0"
37-
esp32 = { version = "0.5.0", default-features = false }
35+
xtensa-lx6-rt = { version = "0.3.0", optional = true }
36+
xtensa-lx6 = "0.2.0"
37+
esp32 = "0.5.0"
3838
bare-metal = "0.2"
3939
nb = "0.1.2"
40-
spin = "0.5.2"
4140
embedded-hal = { version = "0.2.3", features = ["unproven"] }
4241
linked_list_allocator = { version = "0.8.4", optional = true, default-features = false, features = ["alloc_ref"] }
4342
void = { version = "1.0.2", default-features = false }

core

-6.98 MB
Binary file not shown.

examples/blinky.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ extern crate esp32_hal as hal;
55
extern crate panic_halt;
66
extern crate xtensa_lx6_rt;
77

8+
use esp32_hal::target;
89
use hal::prelude::*;
9-
use hal::target;
10-
use xtensa_lx6::get_cycle_count;
10+
use xtensa_lx6::timer::get_cycle_count;
1111

1212
/// The default clock source is the onboard crystal
1313
/// In most cases 40mhz (but can be as low as 2mhz depending on the board)

examples/exception.rs

Lines changed: 50 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -16,79 +16,62 @@ use esp32_hal::serial::{config::Config, NoRx, NoTx, Serial};
1616
use esp32_hal::target;
1717
use esp32_hal::Core::PRO;
1818

19-
static TX: spin::Mutex<Option<esp32_hal::serial::Tx<target::UART0>>> = spin::Mutex::new(None);
19+
// !!! Cannot use CriticalSectionSpinLockMutex here, because an NMI is fires from within a locked
20+
// section which leads to a deadlock in the NMI interrupt handler. This is not a problem in this
21+
// case as this is a single threaded example. !!!
22+
static TX: xtensa_lx6::mutex::CriticalSectionMutex<Option<esp32_hal::serial::Tx<esp32::UART0>>> =
23+
xtensa_lx6::mutex::CriticalSectionMutex::new(None);
24+
25+
fn locked_print(str: &str) {
26+
(&TX).lock(|tx| {
27+
let tx = tx.as_mut().unwrap();
28+
29+
writeln!(
30+
tx,
31+
" {}, Level: {}",
32+
str,
33+
xtensa_lx6::interrupt::get_level()
34+
)
35+
.unwrap();
36+
});
37+
}
2038

2139
#[interrupt]
2240
fn FROM_CPU_INTR0() {
23-
writeln!(
24-
TX.lock().as_mut().unwrap(),
25-
" FROM_CPU_INTR0, level: {}",
26-
xtensa_lx6::interrupt::get_level()
27-
)
28-
.unwrap();
41+
locked_print("FROM_CPU_INTR0");
2942
clear_software_interrupt(Interrupt::FROM_CPU_INTR0).unwrap();
3043
}
3144

3245
#[interrupt]
3346
fn FROM_CPU_INTR1() {
34-
writeln!(
35-
TX.lock().as_mut().unwrap(),
36-
" Start FROM_CPU_INTR1, level: {}",
37-
xtensa_lx6::interrupt::get_level()
38-
)
39-
.unwrap();
47+
locked_print("Start FROM_CPU_INTR1");
4048
interrupt::set_software_interrupt(Interrupt::FROM_CPU_INTR0).unwrap();
4149
interrupt::set_software_interrupt(Interrupt::FROM_CPU_INTR2).unwrap();
42-
writeln!(
43-
TX.lock().as_mut().unwrap(),
44-
" End FROM_CPU_INTR1, level: {}",
45-
xtensa_lx6::interrupt::get_level()
46-
)
47-
.unwrap();
50+
locked_print("End FROM_CPU_INTR1");
4851
clear_software_interrupt(Interrupt::FROM_CPU_INTR1).unwrap();
4952
}
5053

5154
#[interrupt]
5255
fn FROM_CPU_INTR2() {
53-
writeln!(
54-
TX.lock().as_mut().unwrap(),
55-
" FROM_CPU_INTR2, level: {}",
56-
xtensa_lx6::interrupt::get_level()
57-
)
58-
.unwrap();
56+
locked_print("FROM_CPU_INTR2");
5957
clear_software_interrupt(Interrupt::FROM_CPU_INTR2).unwrap();
6058
}
6159

6260
#[interrupt]
6361
fn FROM_CPU_INTR3() {
64-
writeln!(
65-
TX.lock().as_mut().unwrap(),
66-
" FROM_CPU_INTR3, level: {}",
67-
xtensa_lx6::interrupt::get_level()
68-
)
69-
.unwrap();
62+
locked_print("FROM_CPU_INTR3");
7063
clear_software_interrupt(Interrupt::FROM_CPU_INTR3).unwrap();
7164
}
7265

7366
#[interrupt(INTERNAL_SOFTWARE_LEVEL_3_INTR)]
7467
fn software_level_3() {
75-
writeln!(
76-
TX.lock().as_mut().unwrap(),
77-
" INTERNAL_SOFTWARE_LEVEL_3_INTR, level: {}",
78-
xtensa_lx6::interrupt::get_level()
79-
)
80-
.unwrap();
68+
locked_print("INTERNAL_SOFTWARE_LEVEL_3_INTR");
8169
clear_software_interrupt(Interrupt::FROM_CPU_INTR3).unwrap();
8270
}
8371

8472
#[interrupt(INTERNAL_SOFTWARE_LEVEL_1_INTR)]
8573
fn random_name() {
86-
writeln!(
87-
TX.lock().as_mut().unwrap(),
88-
" INTERNAL_SOFTWARE_LEVEL_1_INTR, level: {}",
89-
xtensa_lx6::interrupt::get_level()
90-
)
91-
.unwrap();
74+
locked_print("INTERNAL_SOFTWARE_LEVEL_1_INTR");
9275
clear_software_interrupt(Interrupt::FROM_CPU_INTR3).unwrap();
9376
}
9477

@@ -98,13 +81,10 @@ fn other_exception(
9881
cause: xtensa_lx6_rt::exception::ExceptionCause,
9982
frame: xtensa_lx6_rt::exception::Context,
10083
) {
101-
writeln!(
102-
TX.lock().as_mut().unwrap(),
103-
"Exception {:?}, {:08x?}",
104-
cause,
105-
frame
106-
)
107-
.unwrap();
84+
(&TX).lock(|tx| {
85+
let tx = tx.as_mut().unwrap();
86+
writeln!(tx, "Exception {:?}, {:08x?}", cause, frame).unwrap();
87+
});
10888
loop {}
10989
}
11090

@@ -156,7 +136,7 @@ fn main() -> ! {
156136
writeln!(uart0, "\n\nReboot!\n",).unwrap();
157137

158138
let (tx, _) = uart0.split();
159-
*TX.lock() = Some(tx);
139+
(&TX).lock(|tx_locked| *tx_locked = Some(tx));
160140

161141
interrupt::enable_with_priority(PRO, Interrupt::FROM_CPU_INTR0, InterruptLevel(2)).unwrap();
162142
interrupt::enable_with_priority(PRO, Interrupt::FROM_CPU_INTR1, InterruptLevel(4)).unwrap();
@@ -167,32 +147,40 @@ fn main() -> ! {
167147

168148
// Trigger various software interrupts, because done in an interrupt free section will
169149
// actually trigger at the end in order of priority
170-
interrupt::free(|_| {
171-
writeln!(TX.lock().as_mut().unwrap(), "Start Trigger Interrupts",).unwrap();
150+
(&TX).lock(|tx| {
151+
let tx = tx.as_mut().unwrap();
152+
153+
writeln!(tx, "Start Trigger Interrupts",).unwrap();
172154
interrupt::set_software_interrupt(Interrupt::FROM_CPU_INTR0).unwrap();
173155
interrupt::set_software_interrupt(Interrupt::FROM_CPU_INTR1).unwrap();
174156
interrupt::set_software_interrupt(Interrupt::FROM_CPU_INTR2).unwrap();
175157
// this one will trigger immediately as level 7 is Non-Maskable Intterupt (NMI)
176158
interrupt::set_software_interrupt(Interrupt::FROM_CPU_INTR3).unwrap();
177159
interrupt::set_software_interrupt(Interrupt::INTERNAL_SOFTWARE_LEVEL_1_INTR).unwrap();
178160
interrupt::set_software_interrupt(Interrupt::INTERNAL_SOFTWARE_LEVEL_3_INTR).unwrap();
179-
writeln!(TX.lock().as_mut().unwrap(), "End Trigger Interrupts",).unwrap();
161+
writeln!(tx, "End Trigger Interrupts",).unwrap();
180162
});
181163

182164
// Trigger outside of interrupt free section, triggers immediately
183-
writeln!(TX.lock().as_mut().unwrap(), "Start Trigger Interrupt",).unwrap();
165+
(&TX).lock(|tx| {
166+
let tx = tx.as_mut().unwrap();
167+
writeln!(tx, "Start Trigger Interrupt",).unwrap();
168+
});
184169
interrupt::set_software_interrupt(Interrupt::FROM_CPU_INTR0).unwrap();
185170
interrupt::set_software_interrupt(Interrupt::FROM_CPU_INTR1).unwrap();
186171
interrupt::set_software_interrupt(Interrupt::FROM_CPU_INTR2).unwrap();
187172
// this one will trigger immediately as level 7 is Non-Maskable Intterupt (NMI)
188173
interrupt::set_software_interrupt(Interrupt::FROM_CPU_INTR3).unwrap();
189174
interrupt::set_software_interrupt(Interrupt::INTERNAL_SOFTWARE_LEVEL_1_INTR).unwrap();
190175
interrupt::set_software_interrupt(Interrupt::INTERNAL_SOFTWARE_LEVEL_3_INTR).unwrap();
191-
writeln!(TX.lock().as_mut().unwrap(), "End Trigger Interrupt",).unwrap();
192176

193-
// Trigger a LoadStoreError due to unaligned access in the IRAM
177+
(&TX).lock(|tx| {
178+
let tx = tx.as_mut().unwrap();
179+
writeln!(tx, "End Trigger Interrupt",).unwrap();
180+
writeln!(tx, "\nTrigger exception:",).unwrap();
181+
});
194182

195-
writeln!(TX.lock().as_mut().unwrap(), "\nTrigger exception:",).unwrap();
183+
// Trigger a LoadStoreError due to unaligned access in the IRAM
196184

197185
#[link_section = ".rwtext"]
198186
static mut IRAM: [u8; 12] = [0; 12];
@@ -203,8 +191,10 @@ fn main() -> ! {
203191

204192
loop {
205193
sleep(1.s());
206-
interrupt::free(|_| {
207-
writeln!(TX.lock().as_mut().unwrap(), "Wait for watchdog reset").unwrap()
194+
(&TX).lock(|tx| {
195+
let tx = tx.as_mut().unwrap();
196+
197+
writeln!(tx, "Wait for watchdog reset").unwrap()
208198
});
209199
}
210200
}

examples/multicore.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@ use esp32_hal::dprintln;
1212
use esp32_hal::serial::{config::Config, NoRx, NoTx, Serial};
1313
use esp32_hal::target;
1414

15-
use xtensa_lx6::{get_cycle_count, get_stack_pointer};
15+
use xtensa_lx6::{get_stack_pointer, timer::get_cycle_count};
1616

1717
const BLINK_HZ: Hertz = Hertz(1);
1818

1919
static GLOBAL_COUNT: core::sync::atomic::AtomicU32 = core::sync::atomic::AtomicU32::new(0);
20-
static TX: spin::Mutex<Option<esp32_hal::serial::Tx<target::UART0>>> = spin::Mutex::new(None);
20+
static TX: CriticalSectionSpinLockMutex<Option<esp32_hal::serial::Tx<esp32::UART0>>> =
21+
CriticalSectionSpinLockMutex::new(None);
2122

2223
#[no_mangle]
2324
fn main() -> ! {
@@ -100,14 +101,12 @@ fn main() -> ! {
100101
// panic!("panic test");
101102

102103
let (tx, _) = uart0.split();
103-
*TX.lock() = Some(tx);
104+
(&TX).lock(|locked_tx| *locked_tx = Some(tx));
104105

105106
let _lock = clock_control_config.lock_cpu_frequency();
106107

107108
// start core 1 (APP_CPU)
108-
clock_control_config
109-
.start_core(esp32_hal::Core::APP, cpu1_start)
110-
.unwrap();
109+
clock_control_config.start_app_core(cpu1_start).unwrap();
111110

112111
// main loop, which in turn lock and unlocks apb and cpu locks
113112
let mut x: u32 = 0;
@@ -156,12 +155,14 @@ fn cpu1_start() -> ! {
156155
let mut x: u32 = 0;
157156
let mut prev_ccount = 0;
158157

159-
writeln!(
160-
TX.lock().as_mut().unwrap(),
161-
"Stack Pointer Core 1: {:08x?}",
162-
get_stack_pointer()
163-
)
164-
.unwrap();
158+
(&TX).lock(|tx| {
159+
writeln!(
160+
tx.as_mut().unwrap(),
161+
"Stack Pointer Core 1: {:08x?}",
162+
get_stack_pointer()
163+
)
164+
.unwrap()
165+
});
165166

166167
loop {
167168
let cycles = ClockControlConfig {}.cpu_frequency() / BLINK_HZ;
@@ -182,8 +183,9 @@ fn print_info(loop_count: u32, spin_loop_count: u32, prev_ccount: &mut u32) {
182183

183184
let total = GLOBAL_COUNT.fetch_add(ccount_diff, core::sync::atomic::Ordering::Relaxed);
184185

185-
writeln!(
186-
TX.lock().as_mut().unwrap(),
186+
(&TX).lock(|tx| {
187+
188+
writeln!(tx.as_mut().unwrap(),
187189
"Core: {:?}, Loop: {}, Spin loops:{}, cycles: {}, cycles since previous {}, Total cycles: {}",
188190
esp32_hal::get_core(),
189191
loop_count,
@@ -193,6 +195,7 @@ fn print_info(loop_count: u32, spin_loop_count: u32, prev_ccount: &mut u32) {
193195
total
194196
)
195197
.unwrap();
198+
});
196199

197200
*prev_ccount = ccount;
198201
}

examples/rtccntl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ fn main() -> ! {
118118

119119
x = x.wrapping_add(1);
120120

121-
let ccount = xtensa_lx6::get_cycle_count();
121+
let ccount = xtensa_lx6::timer::get_cycle_count();
122122
let ccount_diff = ccount.wrapping_sub(prev_ccount);
123123

124124
writeln!(

0 commit comments

Comments
 (0)