Skip to content

Commit

Permalink
STD support for the ESP-IDF framework
Browse files Browse the repository at this point in the history
  • Loading branch information
ivmarkov authored and ivmarkov committed Aug 10, 2021
1 parent ae90dcf commit 459eaa6
Show file tree
Hide file tree
Showing 29 changed files with 581 additions and 47 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1880,9 +1880,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"

[[package]]
name = "libc"
version = "0.2.98"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765"
dependencies = [
"rustc-std-workspace-core",
]
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,7 @@ supported_targets! {

("riscv32i-unknown-none-elf", riscv32i_unknown_none_elf),
("riscv32imc-unknown-none-elf", riscv32imc_unknown_none_elf),
("riscv32imc-esp-espidf", riscv32imc_esp_espidf),
("riscv32imac-unknown-none-elf", riscv32imac_unknown_none_elf),
("riscv32gc-unknown-linux-gnu", riscv32gc_unknown_linux_gnu),
("riscv32gc-unknown-linux-musl", riscv32gc_unknown_linux_musl),
Expand Down
37 changes: 37 additions & 0 deletions compiler/rustc_target/src/spec/riscv32imc_esp_espidf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use crate::spec::{LinkerFlavor, PanicStrategy, RelocModel};
use crate::spec::{Target, TargetOptions};

pub fn target() -> Target {
Target {
data_layout: "e-m:e-p:32:32-i64:64-n32-S128".to_string(),
llvm_target: "riscv32".to_string(),
pointer_width: 32,
arch: "riscv32".to_string(),

options: TargetOptions {
families: vec!["unix".to_string()],
os: "espidf".to_string(),
env: "newlib".to_string(),
vendor: "espressif".to_string(),
linker_flavor: LinkerFlavor::Gcc,
linker: Some("riscv32-esp-elf-gcc".to_string()),
cpu: "generic-rv32".to_string(),

// While the RiscV32IMC architecture does not natively support atomics, ESP-IDF does support
// the __atomic* and __sync* GCC builtins, so setting `max_atomic_width` to `Some(32)`
// and `atomic_cas` to `true` will cause the compiler to emit libcalls to these builtins.
//
// Support for atomics is necessary for the Rust STD library, which is supported by the ESP-IDF framework.
max_atomic_width: Some(32),
atomic_cas: true,

features: "+m,+c".to_string(),
executables: true,
panic_strategy: PanicStrategy::Abort,
relocation_model: RelocModel::Static,
emit_debug_gdb_scripts: false,
eh_frame_header: false,
..Default::default()
},
}
}
3 changes: 2 additions & 1 deletion library/panic_unwind/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ cfg_if::cfg_if! {
} else if #[cfg(any(
all(target_family = "windows", target_env = "gnu"),
target_os = "psp",
target_family = "unix",
all(target_family = "unix", not(target_os = "espidf")),
all(target_vendor = "fortanix", target_env = "sgx"),
))] {
// Rust runtime's startup objects depend on these symbols, so make them public.
Expand All @@ -58,6 +58,7 @@ cfg_if::cfg_if! {
// - arch=wasm32
// - os=none ("bare metal" targets)
// - os=uefi
// - os=espidf
// - nvptx64-nvidia-cuda
// - arch=avr
#[path = "dummy.rs"]
Expand Down
2 changes: 1 addition & 1 deletion library/std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" }
core = { path = "../core" }
libc = { version = "0.2.98", default-features = false, features = ['rustc-dep-of-std'] }
libc = { version = "0.2.99", default-features = false, features = ['rustc-dep-of-std'] }
compiler_builtins = { version = "0.1.44" }
profiler_builtins = { path = "../profiler_builtins", optional = true }
unwind = { path = "../unwind" }
Expand Down
1 change: 1 addition & 0 deletions library/std/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ fn main() {
|| target.contains("vxworks")
|| target.contains("wasm32")
|| target.contains("asmjs")
|| target.contains("espidf")
{
// These platforms don't have any special requirements.
} else {
Expand Down
117 changes: 117 additions & 0 deletions library/std/src/os/espidf/fs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#![stable(feature = "metadata_ext", since = "1.1.0")]

use crate::fs::Metadata;
use crate::sys_common::AsInner;

#[allow(deprecated)]
use crate::os::espidf::raw;

/// OS-specific extensions to [`fs::Metadata`].
///
/// [`fs::Metadata`]: crate::fs::Metadata
#[stable(feature = "metadata_ext", since = "1.1.0")]
pub trait MetadataExt {
#[stable(feature = "metadata_ext", since = "1.1.0")]
#[rustc_deprecated(
since = "1.8.0",
reason = "deprecated in favor of the accessor \
methods of this trait"
)]
#[allow(deprecated)]
fn as_raw_stat(&self) -> &raw::stat;

#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_dev(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_ino(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_mode(&self) -> u32;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_nlink(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_uid(&self) -> u32;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_gid(&self) -> u32;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_rdev(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_size(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_atime(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_atime_nsec(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_mtime(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_mtime_nsec(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_ctime(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_ctime_nsec(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_blksize(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_blocks(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_spare4(&self) -> [u32; 2];
}

#[stable(feature = "metadata_ext", since = "1.1.0")]
impl MetadataExt for Metadata {
#[allow(deprecated)]
fn as_raw_stat(&self) -> &raw::stat {
unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) }
}
fn st_dev(&self) -> u64 {
self.as_inner().as_inner().st_dev as u64
}
fn st_ino(&self) -> u64 {
self.as_inner().as_inner().st_ino as u64
}
fn st_mode(&self) -> u32 {
self.as_inner().as_inner().st_mode as u32
}
fn st_nlink(&self) -> u64 {
self.as_inner().as_inner().st_nlink as u64
}
fn st_uid(&self) -> u32 {
self.as_inner().as_inner().st_uid as u32
}
fn st_gid(&self) -> u32 {
self.as_inner().as_inner().st_gid as u32
}
fn st_rdev(&self) -> u64 {
self.as_inner().as_inner().st_rdev as u64
}
fn st_size(&self) -> u64 {
self.as_inner().as_inner().st_size as u64
}
fn st_atime(&self) -> i64 {
self.as_inner().as_inner().st_atime as i64
}
fn st_atime_nsec(&self) -> i64 {
0
}
fn st_mtime(&self) -> i64 {
self.as_inner().as_inner().st_mtime as i64
}
fn st_mtime_nsec(&self) -> i64 {
0
}
fn st_ctime(&self) -> i64 {
self.as_inner().as_inner().st_ctime as i64
}
fn st_ctime_nsec(&self) -> i64 {
0
}
fn st_blksize(&self) -> u64 {
self.as_inner().as_inner().st_blksize as u64
}
fn st_blocks(&self) -> u64 {
self.as_inner().as_inner().st_blocks as u64
}
fn st_spare4(&self) -> [u32; 2] {
let spare4 = self.as_inner().as_inner().st_spare4;
[spare4[0] as u32, spare4[1] as u32]
}
}
6 changes: 6 additions & 0 deletions library/std/src/os/espidf/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//! Definitions for the ESP-IDF framework.

