Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check-in all RAL sources #67

Merged
merged 5 commits into from
Jun 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
52 changes: 14 additions & 38 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,20 @@ name: All Checks
on: [push, pull_request]

jobs:
gen-ral:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install virtualenv
uses: actions/setup-python@v1
with:
python-version: 3.7
- name: Install Python dependencies
run: cd imxrt-ral && pip install -U -r requirements.txt
- name: Generate RAL
run: make -C imxrt-ral ci
- name: Ensure RAL is consistent with checked-in code
run: git update-index --refresh && git diff-index --quiet HEAD

build-ral:
runs-on: ubuntu-latest
Expand All @@ -11,25 +25,6 @@ jobs:
feature: ["imxrt1011", "imxrt1015", "imxrt1021", "imxrt1051", "imxrt1052", "imxrt1061", "imxrt1062", "imxrt1064"]
steps:
- uses: actions/checkout@v2
- name: Cache generated code
uses: actions/cache@v1
id: ral-cache
with:
path: imxrt-ral
key: ${{ runner.OS }}-ral-cache-${{ hashFiles('imxrt-ral/imxrtral.py') }}
# These steps only run if we have a RAL cache miss.
- name: install virtualenv
if: steps.ral-cache.outputs.cache-hit != 'true'
uses: actions/setup-python@v1
with:
python-version: 3.7
- name: Install python dependencies
if: steps.ral-cache.outputs.cache-hit != 'true'
run: cd imxrt-ral && pip install -U -r requirements.txt
- name: Generate code
if: steps.ral-cache.outputs.cache-hit != 'true'
run: cd imxrt-ral && make
# Build and test the RAL
- name: Build imxrt-ral for (${{ matrix.feature }}) RAL
run: cd imxrt-ral && cargo build --verbose --features ${{ matrix.feature }}
- name: Run tests (${{ matrix.feature }}) for RAL
Expand All @@ -42,25 +37,6 @@ jobs:
feature: ["imxrt1062"]
steps:
- uses: actions/checkout@v2
- name: Cache generated code
uses: actions/cache@v1
id: ral-cache
with:
path: imxrt-ral
key: ${{ runner.OS }}-ral-cache-${{ hashFiles('imxrt-ral/imxrtral.py') }}
# These steps only run if we have a RAL cache miss
- name: install virtualenv
if: steps.ral-cache.outputs.cache-hit != 'true'
uses: actions/setup-python@v1
with:
python-version: 3.7
- name: Install python dependencies
if: steps.ral-cache.outputs.cache-hit != 'true'
run: cd imxrt-ral && pip install -U -r requirements.txt
- name: Generate code
if: steps.ral-cache.outputs.cache-hit != 'true'
run: cd imxrt-ral && make
# Build and test the HAL
- name: Build imxrt-hal for (${{ matrix.feature }}) HAL
run: cd imxrt-hal && cargo build --verbose --features ${{ matrix.feature }}
- name: Run tests (${{ matrix.feature }}) for HAL
Expand Down
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@ rustup target add thumbv7em-none-eabihf

### RAL

The `imxrt-ral` crate is auto-generated from the checked-in SVD files, available in `imxrt-ral/svd`. Note that the auto-generated RAL source files are not checked into git. They're ignored so that developers are not encouraged to directly modify the Rust source files. If we modified the files directly, the changes might be lost the next time we auto-generate the RAL crate.
The `imxrt-ral` crate is auto-generated from the checked-in SVD files, available in `imxrt-ral/svd`. It's checked into git, and you should always have whatever represents the latest auto-generated RAL. Generally, you should **not** manually change RAL source files; rather, you should describe changes in `imxrtral.py`, the Python script that auto-generates the RAL.

To generate the RAL,

- Install Python 3. You'll need at least Python 3.6.
- Install the Python dependencies needed to generate the RAL: `pip3 install --user svdtools`. Alternatively, use the rules in the RAL's `Makefile` to create a virtual environment with the necessary dependencies: `make venv update-venv && source venv/bin/activate`.
- Run `make` in the `imxrt-ral` directory: `cd imxrt-ral; make; cd ..;`. The auto-generation script might generate warnings; that's OK.
- Run `make` in the `imxrt-ral` directory: `make -C imxrt-ral`. The auto-generation script might generate warnings; that's OK.

If everything went well, you should find that the `imxrt-ral/src` directory is populated with Rust files. The RAL can build by itself: `cd imxrt-ral && cargo check --features imxrt1062 --target thumbv7em-none-eabihf`.
If everything went well, you should find that the `imxrt-ral/src` directory is populated with Rust files. If you made changes in `imxrtral.py`, you should see those changes reflected in the Rust files. The RAL can build by itself: `cd imxrt-ral && cargo check --features imxrt1062 --target thumbv7em-none-eabihf`.

