├── .gitignore ├── .cargo └── Config.toml ├── README.md ├── Cargo.toml ├── src ├── main.rs └── preempt.rs └── Cargo.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /.cargo/Config.toml: -------------------------------------------------------------------------------- 1 | [target.xtensa-esp32-none-elf] 2 | runner = "espflash --monitor" 3 | 4 | [build] 5 | rustflags = [ 6 | "-C", "link-arg=-nostartfiles", 7 | "-C", "link-arg=-Wl,-Tlinkall.x", 8 | ] 9 | target = "xtensa-esp32-none-elf" 10 | 11 | [unstable] 12 | build-std = ["core"] 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Experiment for preemtive multitasking on ESP32 in bare-metal Rust 2 | 3 | This is just a small experiment having a main task and two additional tasks running on ESP32. 4 | 5 | The code is meant to be as simple as possible to make it easy to understand. 6 | 7 | Please note: Since this uses simple `for`-loops as delays it won't work in release mode! 8 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "esp32-preemt-experiment" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | esp32-hal = { git = "https://github.com/esp-rs/esp-hal", package = "esp32-hal" } 10 | xtensa-lx-rt = { version = "0.10.0", features = ["esp32"] } 11 | xtensa-lx = { version = "0.6.0", features = ["esp32"] } 12 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![no_main] 3 | 4 | use core::{cell::RefCell, fmt::Write}; 5 | 6 | use esp32_hal::{interrupt, Cpu}; 7 | use esp32_hal::{ 8 | pac::{self, Peripherals, TIMG1, UART0}, 9 | prelude::*, 10 | RtcCntl, Serial, Timer, 11 | }; 12 | use xtensa_lx::mutex::{Mutex, SpinLockMutex}; 13 | use xtensa_lx_rt::entry; 14 | use xtensa_lx_rt::exception::Context; 15 | 16 | mod preempt; 17 | use preempt::*; 18 | 19 | static mut SERIAL: SpinLockMutex>>> = 20 | SpinLockMutex::new(RefCell::new(None)); 21 | static mut TIMER1: SpinLockMutex>>> = 22 | SpinLockMutex::new(RefCell::new(None)); 23 | 24 | const TIMER_DELAY: u64 = 10_000u64; 25 | 26 | #[entry] 27 | fn main() -> ! { 28 | let peripherals = Peripherals::take().unwrap(); 29 | 30 | // Disable the TIMG watchdog timer. 31 | let mut timer0 = Timer::new(peripherals.TIMG0); 32 | let mut timer1 = Timer::new(peripherals.TIMG1); 33 | let serial0 = Serial::new(peripherals.UART0).unwrap(); 34 | let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); 35 | 36 | // Disable MWDT and RWDT (Watchdog) flash boot protection 37 | timer0.disable(); 38 | timer1.disable(); 39 | rtc_cntl.set_wdt_global_enable(false); 40 | 41 | interrupt::enable( 42 | Cpu::ProCpu, 43 | pac::Interrupt::TG1_T0_LEVEL, 44 | interrupt::CpuInterrupt::Interrupt20LevelPriority2, 45 | ); 46 | timer1.start(TIMER_DELAY); 47 | timer1.listen(); 48 | 49 | unsafe { 50 | (&SERIAL).lock(|data| (*data).replace(Some(serial0))); 51 | (&TIMER1).lock(|data| (*data).replace(Some(timer1))); 52 | } 53 | 54 | task_create(worker_task1); 55 | task_create(worker_task2); 56 | 57 | unsafe { 58 | xtensa_lx::interrupt::disable(); 59 | xtensa_lx::interrupt::enable_mask( 60 | xtensa_lx_rt::interrupt::CpuInterruptLevel::Level2.mask(), 61 | ); 62 | } 63 | 64 | let mut z = 0; 65 | loop { 66 | unsafe { 67 | (&SERIAL).lock(|data| { 68 | let mut serial = data.borrow_mut(); 69 | let serial = serial.as_mut().unwrap(); 70 | writeln!(serial, "Task Main {}", z).ok(); 71 | }); 72 | } 73 | 74 | for _ in 0..200_000 {} 75 | z += 1; 76 | } 77 | } 78 | 79 | pub extern "C" fn worker_task1() { 80 | let mut cnt = 0; 81 | 82 | loop { 83 | unsafe { 84 | (&SERIAL).lock(|data| { 85 | let mut serial = data.borrow_mut(); 86 | let serial = serial.as_mut().unwrap(); 87 | writeln!(serial, "Task A: {}", cnt).ok(); 88 | }); 89 | } 90 | 91 | cnt += 1; 92 | 93 | for _ in 0..100_000 {} 94 | } 95 | } 96 | 97 | pub extern "C" fn worker_task2() { 98 | let mut cnt = 0; 99 | 100 | loop { 101 | unsafe { 102 | (&SERIAL).lock(|data| { 103 | let mut serial = data.borrow_mut(); 104 | let serial = serial.as_mut().unwrap(); 105 | writeln!(serial, "Task B: {}", cnt).ok(); 106 | }); 107 | } 108 | 109 | cnt += 1; 110 | 111 | for _ in 0..50_000 {} 112 | } 113 | } 114 | 115 | #[no_mangle] 116 | pub fn level2_interrupt(context: &mut Context) { 117 | interrupt::clear( 118 | Cpu::ProCpu, 119 | interrupt::CpuInterrupt::Interrupt20LevelPriority2, 120 | ); 121 | 122 | unsafe { 123 | (&TIMER1).lock(|data| { 124 | let mut timer1 = data.borrow_mut(); 125 | let timer1 = timer1.as_mut().unwrap(); 126 | timer1.clear_interrupt(); 127 | timer1.start(TIMER_DELAY); 128 | }); 129 | } 130 | 131 | task_switch(context); 132 | } 133 | 134 | #[panic_handler] 135 | fn panic(info: &core::panic::PanicInfo) -> ! { 136 | unsafe { 137 | (&SERIAL).lock(|data| { 138 | let mut serial = data.borrow_mut(); 139 | let serial = serial.as_mut().unwrap(); 140 | writeln!(serial, "\n\n*** {:?}", info).ok(); 141 | }); 142 | } 143 | 144 | loop {} 145 | } 146 | -------------------------------------------------------------------------------- /src/preempt.rs: -------------------------------------------------------------------------------- 1 | use xtensa_lx_rt::exception::Context; 2 | 3 | #[derive(Debug, Clone, Copy)] 4 | pub struct TaskContext { 5 | trap_frame: Context, 6 | } 7 | 8 | pub const STACK_SIZE: usize = 8192; 9 | const MAX_TASK: usize = 4; 10 | 11 | pub static mut TASK_STACK: [u8; STACK_SIZE * MAX_TASK] = [0x0u8; STACK_SIZE * MAX_TASK]; 12 | 13 | pub static mut FIRST_SWITCH: bool = true; 14 | 15 | pub static mut TASK_TOP: usize = 0; 16 | 17 | pub static mut CTX_NOW: usize = 0; 18 | 19 | pub static mut CTX_TASKS: [TaskContext; MAX_TASK] = [TaskContext { 20 | trap_frame: Context { 21 | PC: 0, 22 | PS: 0, 23 | A0: 0, 24 | A1: 0, 25 | A2: 0, 26 | A3: 0, 27 | A4: 0, 28 | A5: 0, 29 | A6: 0, 30 | A7: 0, 31 | A8: 0, 32 | A9: 0, 33 | A10: 0, 34 | A11: 0, 35 | A12: 0, 36 | A13: 0, 37 | A14: 0, 38 | A15: 0, 39 | SAR: 0, 40 | EXCCAUSE: 0, 41 | EXCVADDR: 0, 42 | LBEG: 0, 43 | LEND: 0, 44 | LCOUNT: 0, 45 | THREADPTR: 0, 46 | SCOMPARE1: 0, 47 | BR: 0, 48 | ACCLO: 0, 49 | ACCHI: 0, 50 | M0: 0, 51 | M1: 0, 52 | M2: 0, 53 | M3: 0, 54 | F64R_LO: 0, 55 | F64R_HI: 0, 56 | F64S: 0, 57 | FCR: 0, 58 | FSR: 0, 59 | F0: 0, 60 | F1: 0, 61 | F2: 0, 62 | F3: 0, 63 | F4: 0, 64 | F5: 0, 65 | F6: 0, 66 | F7: 0, 67 | F8: 0, 68 | F9: 0, 69 | F10: 0, 70 | F11: 0, 71 | F12: 0, 72 | F13: 0, 73 | F14: 0, 74 | F15: 0, 75 | }, 76 | }; MAX_TASK]; 77 | 78 | pub fn task_create(task: extern "C" fn()) -> usize { 79 | unsafe { 80 | let i = TASK_TOP; 81 | TASK_TOP += 1; 82 | 83 | CTX_TASKS[i].trap_frame.PC = task as u32; 84 | 85 | // stack must be aligned by 16 86 | let task_stack_ptr = (&TASK_STACK as *const _ as usize 87 | + (STACK_SIZE as usize * i as usize) 88 | + STACK_SIZE as usize 89 | - 4) as u32; 90 | let stack_ptr = task_stack_ptr - (task_stack_ptr % 0x10); 91 | CTX_TASKS[i].trap_frame.A1 = stack_ptr; 92 | 93 | CTX_TASKS[i].trap_frame.PS = 0x00040000 | (1 & 3) << 16; // For windowed ABI set WOE and CALLINC (pretend task was 'call4'd). 94 | 95 | CTX_TASKS[i].trap_frame.A0 = 0; 96 | 97 | *((task_stack_ptr - 4) as *mut u32) = 0; 98 | *((task_stack_ptr - 8) as *mut u32) = 0; 99 | *((task_stack_ptr - 12) as *mut u32) = 0; 100 | *((task_stack_ptr - 16) as *mut u32) = 0; 101 | 102 | CTX_NOW = i; 103 | i 104 | } 105 | } 106 | 107 | pub fn task_to_trap_frame(id: usize, trap_frame: &mut Context) { 108 | unsafe { 109 | trap_frame.PC = CTX_TASKS[id].trap_frame.PC; 110 | trap_frame.PS = CTX_TASKS[id].trap_frame.PS; 111 | trap_frame.A0 = CTX_TASKS[id].trap_frame.A0; 112 | trap_frame.A1 = CTX_TASKS[id].trap_frame.A1; 113 | trap_frame.A2 = CTX_TASKS[id].trap_frame.A2; 114 | trap_frame.A3 = CTX_TASKS[id].trap_frame.A3; 115 | trap_frame.A4 = CTX_TASKS[id].trap_frame.A4; 116 | trap_frame.A5 = CTX_TASKS[id].trap_frame.A5; 117 | trap_frame.A6 = CTX_TASKS[id].trap_frame.A6; 118 | trap_frame.A7 = CTX_TASKS[id].trap_frame.A7; 119 | trap_frame.A8 = CTX_TASKS[id].trap_frame.A8; 120 | trap_frame.A9 = CTX_TASKS[id].trap_frame.A9; 121 | trap_frame.A10 = CTX_TASKS[id].trap_frame.A10; 122 | trap_frame.A11 = CTX_TASKS[id].trap_frame.A11; 123 | trap_frame.A12 = CTX_TASKS[id].trap_frame.A12; 124 | trap_frame.A13 = CTX_TASKS[id].trap_frame.A13; 125 | trap_frame.A14 = CTX_TASKS[id].trap_frame.A14; 126 | trap_frame.A15 = CTX_TASKS[id].trap_frame.A15; 127 | trap_frame.SAR = CTX_TASKS[id].trap_frame.SAR; 128 | trap_frame.EXCCAUSE = CTX_TASKS[id].trap_frame.EXCCAUSE; 129 | trap_frame.EXCVADDR = CTX_TASKS[id].trap_frame.EXCVADDR; 130 | trap_frame.LBEG = CTX_TASKS[id].trap_frame.LBEG; 131 | trap_frame.LEND = CTX_TASKS[id].trap_frame.LEND; 132 | trap_frame.LCOUNT = CTX_TASKS[id].trap_frame.LCOUNT; 133 | trap_frame.THREADPTR = CTX_TASKS[id].trap_frame.THREADPTR; 134 | trap_frame.SCOMPARE1 = CTX_TASKS[id].trap_frame.SCOMPARE1; 135 | trap_frame.BR = CTX_TASKS[id].trap_frame.BR; 136 | trap_frame.ACCLO = CTX_TASKS[id].trap_frame.ACCLO; 137 | trap_frame.ACCHI = CTX_TASKS[id].trap_frame.ACCHI; 138 | trap_frame.M0 = CTX_TASKS[id].trap_frame.M0; 139 | trap_frame.M1 = CTX_TASKS[id].trap_frame.M1; 140 | trap_frame.M2 = CTX_TASKS[id].trap_frame.M2; 141 | trap_frame.M3 = CTX_TASKS[id].trap_frame.M3; 142 | trap_frame.F64R_LO = CTX_TASKS[id].trap_frame.F64R_LO; 143 | trap_frame.F64R_HI = CTX_TASKS[id].trap_frame.F64R_HI; 144 | trap_frame.F64S = CTX_TASKS[id].trap_frame.F64S; 145 | trap_frame.FCR = CTX_TASKS[id].trap_frame.FCR; 146 | trap_frame.FSR = CTX_TASKS[id].trap_frame.FSR; 147 | trap_frame.F0 = CTX_TASKS[id].trap_frame.F0; 148 | trap_frame.F1 = CTX_TASKS[id].trap_frame.F1; 149 | trap_frame.F2 = CTX_TASKS[id].trap_frame.F2; 150 | trap_frame.F3 = CTX_TASKS[id].trap_frame.F3; 151 | trap_frame.F4 = CTX_TASKS[id].trap_frame.F4; 152 | trap_frame.F5 = CTX_TASKS[id].trap_frame.F5; 153 | trap_frame.F6 = CTX_TASKS[id].trap_frame.F6; 154 | trap_frame.F7 = CTX_TASKS[id].trap_frame.F7; 155 | trap_frame.F8 = CTX_TASKS[id].trap_frame.F8; 156 | trap_frame.F9 = CTX_TASKS[id].trap_frame.F9; 157 | trap_frame.F10 = CTX_TASKS[id].trap_frame.F10; 158 | trap_frame.F11 = CTX_TASKS[id].trap_frame.F11; 159 | trap_frame.F12 = CTX_TASKS[id].trap_frame.F12; 160 | trap_frame.F13 = CTX_TASKS[id].trap_frame.F13; 161 | trap_frame.F14 = CTX_TASKS[id].trap_frame.F14; 162 | trap_frame.F15 = CTX_TASKS[id].trap_frame.F15; 163 | } 164 | } 165 | 166 | pub fn trap_frame_to_task(id: usize, trap_frame: &Context) { 167 | unsafe { 168 | CTX_TASKS[id].trap_frame.PC = trap_frame.PC; 169 | CTX_TASKS[id].trap_frame.PS = trap_frame.PS; 170 | CTX_TASKS[id].trap_frame.A0 = trap_frame.A0; 171 | CTX_TASKS[id].trap_frame.A1 = trap_frame.A1; 172 | CTX_TASKS[id].trap_frame.A2 = trap_frame.A2; 173 | CTX_TASKS[id].trap_frame.A3 = trap_frame.A3; 174 | CTX_TASKS[id].trap_frame.A4 = trap_frame.A4; 175 | CTX_TASKS[id].trap_frame.A5 = trap_frame.A5; 176 | CTX_TASKS[id].trap_frame.A6 = trap_frame.A6; 177 | CTX_TASKS[id].trap_frame.A7 = trap_frame.A7; 178 | CTX_TASKS[id].trap_frame.A8 = trap_frame.A8; 179 | CTX_TASKS[id].trap_frame.A9 = trap_frame.A9; 180 | CTX_TASKS[id].trap_frame.A10 = trap_frame.A10; 181 | CTX_TASKS[id].trap_frame.A11 = trap_frame.A11; 182 | CTX_TASKS[id].trap_frame.A12 = trap_frame.A12; 183 | CTX_TASKS[id].trap_frame.A13 = trap_frame.A13; 184 | CTX_TASKS[id].trap_frame.A14 = trap_frame.A14; 185 | CTX_TASKS[id].trap_frame.A15 = trap_frame.A15; 186 | CTX_TASKS[id].trap_frame.SAR = trap_frame.SAR; 187 | CTX_TASKS[id].trap_frame.EXCCAUSE = trap_frame.EXCCAUSE; 188 | CTX_TASKS[id].trap_frame.EXCVADDR = trap_frame.EXCVADDR; 189 | CTX_TASKS[id].trap_frame.LBEG = trap_frame.LBEG; 190 | CTX_TASKS[id].trap_frame.LEND = trap_frame.LEND; 191 | CTX_TASKS[id].trap_frame.LCOUNT = trap_frame.LCOUNT; 192 | CTX_TASKS[id].trap_frame.THREADPTR = trap_frame.THREADPTR; 193 | CTX_TASKS[id].trap_frame.SCOMPARE1 = trap_frame.SCOMPARE1; 194 | CTX_TASKS[id].trap_frame.BR = trap_frame.BR; 195 | CTX_TASKS[id].trap_frame.ACCLO = trap_frame.ACCLO; 196 | CTX_TASKS[id].trap_frame.ACCHI = trap_frame.ACCHI; 197 | CTX_TASKS[id].trap_frame.M0 = trap_frame.M0; 198 | CTX_TASKS[id].trap_frame.M1 = trap_frame.M1; 199 | CTX_TASKS[id].trap_frame.M2 = trap_frame.M2; 200 | CTX_TASKS[id].trap_frame.M3 = trap_frame.M3; 201 | CTX_TASKS[id].trap_frame.F64R_LO = trap_frame.F64R_LO; 202 | CTX_TASKS[id].trap_frame.F64R_HI = trap_frame.F64R_HI; 203 | CTX_TASKS[id].trap_frame.F64S = trap_frame.F64S; 204 | CTX_TASKS[id].trap_frame.FCR = trap_frame.FCR; 205 | CTX_TASKS[id].trap_frame.FSR = trap_frame.FSR; 206 | CTX_TASKS[id].trap_frame.F0 = trap_frame.F0; 207 | CTX_TASKS[id].trap_frame.F1 = trap_frame.F1; 208 | CTX_TASKS[id].trap_frame.F2 = trap_frame.F2; 209 | CTX_TASKS[id].trap_frame.F3 = trap_frame.F3; 210 | CTX_TASKS[id].trap_frame.F4 = trap_frame.F4; 211 | CTX_TASKS[id].trap_frame.F5 = trap_frame.F5; 212 | CTX_TASKS[id].trap_frame.F6 = trap_frame.F6; 213 | CTX_TASKS[id].trap_frame.F7 = trap_frame.F7; 214 | CTX_TASKS[id].trap_frame.F8 = trap_frame.F8; 215 | CTX_TASKS[id].trap_frame.F9 = trap_frame.F9; 216 | CTX_TASKS[id].trap_frame.F10 = trap_frame.F10; 217 | CTX_TASKS[id].trap_frame.F11 = trap_frame.F11; 218 | CTX_TASKS[id].trap_frame.F12 = trap_frame.F12; 219 | CTX_TASKS[id].trap_frame.F13 = trap_frame.F13; 220 | CTX_TASKS[id].trap_frame.F14 = trap_frame.F14; 221 | CTX_TASKS[id].trap_frame.F15 = trap_frame.F15; 222 | } 223 | } 224 | 225 | pub fn next_task() { 226 | unsafe { 227 | CTX_NOW = (CTX_NOW + 1) % TASK_TOP; 228 | } 229 | } 230 | 231 | pub fn task_switch(trap_frame: &mut Context) { 232 | unsafe { 233 | if FIRST_SWITCH { 234 | FIRST_SWITCH = false; 235 | TASK_TOP += 1; 236 | CTX_NOW = TASK_TOP - 1; 237 | } 238 | 239 | trap_frame_to_task(CTX_NOW, trap_frame); 240 | next_task(); 241 | task_to_trap_frame(CTX_NOW, trap_frame); 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "aho-corasick" 7 | version = "0.7.18" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" 10 | dependencies = [ 11 | "memchr", 12 | ] 13 | 14 | [[package]] 15 | name = "anyhow" 16 | version = "1.0.56" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" 19 | 20 | [[package]] 21 | name = "bare-metal" 22 | version = "1.0.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" 25 | 26 | [[package]] 27 | name = "cfg-if" 28 | version = "1.0.0" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 31 | 32 | [[package]] 33 | name = "core-isa-parser" 34 | version = "0.2.0" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "23ec98e54b735872e54b2335c2e5a5c7fa7d9c3bfd45500f75280f84089a0083" 37 | dependencies = [ 38 | "anyhow", 39 | "enum-as-inner", 40 | "regex", 41 | "strum", 42 | "strum_macros", 43 | ] 44 | 45 | [[package]] 46 | name = "darling" 47 | version = "0.10.2" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" 50 | dependencies = [ 51 | "darling_core", 52 | "darling_macro", 53 | ] 54 | 55 | [[package]] 56 | name = "darling_core" 57 | version = "0.10.2" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" 60 | dependencies = [ 61 | "fnv", 62 | "ident_case", 63 | "proc-macro2", 64 | "quote", 65 | "strsim", 66 | "syn", 67 | ] 68 | 69 | [[package]] 70 | name = "darling_macro" 71 | version = "0.10.2" 72 | source = "registry+https://github.com/rust-lang/crates.io-index" 73 | checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" 74 | dependencies = [ 75 | "darling_core", 76 | "quote", 77 | "syn", 78 | ] 79 | 80 | [[package]] 81 | name = "embedded-hal" 82 | version = "0.2.7" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" 85 | dependencies = [ 86 | "nb 0.1.3", 87 | "void", 88 | ] 89 | 90 | [[package]] 91 | name = "enum-as-inner" 92 | version = "0.4.0" 93 | source = "registry+https://github.com/rust-lang/crates.io-index" 94 | checksum = "21cdad81446a7f7dc43f6a77409efeb9733d2fa65553efef6018ef257c959b73" 95 | dependencies = [ 96 | "heck", 97 | "proc-macro2", 98 | "quote", 99 | "syn", 100 | ] 101 | 102 | [[package]] 103 | name = "esp-hal-common" 104 | version = "0.1.0" 105 | source = "git+https://github.com/esp-rs/esp-hal#13ae45b4b93515af3faa75f4405ddd96c9a0e0cc" 106 | dependencies = [ 107 | "cfg-if", 108 | "embedded-hal", 109 | "esp-hal-procmacros", 110 | "esp32", 111 | "nb 1.0.0", 112 | "paste", 113 | "void", 114 | "xtensa-lx", 115 | "xtensa-lx-rt", 116 | ] 117 | 118 | [[package]] 119 | name = "esp-hal-procmacros" 120 | version = "0.1.0" 121 | source = "git+https://github.com/esp-rs/esp-hal#13ae45b4b93515af3faa75f4405ddd96c9a0e0cc" 122 | dependencies = [ 123 | "darling", 124 | "proc-macro-error", 125 | "proc-macro2", 126 | "quote", 127 | "syn", 128 | ] 129 | 130 | [[package]] 131 | name = "esp32" 132 | version = "0.11.0" 133 | source = "git+https://github.com/esp-rs/esp-pacs.git?branch=with_source#3b6301bf6f335d1eb95261b37c0980e56e395911" 134 | dependencies = [ 135 | "bare-metal", 136 | "vcell", 137 | "xtensa-lx", 138 | "xtensa-lx-rt", 139 | ] 140 | 141 | [[package]] 142 | name = "esp32-hal" 143 | version = "0.1.0" 144 | source = "git+https://github.com/esp-rs/esp-hal#13ae45b4b93515af3faa75f4405ddd96c9a0e0cc" 145 | dependencies = [ 146 | "bare-metal", 147 | "embedded-hal", 148 | "esp-hal-common", 149 | "nb 1.0.0", 150 | "void", 151 | "xtensa-lx", 152 | "xtensa-lx-rt", 153 | ] 154 | 155 | [[package]] 156 | name = "esp32-preemt-experiment" 157 | version = "0.1.0" 158 | dependencies = [ 159 | "esp32-hal", 160 | "xtensa-lx", 161 | "xtensa-lx-rt", 162 | ] 163 | 164 | [[package]] 165 | name = "fnv" 166 | version = "1.0.7" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 169 | 170 | [[package]] 171 | name = "heck" 172 | version = "0.4.0" 173 | source = "registry+https://github.com/rust-lang/crates.io-index" 174 | checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" 175 | 176 | [[package]] 177 | name = "ident_case" 178 | version = "1.0.1" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 181 | 182 | [[package]] 183 | name = "lock_api" 184 | version = "0.4.6" 185 | source = "registry+https://github.com/rust-lang/crates.io-index" 186 | checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" 187 | dependencies = [ 188 | "scopeguard", 189 | ] 190 | 191 | [[package]] 192 | name = "memchr" 193 | version = "2.4.1" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" 196 | 197 | [[package]] 198 | name = "minijinja" 199 | version = "0.15.0" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "359c4820413be7706e93999171652e140578384f85faac14cb22d350bd0fbabf" 202 | dependencies = [ 203 | "serde", 204 | ] 205 | 206 | [[package]] 207 | name = "mutex-trait" 208 | version = "0.2.0" 209 | source = "registry+https://github.com/rust-lang/crates.io-index" 210 | checksum = "b4bb1638d419e12f8b1c43d9e639abd0d1424285bdea2f76aa231e233c63cd3a" 211 | 212 | [[package]] 213 | name = "nb" 214 | version = "0.1.3" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" 217 | dependencies = [ 218 | "nb 1.0.0", 219 | ] 220 | 221 | [[package]] 222 | name = "nb" 223 | version = "1.0.0" 224 | source = "registry+https://github.com/rust-lang/crates.io-index" 225 | checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" 226 | 227 | [[package]] 228 | name = "paste" 229 | version = "1.0.7" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" 232 | 233 | [[package]] 234 | name = "proc-macro-error" 235 | version = "1.0.4" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 238 | dependencies = [ 239 | "proc-macro-error-attr", 240 | "proc-macro2", 241 | "quote", 242 | "syn", 243 | "version_check", 244 | ] 245 | 246 | [[package]] 247 | name = "proc-macro-error-attr" 248 | version = "1.0.4" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 251 | dependencies = [ 252 | "proc-macro2", 253 | "quote", 254 | "version_check", 255 | ] 256 | 257 | [[package]] 258 | name = "proc-macro2" 259 | version = "1.0.36" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" 262 | dependencies = [ 263 | "unicode-xid", 264 | ] 265 | 266 | [[package]] 267 | name = "quote" 268 | version = "1.0.17" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" 271 | dependencies = [ 272 | "proc-macro2", 273 | ] 274 | 275 | [[package]] 276 | name = "r0" 277 | version = "1.0.0" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "bd7a31eed1591dcbc95d92ad7161908e72f4677f8fabf2a32ca49b4237cbf211" 280 | 281 | [[package]] 282 | name = "regex" 283 | version = "1.5.5" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" 286 | dependencies = [ 287 | "aho-corasick", 288 | "memchr", 289 | "regex-syntax", 290 | ] 291 | 292 | [[package]] 293 | name = "regex-syntax" 294 | version = "0.6.25" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" 297 | 298 | [[package]] 299 | name = "rustversion" 300 | version = "1.0.6" 301 | source = "registry+https://github.com/rust-lang/crates.io-index" 302 | checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" 303 | 304 | [[package]] 305 | name = "scopeguard" 306 | version = "1.1.0" 307 | source = "registry+https://github.com/rust-lang/crates.io-index" 308 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 309 | 310 | [[package]] 311 | name = "serde" 312 | version = "1.0.136" 313 | source = "registry+https://github.com/rust-lang/crates.io-index" 314 | checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" 315 | 316 | [[package]] 317 | name = "spin" 318 | version = "0.9.2" 319 | source = "registry+https://github.com/rust-lang/crates.io-index" 320 | checksum = "511254be0c5bcf062b019a6c89c01a664aa359ded62f78aa72c6fc137c0590e5" 321 | dependencies = [ 322 | "lock_api", 323 | ] 324 | 325 | [[package]] 326 | name = "strsim" 327 | version = "0.9.3" 328 | source = "registry+https://github.com/rust-lang/crates.io-index" 329 | checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" 330 | 331 | [[package]] 332 | name = "strum" 333 | version = "0.24.0" 334 | source = "registry+https://github.com/rust-lang/crates.io-index" 335 | checksum = "e96acfc1b70604b8b2f1ffa4c57e59176c7dbb05d556c71ecd2f5498a1dee7f8" 336 | 337 | [[package]] 338 | name = "strum_macros" 339 | version = "0.24.0" 340 | source = "registry+https://github.com/rust-lang/crates.io-index" 341 | checksum = "6878079b17446e4d3eba6192bb0a2950d5b14f0ed8424b852310e5a94345d0ef" 342 | dependencies = [ 343 | "heck", 344 | "proc-macro2", 345 | "quote", 346 | "rustversion", 347 | "syn", 348 | ] 349 | 350 | [[package]] 351 | name = "syn" 352 | version = "1.0.90" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | checksum = "704df27628939572cd88d33f171cd6f896f4eaca85252c6e0a72d8d8287ee86f" 355 | dependencies = [ 356 | "proc-macro2", 357 | "quote", 358 | "unicode-xid", 359 | ] 360 | 361 | [[package]] 362 | name = "unicode-xid" 363 | version = "0.2.2" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 366 | 367 | [[package]] 368 | name = "vcell" 369 | version = "0.1.3" 370 | source = "registry+https://github.com/rust-lang/crates.io-index" 371 | checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" 372 | 373 | [[package]] 374 | name = "version_check" 375 | version = "0.9.4" 376 | source = "registry+https://github.com/rust-lang/crates.io-index" 377 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 378 | 379 | [[package]] 380 | name = "void" 381 | version = "1.0.2" 382 | source = "registry+https://github.com/rust-lang/crates.io-index" 383 | checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 384 | 385 | [[package]] 386 | name = "xtensa-lx" 387 | version = "0.6.0" 388 | source = "registry+https://github.com/rust-lang/crates.io-index" 389 | checksum = "91da79fb042151f06f4d1a62aff2981c4bba9f295fa4b0fb41185a97575f5385" 390 | dependencies = [ 391 | "bare-metal", 392 | "mutex-trait", 393 | "r0", 394 | "spin", 395 | ] 396 | 397 | [[package]] 398 | name = "xtensa-lx-rt" 399 | version = "0.10.0" 400 | source = "registry+https://github.com/rust-lang/crates.io-index" 401 | checksum = "5f39561918161f5124f3c54ddec73a798dca8358d5e0e5a07788c114cc1ab1c4" 402 | dependencies = [ 403 | "bare-metal", 404 | "core-isa-parser", 405 | "minijinja", 406 | "r0", 407 | "xtensa-lx-rt-proc-macros", 408 | ] 409 | 410 | [[package]] 411 | name = "xtensa-lx-rt-proc-macros" 412 | version = "0.1.0" 413 | source = "registry+https://github.com/rust-lang/crates.io-index" 414 | checksum = "21a8200930e2dbd515c231f7a46033bd6dfe1497a8e9a539878f0de8f0cd730b" 415 | dependencies = [ 416 | "proc-macro2", 417 | "quote", 418 | "syn", 419 | ] 420 | --------------------------------------------------------------------------------