Skip to content

Commit 459eaa6

Browse files
ivmarkovivmarkov
authored and
ivmarkov
committed
STD support for the ESP-IDF framework
1 parent ae90dcf commit 459eaa6

File tree

29 files changed

+581
-47
lines changed

29 files changed

+581
-47
lines changed

Cargo.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -1880,9 +1880,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
18801880

18811881
[[package]]
18821882
name = "libc"
1883-
version = "0.2.98"
1883+
version = "0.2.99"
18841884
source = "registry+https://github.com/rust-lang/crates.io-index"
1885-
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
1885+
checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765"
18861886
dependencies = [
18871887
"rustc-std-workspace-core",
18881888
]

compiler/rustc_target/src/spec/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,7 @@ supported_targets! {
903903

904904
("riscv32i-unknown-none-elf", riscv32i_unknown_none_elf),
905905
("riscv32imc-unknown-none-elf", riscv32imc_unknown_none_elf),
906+
("riscv32imc-esp-espidf", riscv32imc_esp_espidf),
906907
("riscv32imac-unknown-none-elf", riscv32imac_unknown_none_elf),
907908
("riscv32gc-unknown-linux-gnu", riscv32gc_unknown_linux_gnu),
908909
("riscv32gc-unknown-linux-musl", riscv32gc_unknown_linux_musl),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use crate::spec::{LinkerFlavor, PanicStrategy, RelocModel};
2+
use crate::spec::{Target, TargetOptions};
3+
4+
pub fn target() -> Target {
5+
Target {
6+
data_layout: "e-m:e-p:32:32-i64:64-n32-S128".to_string(),
7+
llvm_target: "riscv32".to_string(),
8+
pointer_width: 32,
9+
arch: "riscv32".to_string(),
10+
11+
options: TargetOptions {
12+
families: vec!["unix".to_string()],
13+
os: "espidf".to_string(),
14+
env: "newlib".to_string(),
15+
vendor: "espressif".to_string(),
16+
linker_flavor: LinkerFlavor::Gcc,
17+
linker: Some("riscv32-esp-elf-gcc".to_string()),
18+
cpu: "generic-rv32".to_string(),
19+
20+
// While the RiscV32IMC architecture does not natively support atomics, ESP-IDF does support
21+
// the __atomic* and __sync* GCC builtins, so setting `max_atomic_width` to `Some(32)`
22+
// and `atomic_cas` to `true` will cause the compiler to emit libcalls to these builtins.
23+
//
24+
// Support for atomics is necessary for the Rust STD library, which is supported by the ESP-IDF framework.
25+
max_atomic_width: Some(32),
26+
atomic_cas: true,
27+
28+
features: "+m,+c".to_string(),
29+
executables: true,
30+
panic_strategy: PanicStrategy::Abort,
31+
relocation_model: RelocModel::Static,
32+
emit_debug_gdb_scripts: false,
33+
eh_frame_header: false,
34+
..Default::default()
35+
},
36+
}
37+
}

library/panic_unwind/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ cfg_if::cfg_if! {
4545
} else if #[cfg(any(
4646
all(target_family = "windows", target_env = "gnu"),
4747
target_os = "psp",
48-
target_family = "unix",
48+
all(target_family = "unix", not(target_os = "espidf")),
4949
all(target_vendor = "fortanix", target_env = "sgx"),
5050
))] {
5151
// Rust runtime's startup objects depend on these symbols, so make them public.
@@ -58,6 +58,7 @@ cfg_if::cfg_if! {
5858
// - arch=wasm32
5959
// - os=none ("bare metal" targets)
6060
// - os=uefi
61+
// - os=espidf
6162
// - nvptx64-nvidia-cuda
6263
// - arch=avr
6364
#[path = "dummy.rs"]

library/std/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
1515
panic_unwind = { path = "../panic_unwind", optional = true }
1616
panic_abort = { path = "../panic_abort" }
1717
core = { path = "../core" }
18-
libc = { version = "0.2.98", default-features = false, features = ['rustc-dep-of-std'] }
18+
libc = { version = "0.2.99", default-features = false, features = ['rustc-dep-of-std'] }
1919
compiler_builtins = { version = "0.1.44" }
2020
profiler_builtins = { path = "../profiler_builtins", optional = true }
2121
unwind = { path = "../unwind" }

library/std/build.rs

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ fn main() {
2626
|| target.contains("vxworks")
2727
|| target.contains("wasm32")
2828
|| target.contains("asmjs")
29+
|| target.contains("espidf")
2930
{
3031
// These platforms don't have any special requirements.
3132
} else {

library/std/src/os/espidf/fs.rs

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#![stable(feature = "metadata_ext", since = "1.1.0")]
2+
3+
use crate::fs::Metadata;
4+
use crate::sys_common::AsInner;
5+
6+
#[allow(deprecated)]
7+
use crate::os::espidf::raw;
8+
9+
/// OS-specific extensions to [`fs::Metadata`].
10+
///
11+
/// [`fs::Metadata`]: crate::fs::Metadata
12+
#[stable(feature = "metadata_ext", since = "1.1.0")]
13+
pub trait MetadataExt {
14+
#[stable(feature = "metadata_ext", since = "1.1.0")]
15+
#[rustc_deprecated(
16+
since = "1.8.0",
17+
reason = "deprecated in favor of the accessor \
18+
methods of this trait"
19+
)]
20+
#[allow(deprecated)]
21+
fn as_raw_stat(&self) -> &raw::stat;
22+
23+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
24+
fn st_dev(&self) -> u64;
25+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
26+
fn st_ino(&self) -> u64;
27+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
28+
fn st_mode(&self) -> u32;
29+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
30+
fn st_nlink(&self) -> u64;
31+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
32+
fn st_uid(&self) -> u32;
33+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
34+
fn st_gid(&self) -> u32;
35+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
36+
fn st_rdev(&self) -> u64;
37+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
38+
fn st_size(&self) -> u64;
39+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
40+
fn st_atime(&self) -> i64;
41+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
42+
fn st_atime_nsec(&self) -> i64;
43+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
44+
fn st_mtime(&self) -> i64;
45+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
46+
fn st_mtime_nsec(&self) -> i64;
47+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
48+
fn st_ctime(&self) -> i64;
49+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
50+
fn st_ctime_nsec(&self) -> i64;
51+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
52+
fn st_blksize(&self) -> u64;
53+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
54+
fn st_blocks(&self) -> u64;
55+
#[stable(feature = "metadata_ext2", since = "1.8.0")]
56+
fn st_spare4(&self) -> [u32; 2];
57+
}
58+
59+
#[stable(feature = "metadata_ext", since = "1.1.0")]
60+
impl MetadataExt for Metadata {
61+
#[allow(deprecated)]
62+
fn as_raw_stat(&self) -> &raw::stat {
63+
unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) }
64+
}
65+
fn st_dev(&self) -> u64 {
66+
self.as_inner().as_inner().st_dev as u64
67+
}
68+
fn st_ino(&self) -> u64 {
69+
self.as_inner().as_inner().st_ino as u64
70+
}
71+
fn st_mode(&self) -> u32 {
72+
self.as_inner().as_inner().st_mode as u32
73+
}
74+
fn st_nlink(&self) -> u64 {
75+
self.as_inner().as_inner().st_nlink as u64
76+
}
77+
fn st_uid(&self) -> u32 {
78+
self.as_inner().as_inner().st_uid as u32
79+
}
80+
fn st_gid(&self) -> u32 {
81+
self.as_inner().as_inner().st_gid as u32
82+
}
83+
fn st_rdev(&self) -> u64 {
84+
self.as_inner().as_inner().st_rdev as u64
85+
}
86+
fn st_size(&self) -> u64 {
87+
self.as_inner().as_inner().st_size as u64
88+
}
89+
fn st_atime(&self) -> i64 {
90+
self.as_inner().as_inner().st_atime as i64
91+
}
92+
fn st_atime_nsec(&self) -> i64 {
93+
0
94+
}
95+
fn st_mtime(&self) -> i64 {
96+
self.as_inner().as_inner().st_mtime as i64
97+
}
98+
fn st_mtime_nsec(&self) -> i64 {
99+
0
100+
}
101+
fn st_ctime(&self) -> i64 {
102+
self.as_inner().as_inner().st_ctime as i64
103+
}
104+
fn st_ctime_nsec(&self) -> i64 {
105+
0
106+
}
107+
fn st_blksize(&self) -> u64 {
108+
self.as_inner().as_inner().st_blksize as u64
109+
}
110+
fn st_blocks(&self) -> u64 {
111+
self.as_inner().as_inner().st_blocks as u64
112+
}
113+
fn st_spare4(&self) -> [u32; 2] {
114+
let spare4 = self.as_inner().as_inner().st_spare4;
115+
[spare4[0] as u32, spare4[1] as u32]
116+
}
117+
}