The RAL doesn't change too frequently. But, if you add an SVD patch, you'll need to re-generate the RAL to realize the change. Keep an eye on pull requests that mention a RAL change.
If you add a SVD patch, or if you change something in `imxrtral.py`, you'll need to re-generate the RAL to realize the change.

### HAL

Expand Down
5 changes: 1 addition & 4 deletions imxrt-ral/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,4 @@ cortex_m/*.formatted
svd/*.patched
svd/*.formatted
target
src/**/*.rs
src/**/*.x
Cargo.toml
Cargo.lock
Cargo.lock
48 changes: 48 additions & 0 deletions imxrt-ral/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Generated by imxrtral.py. Do not edit manually.

[package]
name = "imxrt-ral"
authors = ["Tom Burdick <tom.burdick@electromatic.us>", "Ian McIntyre <ianpmcintyre@gmail.com>"]
description = "Register access layer for all NXP i.MX RT microcontrollers"
repository = "https://github.com/imxrt-rs/imxrt-rs"
readme = "README.md"
keywords = ["imxrt", "nxp", "embedded", "no_std"]
categories = ["embedded", "no-std"]
license = "MIT/Apache-2.0"
edition = "2018"

# Change version in imxrtral.py, not in Cargo.toml!
version = "0.3.0"

[package.metadata.docs.rs]
features = ["doc"]
no-default-features = true

[dependencies]
# Change dependency versions in stm32ral.py, not here!
bare-metal = "0.2.5"
external_cortex_m = { package = "cortex-m", version = "0.6.2" }
# TODO use imxrt-rt here in place cortex-m-rt = { version = "0.6.12", optional = true }

[lib]
bench = false
test = false

[features]
rt = []
inline-asm = ["external_cortex_m/inline-asm"]
rtic = []
default = []
nosync = []
doc = []
armv6m = []
armv7em = []
armv7m = []
imxrt1011 = ["armv7em"]
imxrt1015 = ["armv7em"]
imxrt1021 = ["armv7em"]
imxrt1051 = ["armv7em"]
imxrt1052 = ["armv7em"]
imxrt1061 = ["armv7em"]
imxrt1062 = ["armv7em"]
imxrt1064 = ["armv7em"]
7 changes: 5 additions & 2 deletions imxrt-ral/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
SHELL := /usr/bin/env bash
DEVICES ?= imxrt1011 imxrt1015 imxrt1021 imxrt1051 imxrt1052 imxrt1061 imxrt1062 imxrt1064

all: patch crate rustfmt check
all: patch crate rustfmt check

# Things to do in CI
ci: patch crate rustfmt

