Skip to content

Commit caadbbb

Browse files
authored
Separate esp-radio support code (#4175)
1 parent 6baba85 commit caadbbb

File tree

12 files changed

+268
-212
lines changed

12 files changed

+268
-212
lines changed

esp-preempt/Cargo.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ doc-config = { features = ["esp-hal/unstable"] }
1515
check-configs = [
1616
{ features = ["esp-hal/unstable"] },
1717
{ features = ["esp-hal/unstable", "esp-alloc"] },
18+
{ features = ["esp-hal/unstable", "esp-radio"] },
1819
]
1920
clippy-configs = [
2021
{ features = ["esp-hal/unstable", "esp-alloc", "defmt"] },
@@ -40,7 +41,7 @@ document-features = "0.2.11"
4041
esp-alloc = { version = "0.8.0", path = "../esp-alloc", optional = true }
4142
esp-config = { version = "0.5.0", path = "../esp-config" }
4243
esp-sync = { version = "0.0.0", path = "../esp-sync" }
43-
esp-radio-preempt-driver = { version = "0.0.1", path = "../esp-radio-preempt-driver" }
44+
esp-radio-preempt-driver = { version = "0.0.1", path = "../esp-radio-preempt-driver", optional = true }
4445
portable-atomic = { version = "1.11.0", default-features = false }
4546

4647
# Logging interfaces, they are mutually exclusive so they need to be behind separate features.
@@ -55,7 +56,7 @@ esp-metadata-generated = { version = "0.1.0", path = "../esp-metadata-generated"
5556
esp-hal = { version = "1.0.0-rc.0", path = "../esp-hal", features = ["unstable"] }
5657

5758
[features]
58-
default = ["esp-alloc"]
59+
default = ["esp-alloc", "esp-radio"]
5960

6061
## Enable the use of the `esp-alloc` crate for dynamic memory allocation.
6162
##
@@ -64,6 +65,9 @@ default = ["esp-alloc"]
6465
## - `pub extern "C" fn free_internal(ptr: *mut u8)`
6566
esp-alloc = ["dep:esp-alloc"]
6667

68+
## Enables esp-radio support.
69+
esp-radio = ["dep:esp-radio-preempt-driver"]
70+
6771
#! ### Chip selection
6872
#! One of the following features must be enabled to select the target chip:
6973

esp-preempt/src/esp_radio/mod.rs

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
//! esp-radio support
2+
3+
use core::{ffi::c_void, ptr::NonNull};
4+
5+
use allocator_api2::boxed::Box;
6+
use esp_hal::{
7+
system::Cpu,
8+
time::{Duration, Instant},
9+
};
10+
use esp_radio_preempt_driver::{
11+
register_semaphore_implementation,
12+
semaphore::{SemaphoreImplementation, SemaphoreKind, SemaphorePtr},
13+
};
14+
15+
use crate::{
16+
SCHEDULER,
17+
run_queue::MaxPriority,
18+
scheduler::Scheduler,
19+
semaphore::Semaphore,
20+
task::{self, Task},
21+
};
22+
23+
mod queue;
24+
mod timer_queue;
25+
26+
impl esp_radio_preempt_driver::Scheduler for Scheduler {
27+
fn initialized(&self) -> bool {
28+
self.with(|scheduler| {
29+
if scheduler.time_driver.is_none() {
30+
warn!("Trying to initialize esp-radio before starting esp-preempt");
31+
return false;
32+
}
33+
34+
let current_cpu = Cpu::current() as usize;
35+
if !scheduler.per_cpu[current_cpu].initialized {
36+
warn!(
37+
"Trying to initialize esp-radio on {:?} but esp-preempt is not running on this core",
38+
current_cpu
39+
);
40+
return false;
41+
}
42+
43+
true
44+
})
45+
}
46+
47+
fn yield_task(&self) {
48+
task::yield_task();
49+
}
50+
51+
fn yield_task_from_isr(&self) {
52+
task::yield_task();
53+
}
54+
55+
fn max_task_priority(&self) -> u32 {
56+
MaxPriority::MAX_PRIORITY as u32
57+
}
58+
59+
fn task_create(
60+
&self,
61+
name: &str,
62+
task: extern "C" fn(*mut c_void),
63+
param: *mut c_void,
64+
priority: u32,
65+
pin_to_core: Option<u32>,
66+
task_stack_size: usize,
67+
) -> *mut c_void {
68+
self.create_task(
69+
name,
70+
task,
71+
param,
72+
task_stack_size,
73+
priority.min(self.max_task_priority()),
74+
pin_to_core.and_then(|core| match core {
75+
0 => Some(Cpu::ProCpu),
76+
#[cfg(multi_core)]
77+
1 => Some(Cpu::AppCpu),
78+
_ => {
79+
warn!("Invalid core number: {}", core);
80+
None
81+
}
82+
}),
83+
)
84+
.as_ptr()
85+
.cast()
86+
}
87+
88+
fn current_task(&self) -> *mut c_void {
89+
self.current_task().as_ptr().cast()
90+
}
91+
92+
fn schedule_task_deletion(&self, task_handle: *mut c_void) {
93+
task::schedule_task_deletion(task_handle as *mut Task)
94+
}
95+
96+
fn current_task_thread_semaphore(&self) -> SemaphorePtr {
97+
task::with_current_task(|task| {
98+
NonNull::from(
99+
task.thread_semaphore
100+
.get_or_insert_with(|| Semaphore::new_counting(0, 1)),
101+
)
102+
.cast()
103+
})
104+
}
105+
106+
fn usleep(&self, us: u32) {
107+
SCHEDULER.sleep_until(Instant::now() + Duration::from_micros(us as u64));
108+
}
109+
110+
fn now(&self) -> u64 {
111+
// We're using a SingleShotTimer as the time driver, which lets us use the system timer's
112+
// timestamps.
113+
Instant::now().duration_since_epoch().as_micros()
114+
}
115+
}
116+
117+
impl Semaphore {
118+
unsafe fn from_ptr<'a>(ptr: SemaphorePtr) -> &'a Self {
119+
unsafe { ptr.cast::<Self>().as_ref() }
120+
}
121+
}
122+
123+
impl SemaphoreImplementation for Semaphore {
124+
fn create(kind: SemaphoreKind) -> SemaphorePtr {
125+
let sem = Box::new(match kind {
126+
SemaphoreKind::Counting { max, initial } => Semaphore::new_counting(initial, max),
127+
SemaphoreKind::Mutex => Semaphore::new_mutex(false),
128+
SemaphoreKind::RecursiveMutex => Semaphore::new_mutex(true),
129+
});
130+
NonNull::from(Box::leak(sem)).cast()
131+
}
132+
133+
unsafe fn delete(semaphore: SemaphorePtr) {
134+
let sem = unsafe { Box::from_raw(semaphore.cast::<Semaphore>().as_ptr()) };
135+
core::mem::drop(sem);
136+
}
137+
138+
unsafe fn take(semaphore: SemaphorePtr, timeout_us: Option<u32>) -> bool {
139+
let semaphore = unsafe { Semaphore::from_ptr(semaphore) };
140+
141+
semaphore.take(timeout_us)
142+
}
143+
144+
unsafe fn give(semaphore: SemaphorePtr) -> bool {
145+
let semaphore = unsafe { Semaphore::from_ptr(semaphore) };
146+
147+
semaphore.give()
148+
}
149+
150+
unsafe fn current_count(semaphore: SemaphorePtr) -> u32 {
151+
let semaphore = unsafe { Semaphore::from_ptr(semaphore) };
152+
153+
semaphore.current_count()
154+
}
155+
156+
unsafe fn try_take(semaphore: SemaphorePtr) -> bool {
157+
let semaphore = unsafe { Semaphore::from_ptr(semaphore) };
158+
159+
semaphore.try_take()
160+
}
161+
162+
unsafe fn try_give_from_isr(semaphore: SemaphorePtr, _hptw: Option<&mut bool>) -> bool {
163+
unsafe { <Self as SemaphoreImplementation>::give(semaphore) }
164+
}
165+
166+
unsafe fn try_take_from_isr(semaphore: SemaphorePtr, _hptw: Option<&mut bool>) -> bool {
167+
unsafe { <Self as SemaphoreImplementation>::try_take(semaphore) }
168+
}
169+
}
170+
171+
register_semaphore_implementation!(Semaphore);
File renamed without changes.
File renamed without changes.

esp-preempt/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,13 @@ extern crate alloc;
6161
// MUST be the first module
6262
mod fmt;
6363

64-
mod queue;
64+
#[cfg(feature = "esp-radio")]
65+
mod esp_radio;
6566
mod run_queue;
6667
mod scheduler;
67-
mod semaphore;
68+
pub mod semaphore;
6869
mod task;
6970
mod timer;
70-
mod timer_queue;
7171
mod wait_queue;
7272

7373
use core::mem::MaybeUninit;
@@ -87,6 +87,7 @@ use esp_hal::{
8787
time::{Duration, Instant},
8888
};
8989
pub(crate) use scheduler::SCHEDULER;
90+
pub use task::CurrentThreadHandle;
9091

9192
use crate::timer::TimeDriver;
9293

0 commit comments

Comments
 (0)