library/std/src/os/espidf/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//! Definitions for the ESP-IDF framework.
2+
3+
#![stable(feature = "raw_ext", since = "1.1.0")]
4+
5+
pub mod fs;
6+
pub mod raw;

library/std/src/os/espidf/raw.rs

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//! Raw type definitions for the ESP-IDF framework.
2+
3+
#![stable(feature = "raw_ext", since = "1.1.0")]
4+
#![rustc_deprecated(
5+
since = "1.8.0",
6+
reason = "these type aliases are no longer supported by \
7+
the standard library, the `libc` crate on \
8+
crates.io should be used instead for the correct \
9+
definitions"
10+
)]
11+
12+
use crate::os::raw::c_long;
13+
use crate::os::unix::raw::{gid_t, uid_t};
14+
15+
#[stable(feature = "pthread_t", since = "1.8.0")]
16+
pub type pthread_t = libc::pthread_t;
17+
18+
#[stable(feature = "raw_ext", since = "1.1.0")]
19+
pub type blkcnt_t = libc::blkcnt_t;
20+
21+
#[stable(feature = "raw_ext", since = "1.1.0")]
22+
pub type blksize_t = libc::blksize_t;
23+
#[stable(feature = "raw_ext", since = "1.1.0")]
24+
pub type dev_t = libc::dev_t;
25+
#[stable(feature = "raw_ext", since = "1.1.0")]
26+
pub type ino_t = libc::ino_t;
27+
#[stable(feature = "raw_ext", since = "1.1.0")]
28+
pub type mode_t = libc::mode_t;
29+
#[stable(feature = "raw_ext", since = "1.1.0")]
30+
pub type nlink_t = libc::nlink_t;
31+
#[stable(feature = "raw_ext", since = "1.1.0")]
32+
pub type off_t = libc::off_t;
33+
34+
#[stable(feature = "raw_ext", since = "1.1.0")]
35+
pub type time_t = libc::time_t;
36+
37+
#[repr(C)]
38+
#[derive(Clone)]
39+
#[stable(feature = "raw_ext", since = "1.1.0")]
40+
pub struct stat {
41+
#[stable(feature = "raw_ext", since = "1.1.0")]
42+
pub st_dev: dev_t,
43+
#[stable(feature = "raw_ext", since = "1.1.0")]
44+
pub st_ino: ino_t,
45+
#[stable(feature = "raw_ext", since = "1.1.0")]
46+
pub st_mode: mode_t,
47+
#[stable(feature = "raw_ext", since = "1.1.0")]
48+
pub st_nlink: nlink_t,
49+
#[stable(feature = "raw_ext", since = "1.1.0")]
50+
pub st_uid: uid_t,
51+
#[stable(feature = "raw_ext", since = "1.1.0")]
52+
pub st_gid: gid_t,
53+
#[stable(feature = "raw_ext", since = "1.1.0")]
54+
pub st_rdev: dev_t,
55+
#[stable(feature = "raw_ext", since = "1.1.0")]
56+
pub st_size: off_t,
57+
#[stable(feature = "raw_ext", since = "1.1.0")]
58+
pub st_atime: time_t,
59+
#[stable(feature = "raw_ext", since = "1.1.0")]
60+
pub st_mtime: time_t,
61+
#[stable(feature = "raw_ext", since = "1.1.0")]
62+
pub st_ctime: time_t,
63+
#[stable(feature = "raw_ext", since = "1.1.0")]
64+
pub st_blksize: blksize_t,
65+
#[stable(feature = "raw_ext", since = "1.1.0")]
66+
pub st_blocks: blkcnt_t,
67+
#[stable(feature = "raw_ext", since = "1.1.0")]
68+
pub st_spare4: [c_long; 2usize],
69+
}