#![stable(feature = "raw_ext", since = "1.1.0")]

pub mod fs;
pub mod raw;
69 changes: 69 additions & 0 deletions library/std/src/os/espidf/raw.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//! Raw type definitions for the ESP-IDF framework.

#![stable(feature = "raw_ext", since = "1.1.0")]
#![rustc_deprecated(
since = "1.8.0",
reason = "these type aliases are no longer supported by \
the standard library, the `libc` crate on \
crates.io should be used instead for the correct \
definitions"
)]

use crate::os::raw::c_long;
use crate::os::unix::raw::{gid_t, uid_t};

#[stable(feature = "pthread_t", since = "1.8.0")]
pub type pthread_t = libc::pthread_t;

#[stable(feature = "raw_ext", since = "1.1.0")]
pub type blkcnt_t = libc::blkcnt_t;

#[stable(feature = "raw_ext", since = "1.1.0")]
pub type blksize_t = libc::blksize_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type dev_t = libc::dev_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type ino_t = libc::ino_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type mode_t = libc::mode_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type nlink_t = libc::nlink_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type off_t = libc::off_t;

#[stable(feature = "raw_ext", since = "1.1.0")]
pub type time_t = libc::time_t;

#[repr(C)]
#[derive(Clone)]
#[stable(feature = "raw_ext", since = "1.1.0")]
pub struct stat {
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_dev: dev_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_ino: ino_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_mode: mode_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_nlink: nlink_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_uid: uid_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_gid: gid_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_rdev: dev_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_size: off_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_atime: time_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_mtime: time_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_ctime: time_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_blksize: blksize_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_blocks: blkcnt_t,
#[stable(feature = "raw_ext", since = "1.1.0")]
pub st_spare4: [c_long; 2usize],
}
2 changes: 2 additions & 0 deletions library/std/src/os/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ mod imp {
pub mod dragonfly;
#[cfg(target_os = "emscripten")]
pub mod emscripten;
#[cfg(target_os = "espidf")]
pub mod espidf;
#[cfg(target_os = "freebsd")]
pub mod freebsd;
#[cfg(target_os = "fuchsia")]
Expand Down
2 changes: 2 additions & 0 deletions library/std/src/os/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ mod platform {
pub use crate::os::dragonfly::*;
#[cfg(target_os = "emscripten")]
pub use crate::os::emscripten::*;
#[cfg(target_os = "espidf")]
pub use crate::os::espidf::*;
#[cfg(target_os = "freebsd")]
pub use crate::os::freebsd::*;
#[cfg(target_os = "fuchsia")]
Expand Down
3 changes: 2 additions & 1 deletion library/std/src/sys/common/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ use crate::ptr;
target_arch = "asmjs",
target_arch = "wasm32",
target_arch = "hexagon",
target_arch = "riscv32"
target_arch = "riscv32",
target_arch = "xtensa"
)))]
pub const MIN_ALIGN: usize = 8;
#[cfg(all(any(
Expand Down
3 changes: 2 additions & 1 deletion library/std/src/sys/unix/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ cfg_if::cfg_if! {
target_os = "android",
target_os = "illumos",
target_os = "redox",
target_os = "solaris"
target_os = "solaris",
target_os = "espidf"
))] {
#[inline]
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
Expand Down
12 changes: 12 additions & 0 deletions library/std/src/sys/unix/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,3 +246,15 @@ mod imp {
Args { iter: res.into_iter() }
}
}

