Skip to content

Commit ca93b20

Browse files
committed
Auto merge of #2310 - ivmarkov:master, r=Amanieu
Support for the ESP-IDF framework (Xtensa and RiscV arch) Dear all, This PR is implementing support for the [ESP-IDF](https://github.com/espressif/esp-idf) newlib-based framework, which is the open source SDK provided by Espressif for their MCU family (esp32, esp32s2, esp32c3 and all other forthcoming ones). Note that this is the second PR on that topic. Approx. an year ago, `@reitermarkus` contributed an [initial set of changes](0dec549#diff-6c07c29bb7b11b27a308055cca03f299266fd8f05af5a65208b64ff715359c89) which are merged already. Note also that this PR has a [sibling PR against Rust's libStd](rust-lang/rust#87666) which enables **full STD support for the Espressif chipsets** (that is, modulo process support as we are obviously talking about non-kernel bare metal platform here). A short overview of the changes: * The original contribution of `@reitermarkus` is renamed from `xtensa.rs` to `espidf.rs` and all branching through this patch is no longer done based on `target_arch = "xtensa"`, but based on `target_os = "espidf"` (this `target_os` value is to be used by the upcoming Rust targets for the ESP-IDF framework). The primary reason for this change is that branching for ESP-IDF based only on the architecture is no longer valid: the newer Espressif chips (esp32c3 and other upcoming ones) are based on the RISCV32IM(A)C architecture, so this patch now supports both Xtensa and RiscV32. Moreover, I would expect that - given the popularity of the riscv ISA - there will be *other* ports of newlib to riscv which will surely have the layout and sizes of the structures etc. different from the ESP-IDF framework. * The `pthread` structures had sizes which did not match what is used in the ESP-IDF. Ditto for the various `*_INITIALIZER` constants, which do not use 0x00, but 0xff sequences there * The BSD socket API on ESP-IDF is prefixed with `lwip_`. Rather than doing heavyweight proxying in Rust libStd, it is best to just address this here with a custom `link_name`, just like it had been done for MacOS and other systems. * Similar to the `l4re` case, the libc crate should NOT issue a link command to the CRT lib for the ESP-IDF, due to the way the SDK is linked * Various other small fixes: primarily - declaration of standard APIs that are available in the ESP-IDF SDK I should also admit that the patch has one little ESP-IDF-specific cheat: * Since the `pthread` support in ESP-IDF is still lacking RW-locks, I've implemented it as a temporary workaround by simply remapping (with `"link_name"`) the `pthread_rwlock_*` symbols to their equivalent `pthread_mutex_*` symbols. While this implementation is suboptimal, it reduces significantly the PR changeset surface of the other PR which is against Rust libStd.
2 parents a1e0f47 + 85210e6 commit ca93b20

File tree

3 files changed

+61
-25
lines changed

3 files changed

+61
-25
lines changed

src/unix/mod.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,8 @@ pub const ATF_PUBL: ::c_int = 0x08;
297297
pub const ATF_USETRAILERS: ::c_int = 0x10;
298298

299299
cfg_if! {
300-
if #[cfg(target_os = "l4re")] {
301-
// required libraries for L4Re are linked externally, ATM
300+
if #[cfg(any(target_os = "l4re", target_os = "espidf"))] {
301+
// required libraries for L4Re and the ESP-IDF framework are linked externally, ATM
302302
} else if #[cfg(feature = "std")] {
303303
// cargo build, don't pull in anything extra as the libstd dep
304304
// already pulls in all libs.
@@ -576,6 +576,7 @@ extern "C" {
576576
)))]
577577
#[cfg_attr(target_os = "netbsd", link_name = "__socket30")]
578578
#[cfg_attr(target_os = "illumos", link_name = "__xnet_socket")]
579+
#[cfg_attr(target_os = "espidf", link_name = "lwip_socket")]
579580
pub fn socket(domain: ::c_int, ty: ::c_int, protocol: ::c_int) -> ::c_int;
580581
#[cfg(not(all(
581582
libc_cfg_target_vendor,
@@ -587,11 +588,13 @@ extern "C" {
587588
link_name = "connect$UNIX2003"
588589
)]
589590
#[cfg_attr(target_os = "illumos", link_name = "__xnet_connect")]
591+
#[cfg_attr(target_os = "espidf", link_name = "lwip_connect")]
590592
pub fn connect(socket: ::c_int, address: *const sockaddr, len: socklen_t) -> ::c_int;
591593
#[cfg_attr(
592594
all(target_os = "macos", target_arch = "x86"),
593595
link_name = "listen$UNIX2003"
594596
)]
597+
#[cfg_attr(target_os = "espidf", link_name = "lwip_listen")]
595598
pub fn listen(socket: ::c_int, backlog: ::c_int) -> ::c_int;
596599
#[cfg(not(all(
597600
libc_cfg_target_vendor,
@@ -602,6 +605,7 @@ extern "C" {
602605
all(target_os = "macos", target_arch = "x86"),
603606
link_name = "accept$UNIX2003"
604607
)]
608+
#[cfg_attr(target_os = "espidf", link_name = "lwip_accept")]
605609
pub fn accept(socket: ::c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> ::c_int;
606610
#[cfg(not(all(
607611
libc_cfg_target_vendor,
@@ -612,6 +616,7 @@ extern "C" {
612616
all(target_os = "macos", target_arch = "x86"),
613617
link_name = "getpeername$UNIX2003"
614618
)]
619+
#[cfg_attr(target_os = "espidf", link_name = "lwip_getpeername")]
615620
pub fn getpeername(
616621
socket: ::c_int,
617622
address: *mut sockaddr,
@@ -626,11 +631,13 @@ extern "C" {
626631
all(target_os = "macos", target_arch = "x86"),
627632
link_name = "getsockname$UNIX2003"
628633
)]
634+
#[cfg_attr(target_os = "espidf", link_name = "lwip_getsockname")]
629635
pub fn getsockname(
630636
socket: ::c_int,
631637
address: *mut sockaddr,
632638
address_len: *mut socklen_t,
633639
) -> ::c_int;
640+
#[cfg_attr(target_os = "espidf", link_name = "lwip_setsockopt")]
634641
pub fn setsockopt(
635642
socket: ::c_int,
636643
level: ::c_int,
@@ -659,6 +666,7 @@ extern "C" {
659666
link_name = "sendto$UNIX2003"
660667
)]
661668
#[cfg_attr(target_os = "illumos", link_name = "__xnet_sendto")]
669+
#[cfg_attr(target_os = "espidf", link_name = "lwip_sendto")]
662670
pub fn sendto(
663671
socket: ::c_int,
664672
buf: *const ::c_void,
@@ -667,6 +675,7 @@ extern "C" {
667675
addr: *const sockaddr,
668676
addrlen: socklen_t,
669677
) -> ::ssize_t;
678+
#[cfg_attr(target_os = "espidf", link_name = "lwip_shutdown")]
670679
pub fn shutdown(socket: ::c_int, how: ::c_int) -> ::c_int;
671680

672681
#[cfg_attr(
@@ -1122,6 +1131,7 @@ extern "C" {
11221131
pub fn pthread_rwlockattr_destroy(attr: *mut pthread_rwlockattr_t) -> ::c_int;
11231132

11241133
#[cfg_attr(target_os = "illumos", link_name = "__xnet_getsockopt")]
1134+
#[cfg_attr(target_os = "espidf", link_name = "lwip_getsockopt")]
11251135
pub fn getsockopt(
11261136
sockfd: ::c_int,
11271137
level: ::c_int,
@@ -1147,6 +1157,7 @@ extern "C" {
11471157
target_vendor = "nintendo"
11481158
)))]
11491159
#[cfg_attr(target_os = "illumos", link_name = "__xnet_getaddrinfo")]
1160+
#[cfg_attr(target_os = "espidf", link_name = "lwip_getaddrinfo")]
11501161
pub fn getaddrinfo(
11511162
node: *const c_char,
11521163
service: *const c_char,
@@ -1158,6 +1169,7 @@ extern "C" {
11581169
target_arch = "powerpc",
11591170
target_vendor = "nintendo"
11601171
)))]
1172+
#[cfg_attr(target_os = "espidf", link_name = "lwip_freeaddrinfo")]
11611173
pub fn freeaddrinfo(res: *mut addrinfo);
11621174
pub fn gai_strerror(errcode: ::c_int) -> *const ::c_char;
11631175
#[cfg_attr(
@@ -1233,11 +1245,13 @@ extern "C" {
12331245
all(target_os = "macos", target_arch = "x86"),
12341246
link_name = "send$UNIX2003"
12351247
)]
1248+
#[cfg_attr(target_os = "espidf", link_name = "lwip_send")]
12361249
pub fn send(socket: ::c_int, buf: *const ::c_void, len: ::size_t, flags: ::c_int) -> ::ssize_t;
12371250
#[cfg_attr(
12381251
all(target_os = "macos", target_arch = "x86"),
12391252
link_name = "recv$UNIX2003"
12401253
)]
1254+
#[cfg_attr(target_os = "espidf", link_name = "lwip_recv")]
12411255
pub fn recv(socket: ::c_int, buf: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::ssize_t;
12421256
#[cfg_attr(
12431257
all(target_os = "macos", target_arch = "x86"),

src/unix/newlib/xtensa/mod.rs renamed to src/unix/newlib/espidf/mod.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,20 @@ pub const MSG_WAITALL: ::c_int = 0x02;
8484
pub const MSG_MORE: ::c_int = 0x10;
8585
pub const MSG_NOSIGNAL: ::c_int = 0x20;
8686

87+
pub const PTHREAD_STACK_MIN: ::size_t = 768;
88+
8789
extern "C" {
90+
pub fn pthread_create(
91+
native: *mut ::pthread_t,
92+
attr: *const ::pthread_attr_t,
93+
f: extern "C" fn(_: *mut ::c_void) -> *mut ::c_void,
94+
value: *mut ::c_void,
95+
) -> ::c_int;
96+
97+
pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t;
98+
99+
#[link_name = "lwip_sendmsg"]
88100
pub fn sendmsg(s: ::c_int, msg: *const ::msghdr, flags: ::c_int) -> ::ssize_t;
101+
#[link_name = "lwip_recvmsg"]
89102
pub fn recvmsg(s: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t;
90-
91-
pub fn writev(s: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::c_int;
92-
pub fn readv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t;
93103
}

src/unix/newlib/mod.rs

+32-20
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,14 @@ s! {
3333
pub ai_protocol: ::c_int,
3434
pub ai_addrlen: socklen_t,
3535

36-
#[cfg(not(all(libc_cfg_target_vendor, target_arch = "powerpc",
37-
target_vendor = "nintendo")))]
38-
#[cfg(target_arch = "xtensa")]
36+
#[cfg(target_os = "espidf")]
3937
pub ai_addr: *mut sockaddr,
4038

