diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..2dbabf9 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,7 @@ +[target.'cfg(all(target_arch = "riscv32", target_os = "none"))'] +rustflags = [ + "--cfg", "portable_atomic_target_feature=\"zaamo\"", +] + +[build] +target = "riscv32imc-unknown-none-elf" diff --git a/.github/workflows/e310x-hal.yaml b/.github/workflows/e310x-hal.yaml index 043e24d..db7ec55 100644 --- a/.github/workflows/e310x-hal.yaml +++ b/.github/workflows/e310x-hal.yaml @@ -13,9 +13,6 @@ jobs: matrix: # All generated code should be running on stable now, MRSV is 1.65.0 toolchain: [ stable, nightly, 1.65.0 ] - target: - - riscv32imc-unknown-none-elf - - riscv32imac-unknown-none-elf # TODO e310x is not a purely IMAC core include: # Nightly is only for reference and allowed to fail - toolchain: nightly @@ -27,11 +24,11 @@ jobs: - name: Update Rust toolchain run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} - name: Install Rust target - run: rustup target install ${{ matrix.target }} + run: rustup target install riscv32imc-unknown-none-elf - name: Build (no features) - run: cargo build --package e310x-hal --target ${{ matrix.target }} + run: cargo build --package e310x-hal --target riscv32imc-unknown-none-elf - name: Build (all features) - run: cargo build --package e310x-hal --target ${{ matrix.target }} --all-features + run: cargo build --package e310x-hal --target riscv32imc-unknown-none-elf --all-features # On MacOS and Ubuntu, we at least make sure that the crate builds and links. # On Windows, linking fails when the rt feature is enabled. @@ -44,6 +41,8 @@ jobs: - uses: actions/checkout@v4 - name: Update Rust toolchain run: rustup update stable && rustup default stable + - name: Rename .cargo/config to .cargo/config.bak to ignore it + run: mv .cargo/config.toml .cargo/config.bak - name: Build (no features) run: cargo test --package e310x-hal - name: Build (all features) diff --git a/.github/workflows/e310x.yaml b/.github/workflows/e310x.yaml index d7da24f..5c110c9 100644 --- a/.github/workflows/e310x.yaml +++ b/.github/workflows/e310x.yaml @@ -44,6 +44,8 @@ jobs: - uses: actions/checkout@v4 - name: Update Rust toolchain run: rustup update stable && rustup default stable + - name: Rename .cargo/config to .cargo/config.bak to ignore it + run: mv .cargo/config.toml .cargo/config.bak - name: Build (no features) run: cargo test --package e310x - name: Build (all features) diff --git a/e310x-hal/CHANGELOG.md b/e310x-hal/CHANGELOG.md index d2e709d..2b6dd98 100644 --- a/e310x-hal/CHANGELOG.md +++ b/e310x-hal/CHANGELOG.md @@ -8,9 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Changed +- Use `portable-atomic` with `zaamo` feature to use native `amo*` operations. +- Official target is now `riscv32imc-unknown-none-elf`, as it does not fully support the A extension. - Update `e310x` dependency and adapt code - Bump MSRV to 1.65.0 (check Cargo.toml) -- Use `portable-atomic` to allow builds on `riscv32imc-unknown-none-elf`` targets when needed. ## [v0.10.0] - 2023-03-28 diff --git a/e310x-hal/Cargo.toml b/e310x-hal/Cargo.toml index 052429d..69b6372 100644 --- a/e310x-hal/Cargo.toml +++ b/e310x-hal/Cargo.toml @@ -15,9 +15,7 @@ embedded-hal = { version = "0.2.6", features = ["unproven"] } nb = "1.0.0" riscv = { version = "0.10.1", features = ["critical-section-single-hart"] } e310x = { path = "../e310x", version = "0.11.0", features = ["rt", "critical-section"] } - -[target.'cfg(not(target_has_atomic = "32"))'.dependencies] -portable-atomic = { version = "1.4", default-features = false, features = ["unsafe-assume-single-core"] } +portable-atomic = { version = "1.9", default-features = false} [features] g002 = ["e310x/g002"] diff --git a/e310x-hal/src/gpio.rs b/e310x-hal/src/gpio.rs index fb6d289..14604b7 100644 --- a/e310x-hal/src/gpio.rs +++ b/e310x-hal/src/gpio.rs @@ -2,9 +2,6 @@ use core::marker::PhantomData; -#[cfg(target_has_atomic = "32")] -use core::sync::atomic::{AtomicU32, Ordering}; -#[cfg(not(target_has_atomic = "32"))] use portable_atomic::{AtomicU32, Ordering}; /// GpioExt trait extends the GPIO0 peripheral. diff --git a/e310x-hal/src/lib.rs b/e310x-hal/src/lib.rs index b0f50b5..40bf01a 100644 --- a/e310x-hal/src/lib.rs +++ b/e310x-hal/src/lib.rs @@ -2,6 +2,42 @@ //! //! This is an implementation of the [`embedded-hal`] traits for the E310x //! family of microcontrollers. +//! +//! # Building an application for the E310x chips +//! +//! The E310x chips implement the [Zaamo](https://github.com/riscv/riscv-zaamo-zalrsc/blob/main/zaamo-zalrsc.adoc) +//! extension for atomic instructions. This means that it *partially* supports the `A` +//! extension for atomic. Specifically, it supports the `amo*` instructions, but not the +//! `lr*` and `sc*` instructions. +//! +//! It is discouraged to use the `riscv32imac-unknown-none-elf` target for E310x chips, as it +//! will potentially generate code that uses the `lr*` and `sc*` instructions, which are not +//! supported by the E310x chips. Thus, it is recommended to use `riscv32imc-unknown-none-elf`. +//! +//! # Working with atomic operations +//! +//! If you are using the `riscv32imc-unknown-none-elf` target, you will notice that +//! `core::sync::atomic` is not available. To work around this, you can use the +//! [`portable-atomic`](https://docs.rs/portable-atomic/1.8.0/portable_atomic/) crate. +//! This crate allows us to use native `amo*` instructions on the E310x chips without requiring +//! the `A` extension. Furthermore, you can emulate the `lr*` and `sc*` instructions if needed. +//! +//! Thus, the recommended way to work with E310x chips is: +//! +//! 1. Compile your code against the `riscv32imc-unknown-none-elf` target. +//! 2. Add the following configuration to your `.cargo/config.toml`: +//! +//! ```toml +//! [target.'cfg(all(target_arch = "riscv32", target_os = "none"))'] +//! rustflags = [ +//! "--cfg", "portable_atomic_target_feature=\"zaamo\"", +//! ] +//! +//! [build] +//! target = "riscv32imc-unknown-none-elf" +//! ``` +//! +//! This will ensure that the `portable-atomic` crate is correctly configured to work with the E310x chips. #![deny(missing_docs)] #![no_std]