# All yaml files in devices/ will be used to patch an SVD
DEVICE_YAMLS := $(foreach device, $(DEVICES), \
Expand Down Expand Up @@ -68,7 +71,7 @@ clean-patch:
clean-html:
rm -rf html

clean: clean-patch clean-html
clean: clean-patch clean-html clean-check
rm -rf .deps

# As alternative to `pip install --user svdtools`:
Expand Down
201 changes: 201 additions & 0 deletions imxrt-ral/src/cortex_m/armv6m/cpuid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
#![allow(non_snake_case, non_upper_case_globals)]
#![allow(non_camel_case_types)]
//! CPUID

use crate::RORegister;
#[cfg(not(feature = "nosync"))]
use core::marker::PhantomData;

/// Provides identification information for the processor
pub mod Base {

/// This field defines the implementer
pub mod IMPLEMENTER {
/// Offset (24 bits)
pub const offset: u32 = 24;
/// Mask (7 bits: 0x7f << 24)
pub const mask: u32 = 0x7f << offset;
/// Read-only values (empty)
pub mod R {}
/// Write-only values (empty)
pub mod W {}
/// Read-write values
pub mod RW {

/// 0b1000001: ARM Limited
pub const ARM: u32 = 0b1000001;
}
}

/// Implementation defined
pub mod VARIANT {
/// Offset (20 bits)
pub const offset: u32 = 20;
/// Mask (4 bits: 0b1111 << 20)
pub const mask: u32 = 0b1111 << offset;
/// Read-only values (empty)
pub mod R {}
/// Write-only values (empty)
pub mod W {}
/// Read-write values (empty)
pub mod RW {}
}

/// This field defines the architecture
pub mod ARCHITECTURE {
/// Offset (16 bits)
pub const offset: u32 = 16;
/// Mask (4 bits: 0b1111 << 16)
pub const mask: u32 = 0b1111 << offset;
/// Read-only values (empty)
pub mod R {}
/// Write-only values (empty)
pub mod W {}
/// Read-write values
pub mod RW {

/// 0b1100: ARMv6-M
pub const ARMv6M: u32 = 0b1100;
}
}

/// Implementation defined.
pub mod PARTNO {
/// Offset (4 bits)
pub const offset: u32 = 4;
/// Mask (12 bits: 0xfff << 4)
pub const mask: u32 = 0xfff << offset;
/// Read-only values (empty)
pub mod R {}
/// Write-only values (empty)
pub mod W {}
/// Read-write values (empty)
pub mod RW {}
}

/// Implementation defined.
pub mod REVISION {
/// Offset (0 bits)
pub const offset: u32 = 0;
/// Mask (4 bits: 0b1111 << 0)
pub const mask: u32 = 0b1111 << offset;
/// Read-only values (empty)
pub mod R {}
/// Write-only values (empty)
pub mod W {}
/// Read-write values (empty)
pub mod RW {}
}
}
#[repr(C)]
pub struct RegisterBlock {
/// Provides identification information for the processor
pub Base: RORegister<u32>,
}
pub struct ResetValues {
pub Base: u32,
}
#[cfg(not(feature = "nosync"))]
pub struct Instance {
pub(crate) addr: u32,
pub(crate) _marker: PhantomData<*const RegisterBlock>,
}
#[cfg(not(feature = "nosync"))]
impl ::core::ops::Deref for Instance {
type Target = RegisterBlock;
#[inline(always)]
fn deref(&self) -> &RegisterBlock {
unsafe { &*(self.addr as *const _) }
}
}

unsafe impl Send for Instance {}

/// Access functions for the CPUID peripheral instance
pub mod CPUID {
use super::ResetValues;

#[cfg(not(feature = "nosync"))]
use super::Instance;

#[cfg(not(feature = "nosync"))]
const INSTANCE: Instance = Instance {
addr: 0xe000ed00,
_marker: ::core::marker::PhantomData,
};

/// Reset values for each field in CPUID
pub const reset: ResetValues = ResetValues { Base: 0x00000000 };

#[cfg(not(feature = "nosync"))]
#[allow(renamed_and_removed_lints)]
#[allow(private_no_mangle_statics)]
#[no_mangle]
static mut CPUID_TAKEN: bool = false;

/// Safe access to CPUID
///
/// This function returns `Some(Instance)` if this instance is not
/// currently taken, and `None` if it is. This ensures that if you
/// do get `Some(Instance)`, you are ensured unique access to
/// the peripheral and there cannot be data races (unless other
/// code uses `unsafe`, of course). You can then pass the
/// `Instance` around to other functions as required. When you're
/// done with it, you can call `release(instance)` to return it.
///
/// `Instance` itself dereferences to a `RegisterBlock`, which
/// provides access to the peripheral's registers.
#[cfg(not(feature = "nosync"))]
#[inline]
pub fn take() -> Option<Instance> {
external_cortex_m::interrupt::free(|_| unsafe {
if CPUID_TAKEN {
None
} else {
CPUID_TAKEN = true;
Some(INSTANCE)
}
})
}

/// Release exclusive access to CPUID
///
/// This function allows you to return an `Instance` so that it
/// is available to `take()` again. This function will panic if
/// you return a different `Instance` or if this instance is not
/// already taken.
#[cfg(not(feature = "nosync"))]
#[inline]
pub fn release(inst: Instance) {
external_cortex_m::interrupt::free(|_| unsafe {
if CPUID_TAKEN && inst.addr == INSTANCE.addr {
CPUID_TAKEN = false;
} else {
panic!("Released a peripheral which was not taken");
}
});
}

/// Unsafely steal CPUID
///
/// This function is similar to take() but forcibly takes the
/// Instance, marking it as taken irregardless of its previous
/// state.
#[cfg(not(feature = "nosync"))]
#[inline]
pub unsafe fn steal() -> Instance {
CPUID_TAKEN = true;
INSTANCE
}
}

/// Raw pointer to CPUID
///
/// Dereferencing this is unsafe because you are not ensured unique
/// access to the peripheral, so you may encounter data races with
/// other users of this peripheral. It is up to you to ensure you
/// will not cause data races.
///
/// This constant is provided for ease of use in unsafe code: you can
/// simply call for example `write_reg!(gpio, GPIOA, ODR, 1);`.
pub const CPUID: *const RegisterBlock = 0xe000ed00 as *const _;
Loading