4139
pub ai_canonname: *mut ::c_char,
4240

43-
#[cfg(not(all(libc_cfg_target_vendor, target_arch = "powerpc",
44-
target_vendor = "nintendo")))]
45-
#[cfg(not(target_arch = "xtensa"))]
41+
#[cfg(not(any(
42+
target_os = "espidf",
43+
all(libc_cfg_target_vendor, target_arch = "powerpc", target_vendor = "nintendo"))))]
4644
pub ai_addr: *mut sockaddr,
4745

4846
pub ai_next: *mut addrinfo,
@@ -232,23 +230,37 @@ s! {
232230
// unverified constants
233231
align_const! {
234232
pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
235-
size: [0; __SIZEOF_PTHREAD_MUTEX_T],
233+
size: [__PTHREAD_INITIALIZER_BYTE; __SIZEOF_PTHREAD_MUTEX_T],
236234
};
237235
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
238-
size: [0; __SIZEOF_PTHREAD_COND_T],
236+
size: [__PTHREAD_INITIALIZER_BYTE; __SIZEOF_PTHREAD_COND_T],
239237
};
240238
pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
241-
size: [0; __SIZEOF_PTHREAD_RWLOCK_T],
239+
size: [__PTHREAD_INITIALIZER_BYTE; __SIZEOF_PTHREAD_RWLOCK_T],
242240
};
243241
}
244242
pub const NCCS: usize = 32;
245-
pub const __SIZEOF_PTHREAD_ATTR_T: usize = 56;
246-
pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40;
247-
pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4;
248-
pub const __SIZEOF_PTHREAD_COND_T: usize = 48;
249-
pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4;
250-
pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56;
251-
pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8;
243+
cfg_if! {
244+
if #[cfg(target_os = "espidf")] {
245+
const __PTHREAD_INITIALIZER_BYTE: u8 = 0xff;
246+
pub const __SIZEOF_PTHREAD_ATTR_T: usize = 32;
247+
pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 4;
248+
pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 12;
249+
pub const __SIZEOF_PTHREAD_COND_T: usize = 4;
250+
pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 8;
251+
pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 4;
252+
pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 12;
253+
} else {
254+
const __PTHREAD_INITIALIZER_BYTE: u8 = 0;
255+
pub const __SIZEOF_PTHREAD_ATTR_T: usize = 56;
256+
pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40;
257+
pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4;
258+
pub const __SIZEOF_PTHREAD_COND_T: usize = 48;
259+
pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4;
260+
pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56;
261+
pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8;
262+
}
263+
}
252264
pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32;
253265
pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4;
254266
pub const __PTHREAD_MUTEX_HAVE_PREV: usize = 1;
@@ -688,15 +700,15 @@ extern "C" {
688700
}
689701

690702
cfg_if! {
691-
if #[cfg(target_arch = "arm")] {
703+
if #[cfg(target_os = "espidf")] {
704+
mod espidf;
705+
pub use self::espidf::*;
706+
} else if #[cfg(target_arch = "arm")] {
692707
mod arm;
693708
pub use self::arm::*;
694709
} else if #[cfg(target_arch = "aarch64")] {
695710
mod aarch64;
696711
pub use self::aarch64::*;
697-
} else if #[cfg(target_arch = "xtensa")] {
698-
mod xtensa;
699-
pub use self::xtensa::*;
700712
} else if #[cfg(target_arch = "powerpc")] {
701713
mod powerpc;
702714
pub use self::powerpc::*;

0 commit comments

Comments
 (0)