#[cfg(target_os = "espidf")]
mod imp {
use super::Args;

#[inline(always)]
pub unsafe fn init(_argc: isize, _argv: *const *const u8) {}

pub fn args() -> Args {
Args { iter: Vec::new().into_iter() }
}
}
27 changes: 24 additions & 3 deletions library/std/src/sys/unix/condvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,23 @@ impl Condvar {
))]
pub unsafe fn init(&mut self) {}

// NOTE: ESP-IDF's PTHREAD_COND_INITIALIZER support is not released yet
// So on that platform, init() should always be called
// Moreover, that platform does not have pthread_condattr_setclock support,
// hence that initialization should be skipped as well
#[cfg(target_os = "espidf")]
pub unsafe fn init(&mut self) {
let r = libc::pthread_cond_init(self.inner.get(), crate::ptr::null());
assert_eq!(r, 0);
}

#[cfg(not(any(
target_os = "macos",
target_os = "ios",
target_os = "l4re",
target_os = "android",
target_os = "redox"
target_os = "redox",
target_os = "espidf"
)))]
pub unsafe fn init(&mut self) {
use crate::mem::MaybeUninit;
Expand Down Expand Up @@ -76,7 +87,12 @@ impl Condvar {
// where we configure condition variable to use monotonic clock (instead of
// default system clock). This approach avoids all problems that result
// from changes made to the system time.
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))]
#[cfg(not(any(
target_os = "macos",
target_os = "ios",
target_os = "android",
target_os = "espidf"
)))]
pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
use crate::mem;

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

0 comments on commit 459eaa6

Please sign in to comment.