library/std/src/os/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ mod imp {
8080
pub mod dragonfly;
8181
#[cfg(target_os = "emscripten")]
8282
pub mod emscripten;
83+
#[cfg(target_os = "espidf")]
84+
pub mod espidf;
8385
#[cfg(target_os = "freebsd")]
8486
pub mod freebsd;
8587
#[cfg(target_os = "fuchsia")]

library/std/src/os/unix/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ mod platform {
4040
pub use crate::os::dragonfly::*;
4141
#[cfg(target_os = "emscripten")]
4242
pub use crate::os::emscripten::*;
43+
#[cfg(target_os = "espidf")]
44+
pub use crate::os::espidf::*;
4345
#[cfg(target_os = "freebsd")]
4446
pub use crate::os::freebsd::*;
4547
#[cfg(target_os = "fuchsia")]

library/std/src/sys/common/alloc.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ use crate::ptr;
1414
target_arch = "asmjs",
1515
target_arch = "wasm32",
1616
target_arch = "hexagon",
17-
target_arch = "riscv32"
17+
target_arch = "riscv32",
18+
target_arch = "xtensa"
1819
)))]
1920
pub const MIN_ALIGN: usize = 8;
2021
#[cfg(all(any(

library/std/src/sys/unix/alloc.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ cfg_if::cfg_if! {
5757
target_os = "android",
5858
target_os = "illumos",
5959
target_os = "redox",
60-
target_os = "solaris"
60+
target_os = "solaris",
61+
target_os = "espidf"
6162
))] {
6263
#[inline]
6364
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {

library/std/src/sys/unix/args.rs

+12
Original file line numberDiff line numberDiff line change
@@ -246,3 +246,15 @@ mod imp {
246246
Args { iter: res.into_iter() }
247247
}
248248
}
249+
250+
#[cfg(target_os = "espidf")]
251+
mod imp {
252+
use super::Args;
253+
254+
#[inline(always)]
255+
pub unsafe fn init(_argc: isize, _argv: *const *const u8) {}
256+
257+
pub fn args() -> Args {
258+
Args { iter: Vec::new().into_iter() }
259+
}
260+
}

library/std/src/sys/unix/condvar.rs

+24-3
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,23 @@ impl Condvar {
3434
))]
3535
pub unsafe fn init(&mut self) {}
3636

