Skip to main content

esp_idf_hal/
cpu.rs

1#[cfg(any(esp32, esp32s3, esp32p4))]
2use core::arch::asm;
3
4use esp_idf_sys::*;
5
6use enumset::EnumSetType;
7
8/// Returns the number of cores supported by the esp32* chip
9pub const CORES: u32 = SOC_CPU_CORES_NUM;
10
11#[derive(Debug, EnumSetType)]
12#[repr(C)]
13pub enum Core {
14    Core0 = 0, // PRO on dual-core systems, the one and only CPU on single-core systems
15    #[cfg(any(esp32, esp32s3, esp32p4))]
16    Core1 = 1, // APP on dual-core systems
17}
18
19impl Core {
20    #[inline(always)]
21    pub fn is_active(&self) -> bool {
22        *self == core()
23    }
24}
25
26impl From<Core> for i32 {
27    fn from(core: Core) -> Self {
28        core as _
29    }
30}
31
32impl From<i32> for Core {
33    fn from(core: i32) -> Self {
34        match core {
35            0 => Core::Core0,
36            #[cfg(any(esp32, esp32s3, esp32p4))]
37            1 => Core::Core1,
38            _ => panic!(),
39        }
40    }
41}
42
43/// Returns the currently active core ID
44/// On single-core systems, like esp32s2 and esp32c3 this function always returns 0
45///
46/// On dual-core systems like esp32 and esp32s3 this function returns:
47/// 0 - when the active core is the PRO CPU
48/// 1 - when the active core is the APP CPU
49#[inline(always)]
50#[link_section = ".iram1.cpu_core"]
51pub fn core() -> Core {
52    #[cfg(any(
53        esp32c3, esp32s2, esp32c2, esp32h2, esp32h4, esp32c5, esp32c6, esp32c61
54    ))]
55    let core = 0;
56
57    #[allow(unused_assignments)]
58    #[cfg(any(esp32, esp32s3, esp32p4))]
59    let mut core = 0;
60
61    #[cfg(any(esp32, esp32s3))]
62    unsafe {
63        asm!("rsr.prid {0}", "extui {0},{0},13,1", out(reg) core);
64    }
65
66    #[cfg(esp32p4)]
67    unsafe {
68        asm!("csrr {0}, mhartid", out(reg) core);
69    }
70
71    match core {
72        0 => Core::Core0,
73        #[cfg(any(esp32, esp32s3, esp32p4))]
74        1 => Core::Core1,
75        other => panic!("Unknown core: {other}"),
76    }
77}