diff --git a/boards/microbit-v2/Kconfig b/boards/microbit-v2/Kconfig index 5b6d68fe28d0..44eacaf949f5 100644 --- a/boards/microbit-v2/Kconfig +++ b/boards/microbit-v2/Kconfig @@ -19,6 +19,7 @@ config BOARD_MICROBIT_V2 select HAS_VDD_LC_FILTER_REG1 select HAVE_SAUL_GPIO + select HAVE_LSM303AGR source "$(RIOTBOARD)/common/microbit/Kconfig" source "$(RIOTBOARD)/common/nrf52/Kconfig" diff --git a/boards/microbit-v2/Makefile.dep b/boards/microbit-v2/Makefile.dep index 1af3e2ed3d9b..899b5fa84b2f 100644 --- a/boards/microbit-v2/Makefile.dep +++ b/boards/microbit-v2/Makefile.dep @@ -1,2 +1,6 @@ include $(RIOTBOARD)/common/microbit/Makefile.dep include $(RIOTBOARD)/common/nrf52/Makefile.dep + +ifneq (,$(filter saul_default,$(USEMODULE))) + USEMODULE += lsm303agr +endif diff --git a/boards/microbit-v2/include/lsm303agr-config.rs b/boards/microbit-v2/include/lsm303agr-config.rs new file mode 100644 index 000000000000..e23d8e32c932 --- /dev/null +++ b/boards/microbit-v2/include/lsm303agr-config.rs @@ -0,0 +1 @@ +const I2C_DEVICES: &[u8] = &[0]; diff --git a/doc/doxygen/src/using-rust.md b/doc/doxygen/src/using-rust.md index 8645004bf098..55ad2f27cc6a 100644 --- a/doc/doxygen/src/using-rust.md +++ b/doc/doxygen/src/using-rust.md @@ -79,6 +79,28 @@ The wrappers are [documented together with riot-sys and some of the examples]. [I2CDevice]: https://rustdoc.etonomy.org/riot_wrappers/i2c/struct.I2CDevice.html [corresponding embedded-hal I2C traits]: https://rustdoc.etonomy.org/embedded_hal/blocking/i2c/index.html +Library components in Rust +-------------------------- + +It is possible to use Rust in different modules than the application itself. + +Such modules are usually pseudomodules (although they may be mixed with C in regular modules as well). +They always depend on the `rust_riotmodules` module / crate, +which collects all enabled modules into a single crate by means of optional features. + +If the application is not written in Rust, +that then depends on `rust_riotmodules_standalone`, +which adds a panic handler and serves as a root crate. + +If the application is written in Rust, +`rust_riotmodules` needs to be added as a dependency of the application. +(This helps deduplicate between application and library code, +and also avoids symbol name clashes). +This is done by adding a dependency on the local `rust_riotmodules` crate (which is a no-op when no such modules are enabled), +and placing an `extern crate rust_riotmodules;` statement in the code. +(The latter is needed even after most `extern crate` was abolished in 2018, +because crates depended on but not used otherwise are usually not linked in). + Toolchain {#toolchain} --------- diff --git a/drivers/Kconfig b/drivers/Kconfig index e93c467c7a6b..3efeedec0fe5 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -106,6 +106,7 @@ rsource "lpd8808/Kconfig" rsource "lpsxxx/Kconfig" rsource "lsm6dsl/Kconfig" rsource "lsm303dlhc/Kconfig" +rsource "lsm303agr/Kconfig" rsource "ltc4150/Kconfig" rsource "mag3110/Kconfig" rsource "mhz19/Kconfig" diff --git a/drivers/lsm303agr/Cargo.toml b/drivers/lsm303agr/Cargo.toml new file mode 100644 index 000000000000..e4823f14486c --- /dev/null +++ b/drivers/lsm303agr/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "riot-module-lsm303agr" +version = "0.1.0" +edition = "2021" + +authors = ["Christian Amsüss "] +license = "LGPL-2.1-only" + +# Shipped with RIOT-OS; this has no external API that would make +# sense to consume in any context than from within RIOT +publish = false + +[dependencies] +lsm303agr = "^0.2" +riot-wrappers = "^0.7.17" +# Whatever lsm uses +nb = "*" diff --git a/drivers/lsm303agr/Kconfig b/drivers/lsm303agr/Kconfig new file mode 100644 index 000000000000..089158ac31b9 --- /dev/null +++ b/drivers/lsm303agr/Kconfig @@ -0,0 +1,20 @@ +# Copyright (c) 2022 HAW Hamburg +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. +# + +config MODULE_LSM303AGR + bool + prompt "LSM303AGR 3D accelerometer/magnetometer" if !(MODULE_SAUL_DEFAULT && HAVE_LSM303AGR) + default y if (MODULE_SAUL_DEFAULT && HAVE_LSM303AGR) + depends on HAS_PERIPH_I2C + depends on TEST_KCONFIG + select MODULE_RUST_RIOTMODULES + select MODULE_PERIPH_I2C + +config HAVE_LSM303AGR + bool + help + Indicates that a lsm303agr sensor is present. diff --git a/drivers/lsm303agr/Makefile.dep b/drivers/lsm303agr/Makefile.dep new file mode 100644 index 000000000000..fb1f1f980b09 --- /dev/null +++ b/drivers/lsm303agr/Makefile.dep @@ -0,0 +1,3 @@ +USEMODULE += rust_riotmodules + +FEATURES_REQUIRED += periph_i2c diff --git a/drivers/lsm303agr/Makefile.include b/drivers/lsm303agr/Makefile.include new file mode 100644 index 000000000000..83d4041ec1ff --- /dev/null +++ b/drivers/lsm303agr/Makefile.include @@ -0,0 +1 @@ +PSEUDOMODULES += lsm303agr diff --git a/drivers/lsm303agr/doc.txt b/drivers/lsm303agr/doc.txt new file mode 100644 index 000000000000..b007c3b8fc6c --- /dev/null +++ b/drivers/lsm303agr/doc.txt @@ -0,0 +1,47 @@ +/** + +@defgroup drivers_lsm303agr LSM303AGR 3D accelerometer/magnetometer +@ingroup drivers_sensors +@ingroup drivers_saul +@brief Device driver for the LSM303AGR 3D accelerometer/magnetometer + +This driver is written in Rust, +and based on the externally maintained [lsm303agr] crate. + +This means that: + +- it is only available on platforms supported by Rust, +- it needs Rust installed on the build machine as described in @ref using-rust, and +- it downloads additional Rust code from crates.io (in versions pinned by RIOT) when first used. + +[lsm303agr]: https://crates.io/crates/lsm303agr + +## Usage + +When configured on a board, the devices are initialized at a fixed data acquisition rate and the chip's default range of +-2g. +Data values are obtained on demand +whenever queried through @ref drivers_saul. + +For each device, two SAUL entries are registered labelled "LSM303AGR accelerometer" and "LSM303AGR magnetometer", +which produces 3-axis values in units of g and Tesla, respectively. +Accelerometer values are always scaled to milli-g (they come that way and don't exceed the i16 range of SAUL phydats); +magnetometer readings are dynamically downscaled from their original i32 Nanotesla readings to fit in a phydat. + +The driver is configured for a board by placing an `lsm303agr-config.rs` file +in the board's include directory, which lists the I2C device(s) on which an accelerometer should be found: + +``` +const I2C_DEVICES: &[u8] = &[0]; +``` + +## Limitations + +- Advanced features of the sensor + (adjusting acquisition rate or resolution, free-fall detection, interrupts etc.) + are not exposed. + +- The driver accepts some memory overhead (roughly, two mutexes) to avoid unsafe code and enhance readability. + The unsafe code would be sound based on the assertion that the initialization code is only called once + (and in particular is not reentrant). + +*/ diff --git a/drivers/lsm303agr/src/lib.rs b/drivers/lsm303agr/src/lib.rs new file mode 100644 index 000000000000..5445927ee744 --- /dev/null +++ b/drivers/lsm303agr/src/lib.rs @@ -0,0 +1,123 @@ +#![no_std] + +use lsm303agr::{interface, mode, Lsm303agr, AccelOutputDataRate::Hz50}; + +use riot_wrappers::{saul, println, i2c, cstr::cstr, mutex::Mutex}; +use saul::{Phydat, registration}; + +// FIXME: Is this the way we want to go? It's mimicking the C way, but we could just as well take +// the board config from some YAML. +include!(concat!(env!("BOARDDIR"), "/include/lsm303agr-config.rs")); + +const NDEVICES: usize = I2C_DEVICES.len(); + +static DRIVER: registration::Driver = registration::Driver::new(); +static DRIVER_MAG: registration::Driver = registration::Driver::new(); + +// These two being in mutexes is somewhat unnecessary (the mutexes are locked at startup and then +// never unlocked). The alternative is to unsafely access them (asserting that auto_init_lsm303agr +// / init will only ever be called once), or hiding that assertion at some preprocessor level (like +// cortex-m-rt's main does). +// +// Doing it at runtime comes at the cost of two global mutexes in memory, and some more startup +// calls. +// +// Using an Option (with .insert) rather than MaybeUninit (with .write) is another step that +// sacrifices minimal resources (could be none at all, didn't check) for readability. + +// This can't go into ROM because it has a .next pointer that is altered at runtime when some other +// device is registered. (In an alternative implementation where all SAUL registries are managed by +// XFA, this would be possible; finding the point in time when they are ready to be used would be +// tricky, though.). +static REG: Mutex<[Option>; NDEVICES]> = Mutex::new([None; NDEVICES]); +static REG_MAG: Mutex<[Option>; NDEVICES]> = Mutex::new([None; NDEVICES]); +// This can't go into ROM because it contains an inner Mutex (and possibly state data from the +// Lsm303agr instance, didn't bother to check) +static LSM: Mutex<[Option; NDEVICES]> = Mutex::new([None; NDEVICES]); + +#[no_mangle] +pub extern "C" fn auto_init_lsm303agr() { + if let Err(e) = init() { + println!("LSM303AGR init error: {}", e); + } +} + +/// Initialize the configured LSM303AGR device, returning an error string for debug if anything +/// goes wrong +fn init() -> Result<(), &'static str> { + let lsm = LSM + .try_leak() + .expect("LSM303AGR init is only called once"); + + let reg = REG + .try_leak() + .expect("LSM303AGR init is only called once"); + let reg_mag = REG_MAG + .try_leak() + .expect("LSM303AGR init is only called once"); + + for (&i2cdev, (lsm, (reg, reg_mag))) in I2C_DEVICES.iter().zip(lsm.iter_mut().zip(reg.iter_mut().zip(reg_mag.iter_mut()))) { + let mut device = Lsm303agr::new_with_i2c(i2c::I2CDevice::new(i2cdev)); + + device.init() + .map_err(|_| "Device initialization failed")?; + device.set_accel_odr(Hz50) + .map_err(|_| "Device configuration failed")?; + + let lsm = lsm.insert(SaulLSM { device: Mutex::new(device) }); + + let reg = reg.insert(registration::Registration::new(&DRIVER, lsm, Some(cstr!("LSM303AGR accelerometer")))); + let reg_mag = reg_mag.insert(registration::Registration::new(&DRIVER_MAG, lsm, Some(cstr!("LSM303AGR magnetometer")))); + + reg.register_static(); + reg_mag.register_static(); + } + + Ok(()) +} + +struct SaulLSM { + device: Mutex, mode::MagOneShot>>, +} + +impl registration::Drivable for &SaulLSM { + const CLASS: saul::Class = saul::Class::Sensor(Some(saul::SensorClass::Accel)); + + const HAS_READ: bool = true; + + fn read(self) -> Result { + // SAUL doesn't guarantee exclusive access; different threads may read simultaneously. + let mut device = self.device.try_lock() + .ok_or(registration::Error)?; + + let data = device.accel_data() + .map_err(|_| registration::Error)?; + // Data is in the +-2g range by default, which doesn't overflow even the i16 SAUL uses + Ok(Phydat::new(&[data.x as _, data.y as _, data.z as _], Some(saul::Unit::G), -3)) + } +} + +struct MagAspect(&'static SaulLSM); + +impl From<&'static SaulLSM> for MagAspect { + fn from(input: &'static SaulLSM) -> Self { + Self(input) + } +} + +impl registration::Drivable for MagAspect { + const CLASS: saul::Class = saul::Class::Sensor(Some(saul::SensorClass::Mag)); + + const HAS_READ: bool = true; + + fn read(self) -> Result { + // SAUL doesn't guarantee exclusive access; different threads may read simultaneously. + let mut device = self.0.device.try_lock() + .ok_or(registration::Error)?; + + let data = nb::block!(device.mag_data()) + .map_err(|_| registration::Error)?; + // Original data is in nanotesla + return Ok(Phydat::fit(&[data.x, data.y, data.z], Some(saul::Unit::T), -9)) + } +} diff --git a/drivers/saul/init_devs/init.c b/drivers/saul/init_devs/init.c index 572b83005246..6c5116e1105b 100644 --- a/drivers/saul/init_devs/init.c +++ b/drivers/saul/init_devs/init.c @@ -187,6 +187,10 @@ void saul_init_devs(void) extern void auto_init_lpsxxx(void); auto_init_lpsxxx(); } + if (IS_USED(MODULE_LSM303AGR)) { + extern void auto_init_lsm303agr(void); + auto_init_lsm303agr(); + } if (IS_USED(MODULE_LSM303DLHC)) { extern void auto_init_lsm303dlhc(void); auto_init_lsm303dlhc(); diff --git a/examples/rust-gcoap/Cargo.toml b/examples/rust-gcoap/Cargo.toml index 4a0e2a7dcbbe..275eedaffb1d 100644 --- a/examples/rust-gcoap/Cargo.toml +++ b/examples/rust-gcoap/Cargo.toml @@ -14,3 +14,9 @@ riot-wrappers = { version = "^0.7.18", features = [ "set_panic_handler", "panic_ coap-message-demos = { git = "https://gitlab.com/chrysn/coap-message-demos/", default-features = false } coap-handler-implementations = "0.3" riot-coap-handler-demos = { git = "https://gitlab.com/etonomy/riot-module-examples/", features = [ "vfs" ] } + +# While currently this exmple does not use any RIOT modules implemented in +# Rust, that may change; it is best practice for any RIOT application that has +# its own top-level Rust crate to include rust_riotmodules from inside +# RIOTBASE. +rust_riotmodules = { path = "../../sys/rust_riotmodules/" } diff --git a/examples/rust-gcoap/src/lib.rs b/examples/rust-gcoap/src/lib.rs index 4fdcdbba219b..301557978eed 100644 --- a/examples/rust-gcoap/src/lib.rs +++ b/examples/rust-gcoap/src/lib.rs @@ -10,6 +10,8 @@ use riot_wrappers::{gcoap, thread, ztimer, gnrc}; use coap_handler_implementations::{ReportingHandlerBuilder, HandlerBuilder}; +extern crate rust_riotmodules; + riot_main!(main); fn main() { diff --git a/examples/rust-hello-world/Cargo.toml b/examples/rust-hello-world/Cargo.toml index a841f702c230..9dc05fcfd2b1 100644 --- a/examples/rust-hello-world/Cargo.toml +++ b/examples/rust-hello-world/Cargo.toml @@ -11,3 +11,9 @@ crate-type = ["staticlib"] [dependencies] # `default-features = false` can be removed with 0.8, and enables building on stable during the 0.7 series riot-wrappers = { version = "0.7", features = [ "set_panic_handler" ], default-features = false } + +# While currently this exmple does not use any RIOT modules implemented in +# Rust, that may change; it is best practice for any RIOT application that has +# its own top-level Rust crate to include rust_riotmodules from inside +# RIOTBASE. +rust_riotmodules = { path = "../../sys/rust_riotmodules/" } diff --git a/examples/rust-hello-world/src/lib.rs b/examples/rust-hello-world/src/lib.rs index f4ad7a8fc472..3f72a5615a3e 100644 --- a/examples/rust-hello-world/src/lib.rs +++ b/examples/rust-hello-world/src/lib.rs @@ -8,6 +8,8 @@ use riot_wrappers::riot_main; use riot_wrappers::println; +extern crate rust_riotmodules; + riot_main!(main); fn main() { diff --git a/makefiles/arch/riscv.inc.mk b/makefiles/arch/riscv.inc.mk index f5695af2a9e4..58bc5334a71d 100644 --- a/makefiles/arch/riscv.inc.mk +++ b/makefiles/arch/riscv.inc.mk @@ -80,5 +80,3 @@ LINKFLAGS += $(CFLAGS_CPU) $(CFLAGS_LINK) $(CFLAGS_DBG) $(CFLAGS_OPT) -nostartfi # Platform triple as used by Rust RUST_TARGET = riscv32imac-unknown-none-elf -# Workaround for https://github.com/rust-lang/rust-bindgen/issues/1555 -CARGO_EXTRACFLAGS += --target=riscv32 diff --git a/makefiles/cargo-settings.inc.mk b/makefiles/cargo-settings.inc.mk index abc584f16fb2..983c2c1909f2 100644 --- a/makefiles/cargo-settings.inc.mk +++ b/makefiles/cargo-settings.inc.mk @@ -1,13 +1,3 @@ -# Rust's own version of the target triple / quadruple. -# -# This does not have a sane default, and needs to be set in the architecture -# files. -# RUST_TARGET = ... - -# Flags that need to be added to the RIOT_CFLAGS passed to cargo in order to -# make bindgen happy -CARGO_EXTRACFLAGS ?= - # Setting anything other than "debug" or "release" will necessitate additional # -Z unstable-options as of 2021-03 nightlies. CARGO_PROFILE ?= release diff --git a/makefiles/cargo-targets.inc.mk b/makefiles/cargo-targets.inc.mk index 7b6628d8d84a..c12518bf28e9 100644 --- a/makefiles/cargo-targets.inc.mk +++ b/makefiles/cargo-targets.inc.mk @@ -1,6 +1,22 @@ CARGO_COMPILE_COMMANDS = $(BINDIR)/cargo-compile-commands.json CARGO_COMPILE_COMMANDS_FLAGS = --clang +# When an application crate is built, it has to use rust_riotmodules_standalone itself to +# pull in any Rust modules that might be enabled through RIOT's module system. +# (If the application fails to add the rust_riotmodules_standalone dependency, that will +# go unnoticed and work fine if none of the catchall-dispatched modules are +# active -- but if one is enabled, this also serves to ensure the application +# is not silently built without them, as the feature will not be available to +# Cargo). +# +# This list should eventually be autogenerated. +ifneq (,$(filter lsm303agr,$(USEMODULE))) + CARGO_OPTIONS += --features rust_riotmodules/riot-module-lsm303agr +endif +ifneq (,$(filter shell_democommands,$(USEMODULE))) + CARGO_OPTIONS += --features rust_riotmodules/riot-module-shell-democommands +endif + # This is duplicating the compile-commands rule because unlike in the use case # when a $(RIOTBASE)/compile_commands.json is built, we *want* this to be # per-board and per-application. (The large mechanisms are shared anyway). @@ -64,3 +80,6 @@ $(APPLICATION_RUST_MODULE).module: $(CARGO_LIB) FORCE # (should they not exist), and also from re-building everything every time # because the .cargo inside is as ephemeral as the build container. $(shell mkdir -p ~/.cargo/git ~/.cargo/registry) + +FORCE: +.phony: FORCE diff --git a/makefiles/vars.inc.mk b/makefiles/vars.inc.mk index c0eaf7e614e3..980af62f6e2c 100644 --- a/makefiles/vars.inc.mk +++ b/makefiles/vars.inc.mk @@ -132,3 +132,8 @@ export AFL_FLAGS # Additional command-line flags passed to afl durin # LOG_LEVEL # Logging level as integer (NONE: 0, ERROR: 1, WARNING: 2, INFO: 3, DEBUG: 4, default: 3) # KCONFIG_ADD_CONFIG # List of .config files to be merged used by Boards and CPUs. See kconfig.mk # VERBOSE_ASSERT # Set to 1 to print the file and line of a failed assert when assertions blow + +export RUST_TARGET # Rust's own version of the target triple / quadruple. + # + # It is set by the architecture (and thus eventually the CPU), and exported to + # be available when building Rust modules. diff --git a/sys/Kconfig b/sys/Kconfig index 37943f299bc6..2b1e75d678a2 100644 --- a/sys/Kconfig +++ b/sys/Kconfig @@ -79,6 +79,7 @@ rsource "progress_bar/Kconfig" rsource "ps/Kconfig" rsource "random/Kconfig" rsource "rtc_utils/Kconfig" +rsource "rust_riotmodules/Kconfig" rsource "saul_reg/Kconfig" rsource "schedstatistics/Kconfig" rsource "sema/Kconfig" diff --git a/sys/Makefile.dep b/sys/Makefile.dep index edd461937433..1d993381ebf6 100644 --- a/sys/Makefile.dep +++ b/sys/Makefile.dep @@ -338,6 +338,11 @@ ifneq (,$(filter shell_commands,$(USEMODULE))) endif endif +ifneq (,$(filter shell_democommands,$(USEMODULE))) + USEMODULE += rust_riotmodules + USEMODULE += shell +endif + ifneq (,$(filter md5sum sha1sum sha256sum,$(USEMODULE))) USEMODULE += vfs_util USEMODULE += hashes @@ -956,4 +961,8 @@ ifneq (,$(filter fido2_ctap,$(USEMODULE))) USEMODULE += fido2 endif +ifneq (,$(filter rust_riotmodules,$(USEMODULE))) + include $(RIOTBASE)/sys/rust_riotmodules/Makefile.dep +endif + include $(RIOTBASE)/sys/test_utils/Makefile.dep diff --git a/sys/Makefile.include b/sys/Makefile.include index 64e51fae6ea6..4e90267c108b 100644 --- a/sys/Makefile.include +++ b/sys/Makefile.include @@ -159,3 +159,9 @@ endif ifneq (,$(filter shell_lock,$(USEMODULE))) include $(RIOTBASE)/sys/shell_lock/Makefile.include endif + +PSEUDOMODULES += shell_democommands + +ifneq (,$(filter rust_riotmodules,$(USEMODULE))) + include $(RIOTBASE)/sys/rust_riotmodules/Makefile.include +endif diff --git a/sys/rust_riotmodules/Cargo.toml b/sys/rust_riotmodules/Cargo.toml new file mode 100644 index 000000000000..45fe52acbee1 --- /dev/null +++ b/sys/rust_riotmodules/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "rust_riotmodules" +version = "0.1.0" +authors = ["Christian Amsüss "] +edition = "2021" +publish = false + + +[dependencies] +# The list contains all modules available in RIOT, and should eventually be +# autogenerated (or at least automatically checked for consistency). + +riot-module-lsm303agr = { path = "../../drivers/lsm303agr", optional = true } +riot-module-shell-democommands = { path = "../../sys/shell/democommands", optional = true } diff --git a/sys/rust_riotmodules/Kconfig b/sys/rust_riotmodules/Kconfig new file mode 100644 index 000000000000..4a8cf1163854 --- /dev/null +++ b/sys/rust_riotmodules/Kconfig @@ -0,0 +1,23 @@ +# Copyright (c) 2022 HAW Hamburg +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. +# + +menuconfig MODULE_RUST_RIOTMODULES + bool "RUST RIOT modules" + depends on TEST_KCONFIG + depends on HAS_RUST_TARGET + help + This module is used when some module asks to have its code built + through rust_riotmodules. + +config MODULE_RUST_RIOTMODULES_STANDALONE + bool "RUST RIOT modules are standalone" + default y + depends on MODULE_RUST_RIOTMODULES + help + This module is used when rust_riotmodules is selected, and the main + application does not already contain Rust code through which the + rust_riotmodules are built. diff --git a/sys/rust_riotmodules/Makefile.dep b/sys/rust_riotmodules/Makefile.dep new file mode 100644 index 000000000000..d2b9b8a2cf89 --- /dev/null +++ b/sys/rust_riotmodules/Makefile.dep @@ -0,0 +1,10 @@ +# No check for the presence of any of any dependencies (were there none, this +# wouldn't have been pulled in), but only pull in building this in if the +# application does not already provide a crate -- in which case the +# CARGO_OPTIONS added depending on the pseudomodules are enabled in the regular +# cargo-targets. +ifeq (,${APPLICATION_RUST_MODULE}) + USEMODULE += rust_riotmodules_standalone +endif + +FEATURES_REQUIRED += rust_target diff --git a/sys/rust_riotmodules/Makefile.include b/sys/rust_riotmodules/Makefile.include new file mode 100644 index 000000000000..cb1013b0393a --- /dev/null +++ b/sys/rust_riotmodules/Makefile.include @@ -0,0 +1,6 @@ +## This module is used when some module asking to have its code built +# through rust_riotmodules. Whether that happens through actually enabling the +# rust_riotmodules_standalone module or by the application's crate was decided +# in ./Makefile.dep depending on whether a Rust application module is present +# or not. +PSEUDOMODULES += rust_riotmodules diff --git a/sys/rust_riotmodules/src/lib.rs b/sys/rust_riotmodules/src/lib.rs new file mode 100644 index 000000000000..819c4a5391e2 --- /dev/null +++ b/sys/rust_riotmodules/src/lib.rs @@ -0,0 +1,14 @@ +#![no_std] + +// Crates in here are pub used in case they make anything accessible to Rust applications directly; +// they can then access the crates as `rust_riotmodules::lsm303agr` or similar. +// +// (Also, if they were not pub used, they'd need to be extern crate'd). + +// This list should be as auto-generated / -maintained as the one in Cargo.toml + +#[cfg(feature = "riot-module-lsm303agr")] +pub use riot_module_lsm303agr as lsm303agr; + +#[cfg(feature = "riot-module-shell-democommands")] +pub use riot_module_shell_democommands as democommands; diff --git a/sys/rust_riotmodules_standalone/Cargo.lock b/sys/rust_riotmodules_standalone/Cargo.lock new file mode 100644 index 000000000000..439acede226c --- /dev/null +++ b/sys/rust_riotmodules_standalone/Cargo.lock @@ -0,0 +1,759 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "atomic-polyfill" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14bf7b4f565e5e717d7a7a65b2a05c0b8c96e4db636d6f780f03b15108cdd1b" +dependencies = [ + "critical-section", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version 0.2.3", +] + +[[package]] +name = "bare-metal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" + +[[package]] +name = "bindgen" +version = "0.60.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "clap", + "env_logger", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex 1.1.0", + "which", +] + +[[package]] +name = "bit_field" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" + +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "c2rust-asm-casts" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99883a495b2e1ea1c26a2b5fd08ff58490d127b638582cc4a0f7e336ccbea178" + +[[package]] +name = "c2rust-bitfields" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb34f0c0ace43530b2df7f18bc69ee0c4082158aa451ece29602f8c841e73764" +dependencies = [ + "c2rust-bitfields-derive", +] + +[[package]] +name = "c2rust-bitfields-derive" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dd1601a7b828ab874d890e5a895563ca8ad485bdd3d2a359f148c8b72537241" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clang-sys" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a050e2153c5be08febd6734e29298e844fdb0fa21aeddd63b4eb7baa106c69b" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "3.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" +dependencies = [ + "atty", + "bitflags", + "clap_lex", + "indexmap", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap_lex" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "cortex-m" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd20d4ac4aa86f4f75f239d59e542ef67de87cce2c282818dc6e84155d3ea126" +dependencies = [ + "bare-metal 0.2.5", + "bitfield", + "embedded-hal", + "volatile-register", +] + +[[package]] +name = "critical-section" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95da181745b56d4bd339530ec393508910c909c784e8962d15d722bacf0bcbcd" +dependencies = [ + "bare-metal 1.0.0", + "cfg-if", + "cortex-m", + "riscv", +] + +[[package]] +name = "cstr_core" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "644828c273c063ab0d39486ba42a5d1f3a499d35529c759e763a9c6cb8a0fb08" +dependencies = [ + "cty", + "memchr", +] + +[[package]] +name = "cty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "embedded-graphics" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40a69991ceb896bd4810a0cf2bcc46fc94b7860573c71f965d8e5b3d66942fed" +dependencies = [ + "byteorder", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "env_logger" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "heapless" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a08e755adbc0ad283725b29f4a4883deee15336f372d5f61fae59efec40f983" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version 0.4.0", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "indexmap" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" + +[[package]] +name = "libloading" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "lock_api" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "mutex-trait" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4bb1638d419e12f8b1c43d9e639abd0d1424285bdea2f76aa231e233c63cd3a" + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.0.0", +] + +[[package]] +name = "nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" + +[[package]] +name = "nom" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "os_str_bytes" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "proc-macro2" +version = "1.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" + +[[package]] +name = "riot-sys" +version = "0.7.8" +source = "git+https://github.com/RIOT-OS/rust-riot-sys#525b2384a3541d4879a5f3845ee6241243c29a78" +dependencies = [ + "bindgen", + "c2rust-asm-casts", + "c2rust-bitfields", + "cty", + "regex", + "serde", + "serde_json", + "shlex 1.1.0", +] + +[[package]] +name = "riot-wrappers" +version = "0.7.22" +dependencies = [ + "bare-metal 1.0.0", + "cstr_core", + "embedded-graphics", + "embedded-hal", + "heapless", + "hex", + "mutex-trait", + "nb 0.1.3", + "num-traits", + "pin-utils", + "riot-sys", + "shlex 0.1.1", +] + +[[package]] +name = "riscv" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6907ccdd7a31012b70faf2af85cd9e5ba97657cc3987c4f13f8e4d2c2a088aba" +dependencies = [ + "bare-metal 1.0.0", + "bit_field", + "riscv-target", +] + +[[package]] +name = "riscv-target" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88aa938cda42a0cf62a20cfe8d139ff1af20c2e681212b5b34adb5a58333f222" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "rust_riotmodules" +version = "0.1.0" + +[[package]] +name = "rust_riotmodules_standalone" +version = "0.1.0" +dependencies = [ + "riot-wrappers", + "rust_riotmodules", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.10", +] + +[[package]] +name = "ryu" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41d061efea015927ac527063765e73601444cdc344ba855bc7bd44578b25e1c" + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.137" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.137" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "shlex" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" + +[[package]] +name = "shlex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" + +[[package]] +name = "spin" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c530c2b0d0bf8b69304b39fe2001993e267461948b890cd037d8ad4293fa1a0d" +dependencies = [ + "lock_api", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" + +[[package]] +name = "unicode-ident" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" + +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6" +dependencies = [ + "vcell", +] + +[[package]] +name = "which" +version = "4.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" +dependencies = [ + "either", + "lazy_static", + "libc", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/sys/rust_riotmodules_standalone/Cargo.toml b/sys/rust_riotmodules_standalone/Cargo.toml new file mode 100644 index 000000000000..f1a7c50344ac --- /dev/null +++ b/sys/rust_riotmodules_standalone/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "rust_riotmodules_standalone" +version = "0.1.0" +authors = ["Christian Amsüss "] +edition = "2021" +publish = false + +[lib] +crate-type = [ "staticlib" ] + +[profile.release] +lto = true +opt-level = "s" +debug = true +panic = "abort" +codegen-units = 1 + +[dependencies] +riot-wrappers = { version = "0.7", default-features = false, features = [ "set_panic_handler" ] } + +rust_riotmodules = { path = "../rust_riotmodules" } diff --git a/sys/rust_riotmodules_standalone/Makefile b/sys/rust_riotmodules_standalone/Makefile new file mode 100644 index 000000000000..a7a4a980b7a4 --- /dev/null +++ b/sys/rust_riotmodules_standalone/Makefile @@ -0,0 +1,12 @@ +include $(RIOTBASE)/Makefile.base + +include $(RIOTMAKE)/cargo-settings.inc.mk + +APPLICATION_RUST_MODULE = rust_riotmodules_standalone + +# No need to set the Cargo features enabled through the general pseudomodules: +# They're added to the crate in cargo-targets.inc.mk no matter whether it's +# building the rust_riotmodules_standalone top level crate or an application +# crate. + +include $(RIOTMAKE)/cargo-targets.inc.mk diff --git a/sys/rust_riotmodules_standalone/src/lib.rs b/sys/rust_riotmodules_standalone/src/lib.rs new file mode 100644 index 000000000000..3f27a514f235 --- /dev/null +++ b/sys/rust_riotmodules_standalone/src/lib.rs @@ -0,0 +1,9 @@ +#![no_std] + +// As we're pulling all crates in only for their side effects of having symbols (they are required +// on the Rust side like riot_wrappers' panic_handler, and rust_riotmodules does that on its own +// too) all these crates have to be extern-crate'd to be pulled in because they are not used on the +// language level. + +extern crate riot_wrappers; +extern crate rust_riotmodules; diff --git a/sys/shell/democommands/Cargo.toml b/sys/shell/democommands/Cargo.toml new file mode 100644 index 000000000000..91bebce99fd5 --- /dev/null +++ b/sys/shell/democommands/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "riot-module-shell-democommands" +version = "0.1.0" +edition = "2021" + +authors = ["Christian Amsüss "] +license = "LGPL-2.1-only" + +# Shipped with RIOT-OS; this has no external API that would make +# sense to consume in any context than from within RIOT +publish = false + +[dependencies] +riot-wrappers = "^0.7.17" diff --git a/sys/shell/democommands/src/lib.rs b/sys/shell/democommands/src/lib.rs new file mode 100644 index 000000000000..3c8623c2b1ee --- /dev/null +++ b/sys/shell/democommands/src/lib.rs @@ -0,0 +1,17 @@ +#![no_std] + +use riot_wrappers::println; +use core::fmt::Write; + +riot_wrappers::static_command!(static_hello_world, "hello_world", "Print a greeting", hello_world); + +pub fn hello_world<'a>(_w: &mut impl Write, args: impl IntoIterator) { + let mut args = args.into_iter(); + let commandname = args.next().expect("How was this started without an argv[0]?"); + + match args.next() { + Some("--help") => println!("Usage: {commandname}"), + None => println!("Hello RIOT!"), + _ => println!("Invalid argument."), + }; +} diff --git a/tests/rust_libs/Makefile b/tests/rust_libs/Makefile new file mode 100644 index 000000000000..a41e32300765 --- /dev/null +++ b/tests/rust_libs/Makefile @@ -0,0 +1,12 @@ +include ../Makefile.tests_common + +USEMODULE += shell +USEMODULE += shell_democommands + +FEATURES_REQUIRED += rust_target + +# Currently unknown, something related to the LED_PORT definition that doesn't +# pass C2Rust's transpilation +BOARD_BLACKLIST := ek-lm4f120xl + +include $(RIOTBASE)/Makefile.include diff --git a/tests/rust_libs/Makefile.ci b/tests/rust_libs/Makefile.ci new file mode 100644 index 000000000000..84248e69c910 --- /dev/null +++ b/tests/rust_libs/Makefile.ci @@ -0,0 +1,10 @@ +BOARD_INSUFFICIENT_MEMORY := \ + nucleo-f031k6 \ + nucleo-f042k6 \ + nucleo-l011k4 \ + nucleo-l031k6 \ + samd10-xmini \ + stk3200 \ + stm32f030f4-demo \ + stm32g0316-disco \ + # diff --git a/tests/rust_libs/main.c b/tests/rust_libs/main.c new file mode 120000 index 000000000000..c541a5892ab9 --- /dev/null +++ b/tests/rust_libs/main.c @@ -0,0 +1 @@ +../shell/main.c \ No newline at end of file diff --git a/tests/rust_libs/tests/01-run.py b/tests/rust_libs/tests/01-run.py new file mode 100755 index 000000000000..e4994164572b --- /dev/null +++ b/tests/rust_libs/tests/01-run.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2017 Alexandre Abadie +# 2022 Christian Amsüss +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. + +import sys +from testrunner import run + + +EXPECTED_HELP = ( + 'Command Description', + '---------------------------------------', + 'bufsize Get the shell\'s buffer size', + 'start_test starts a test', + 'end_test ends a test', + 'echo prints the input command', + 'empty print nothing on command', + 'hello_world Print a greeting', + 'xfa_test1 xfa test command 1', + 'xfa_test2 xfa test command 2', +) + +PROMPT = '> ' + +CMDS = ( + ('start_test', '[TEST_START]'), + + # test default commands + ('help', EXPECTED_HELP), + + ('end_test', '[TEST_END]'), +) + +CMDS_REGEX = {'ps.rs'} + + +def check_cmd(child, cmd, expected): + regex = cmd in CMDS_REGEX + child.expect(PROMPT) + child.sendline(cmd) + for line in expected: + if regex: + child.expect(line) + else: + child.expect_exact(line) + + +def testfunc(child): + # loop other defined commands and expected output + for cmd, expected in CMDS: + check_cmd(child, cmd, expected) + + +if __name__ == "__main__": + sys.exit(run(testfunc)) diff --git a/tests/rust_minimal/Cargo.toml b/tests/rust_minimal/Cargo.toml index 128a03eb9f48..c6b2f5f54606 100644 --- a/tests/rust_minimal/Cargo.toml +++ b/tests/rust_minimal/Cargo.toml @@ -17,3 +17,8 @@ panic = "abort" [dependencies] # `default-features = false` can be removed with 0.8, and enables building on stable during the 0.7 series riot-wrappers = { version = "0.7", features = [ "set_panic_handler" ], default-features = false } + +# While currently this test does not use any RIOT modules implemented in Rust, +# that may change; it is best practice for any RIOT application that has its +# own top-level Rust crate to include rust_riotmodules from inside RIOTBASE. +rust_riotmodules = { path = "../../sys/rust_riotmodules/" } diff --git a/tests/rust_minimal/src/lib.rs b/tests/rust_minimal/src/lib.rs index 358a332ab27e..6ba145d044b9 100644 --- a/tests/rust_minimal/src/lib.rs +++ b/tests/rust_minimal/src/lib.rs @@ -8,6 +8,8 @@ use riot_wrappers::riot_main; use riot_wrappers::println; +extern crate rust_riotmodules; + riot_main!(main); fn main() {