37+
// NOTE: ESP-IDF's PTHREAD_COND_INITIALIZER support is not released yet
38+
// So on that platform, init() should always be called
39+
// Moreover, that platform does not have pthread_condattr_setclock support,
40+
// hence that initialization should be skipped as well
41+
#[cfg(target_os = "espidf")]
42+
pub unsafe fn init(&mut self) {
43+
let r = libc::pthread_cond_init(self.inner.get(), crate::ptr::null());
44+
assert_eq!(r, 0);
45+
}
46+
3747
#[cfg(not(any(
3848
target_os = "macos",
3949
target_os = "ios",
4050
target_os = "l4re",
4151
target_os = "android",
42-
target_os = "redox"
52+
target_os = "redox",
53+
target_os = "espidf"
4354
)))]
4455
pub unsafe fn init(&mut self) {
4556
use crate::mem::MaybeUninit;
@@ -76,7 +87,12 @@ impl Condvar {
7687
// where we configure condition variable to use monotonic clock (instead of
7788
// default system clock). This approach avoids all problems that result
7889
// from changes made to the system time.
79-
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))]
90+
#[cfg(not(any(
91+
target_os = "macos",
92+
target_os = "ios",
93+
target_os = "android",
94+
target_os = "espidf"
95+
)))]
8096
pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
8197
use crate::mem;
8298

@@ -103,7 +119,12 @@ impl Condvar {
103119
// This implementation is modeled after libcxx's condition_variable
104120
// https://github.com/llvm-mirror/libcxx/blob/release_35/src/condition_variable.cpp#L46
105121
// https://github.com/llvm-mirror/libcxx/blob/release_35/include/__mutex_base#L367
106-
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "android"))]
122+
#[cfg(any(
123+
target_os = "macos",
124+
target_os = "ios",
125+
target_os = "android",
126+
target_os = "espidf"
127+
))]
107128
pub unsafe fn wait_timeout(&self, mutex: &Mutex, mut dur: Duration) -> bool {
108129
use crate::ptr;
109130
use crate::time::Instant;

0 commit comments

Comments
 (0)