aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml379
-rw-r--r--.github/workflows/docs.yml93
-rw-r--r--.github/workflows/properties/build.properties.json6
-rw-r--r--.github/workflows/properties/docs.properties.json6
-rw-r--r--.github/workflows/properties/publish.properties.json6
-rw-r--r--.github/workflows/publish.yml94
-rw-r--r--.travis.yml1
-rw-r--r--Cargo.toml10
-rw-r--r--book/en/src/by-example/app.md14
-rw-r--r--book/en/src/by-example/resources.md10
-rw-r--r--book/ru/src/by-example/app.md2
-rw-r--r--build.rs5
-rw-r--r--ci/install.sh9
-rw-r--r--ci/script.sh23
-rw-r--r--examples/schedule.rs7
-rw-r--r--examples/t-cfg-resources.rs36
-rw-r--r--macros/src/codegen.rs3
-rw-r--r--macros/src/codegen/init.rs6
-rw-r--r--macros/src/codegen/post_init.rs9
-rw-r--r--macros/src/codegen/resources.rs10
-rw-r--r--src/cyccnt.rs4
21 files changed, 710 insertions, 23 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 00000000..00086ff5
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,379 @@
+name: Build
+on:
+ push:
+ branches:
+ - master
+ - ghatest
+ pull_request:
+ branches:
+ - master
+ - ghatest
+
+env:
+ CARGO_TERM_COLOR: always
+
+jobs:
+ # Run cargo fmt --check, includes macros/
+ style:
+ name: Check Style with cargo fmt
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v1
+
+ - name: Install Rust
+ uses: actions-rs/toolchain@v1
+ with:
+ profile: minimal
+ toolchain: stable
+ override: true
+ components: rustfmt
+
+ - name: cargo fmt --check
+ uses: actions-rs/cargo@v1
+ with:
+ command: fmt
+ args: --all -- --check
+
+ # Compilation check
+ check:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ target:
+ - thumbv7m-none-eabi
+ - thumbv6m-none-eabi
+ - x86_64-unknown-linux-gnu
+ toolchain:
+ - stable
+ - 1.36.0
+ - nightly
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Install Rust ${{ matrix.toolchain }} with target (${{ matrix.target }})
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: ${{ matrix.toolchain }}
+ target: ${{ matrix.target }}
+ override: true
+
+ - name: Disable optimisation profiles
+ if: matrix.toolchain == '1.36.0'
+ run: sed -i '/^\[profile.*build-override]$/,/^$/{/^#/!{/^$/!d}}' Cargo.toml
+
+ - name: cargo check
+ uses: actions-rs/cargo@v1
+ with:
+ use-cross: false
+ command: check
+ args: --target=${{ matrix.target }}
+
+ # Verify all examples
+ checkexamples:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ target:
+ - thumbv7m-none-eabi
+ - thumbv6m-none-eabi
+ toolchain:
+ - stable
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Install Rust ${{ matrix.toolchain }} with target (${{ matrix.target }})
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: ${{ matrix.toolchain }}
+ target: ${{ matrix.target }}
+ override: true
+ - uses: actions-rs/cargo@v1
+ with:
+ use-cross: false
+ command: check
+ args: --examples --target=${{ matrix.target }} --features __min_r1_43
+
+ - name: cargo check -p homogeneous
+ uses: actions-rs/cargo@v1
+ with:
+ use-cross: false
+ command: check
+ args: -p homogeneous --examples --target=${{ matrix.target }}
+
+ - name: Install QEMU
+ run: |
+ mkdir qemu
+ curl -L https://github.com/japaric/qemu-bin/raw/master/14.04/qemu-system-arm-2.12.0 > qemu/qemu-system-arm
+ chmod +x qemu/qemu-system-arm
+
+ - name: Setup arm-none-eabi-gcc
+ uses: fiam/arm-none-eabi-gcc@v1
+ with:
+ release: '9-2019-q4' # The arm-none-eabi-gcc release to use.
+
+ - name: Run-pass tests
+ run: |
+ # Add QEMU to the path
+ echo $PATH
+ PATH=$(pwd)/qemu:$PATH
+ arm_example() {
+ local COMMAND=$1
+ local EXAMPLE=$2
+ local BUILD_MODE=$3
+ local FEATURES=$4
+ local BUILD_NUM=$5
+
+ if [ $BUILD_MODE = "release" ]; then
+ local RELEASE_FLAG="--release"
+ else
+ local RELEASE_FLAG=""
+ fi
+
+ if [ -n "$FEATURES" ]; then
+ local FEATURES_FLAG="--features $FEATURES"
+ local FEATURES_STR=${FEATURES/,/_}_
+ else
+ local FEATURES_FLAG=""
+ local FEATURES_STR=""
+ fi
+ local CARGO_FLAGS="--example $EXAMPLE --target ${{ matrix.target }} $RELEASE_FLAG $FEATURES_FLAG"
+
+ if [ $COMMAND = "run" ]; then
+ cargo $COMMAND $CARGO_FLAGS | diff -u ci/expected/$EXAMPLE.run -
+ else
+ cargo $COMMAND $CARGO_FLAGS
+ fi
+ arm-none-eabi-objcopy -O ihex target/${{ matrix.target }}/$BUILD_MODE/examples/$EXAMPLE ci/builds/${EXAMPLE}_${FEATURES_STR}${BUILD_MODE}_${BUILD_NUM}.hex
+ }
+
+ mkdir -p ci/builds
+ exs=(
+ idle
+ init
+ hardware
+ preempt
+ binds
+
+ resource
+ lock
+ late
+ only-shared-access
+
+ task
+ message
+ capacity
+
+ types
+ not-send
+ not-sync
+ shared-with-init
+
+ generics
+ cfg
+ pool
+ ramfunc
+ )
+
+ for ex in ${exs[@]}; do
+ if [ $ex = pool ]; then
+ if [ ${{ matrix.target }} = thumbv6m-none-eabi ]; then
+ continue
+ fi
+
+ td=$(mktemp -d)
+
+ cargo run --example $ex --target ${{ matrix.target }} --features __v7 >\
+ $td/pool.run
+ grep 'foo(0x2' $td/pool.run
+ grep 'bar(0x2' $td/pool.run
+ arm-none-eabi-objcopy -O ihex target/${{ matrix.target }}/debug/examples/$ex \
+ ci/builds/${ex}___v7_debug_1.hex
+
+ cargo run --example $ex --target ${{ matrix.target }} --features __v7 --release >\
+ $td/pool.run
+ grep 'foo(0x2' $td/pool.run
+ grep 'bar(0x2' $td/pool.run
+ arm-none-eabi-objcopy -O ihex target/${{ matrix.target }}/release/examples/$ex \
+ ci/builds/${ex}___v7_release_1.hex
+
+ rm -rf $td
+
+ continue
+ fi
+
+ if [ $ex = types ]; then
+ if [ ${{ matrix.target }} = thumbv6m-none-eabi ]; then
+ continue
+ fi
+
+ arm_example "run" $ex "debug" "__v7" "1"
+ arm_example "run" $ex "release" "__v7" "1"
+
+ continue
+ fi
+
+ arm_example "run" $ex "debug" "" "1"
+ if [ $ex = types ]; then
+ arm_example "run" $ex "release" "" "1"
+ else
+ arm_example "build" $ex "release" "" "1"
+ fi
+ done
+
+ built=()
+ cargo clean
+ for ex in ${exs[@]}; do
+ if [ $ex = types ] || [ $ex = pool ]; then
+ if [ ${{ matrix.target }} = thumbv6m-none-eabi ]; then
+ continue
+ fi
+
+ arm_example "build" $ex "debug" "__v7" "2"
+ cmp ci/builds/${ex}___v7_debug_1.hex \
+ ci/builds/${ex}___v7_debug_2.hex
+ arm_example "build" $ex "release" "__v7" "2"
+ cmp ci/builds/${ex}___v7_release_1.hex \
+ ci/builds/${ex}___v7_release_2.hex
+ else
+ arm_example "build" $ex "debug" "" "2"
+ cmp ci/builds/${ex}_debug_1.hex \
+ ci/builds/${ex}_debug_2.hex
+ arm_example "build" $ex "release" "" "2"
+ cmp ci/builds/${ex}_release_1.hex \
+ ci/builds/${ex}_release_2.hex
+ fi
+
+ built+=( $ex )
+ done
+
+ ( cd target/${{ matrix.target }}/release/examples/ && size ${built[@]} )
+
+
+ # Check the correctness of macros/ crate
+ checkmacros:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ target:
+ - x86_64-unknown-linux-gnu
+ toolchain:
+ - stable
+ - 1.36.0
+ - nightly
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Install Rust ${{ matrix.toolchain }} with target (${{ matrix.target }})
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: ${{ matrix.toolchain }}
+ target: ${{ matrix.target }}
+ override: true
+
+ - name: Disable optimisation profiles
+ if: matrix.toolchain == '1.36.0'
+ run: sed -i '/^\[profile.*build-override]$/,/^$/{/^#/!{/^$/!d}}' Cargo.toml
+
+ - name: cargo check
+ uses: actions-rs/cargo@v1
+ with:
+ use-cross: false
+ command: check
+ args: --manifest-path macros/Cargo.toml --target=${{ matrix.target }}
+
+ # Run test suite for thumbv7m
+ testv7:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Install Rust
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: 1.36.0
+ target: thumbv7m-none-eabi
+ override: true
+
+ - name: Disable optimisation profiles
+ run: sed -i '/^\[profile.*build-override]$/,/^$/{/^#/!{/^$/!d}}' Cargo.toml
+
+ - uses: actions-rs/cargo@v1
+ with:
+ use-cross: false
+ command: test
+ args: --test single --features __v7
+
+ # Run test suite for thumbv6m
+ testv6:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Install Rust
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: 1.36.0
+ target: thumbv6m-none-eabi
+ override: true
+
+ - name: Disable optimisation profiles
+ run: sed -i '/^\[profile.*build-override]$/,/^$/{/^#/!{/^$/!d}}' Cargo.toml
+
+ - uses: actions-rs/cargo@v1
+ with:
+ use-cross: false
+ command: test
+ args: --test single
+
+ # Verify all multicore examples
+ checkmulticore:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ target:
+ - x86_64-unknown-linux-gnu
+ toolchain:
+ - nightly
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Install Rust ${{ matrix.toolchain }} with x86_64-unknown-linux-gnu
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: ${{ matrix.toolchain }}
+ target: x86_64-unknown-linux-gnu
+ override: true
+ - name: Install Rust ${{ matrix.toolchain }} with thumbv7m-none-eabi
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: ${{ matrix.toolchain }}
+ target: thumbv7m-none-eabi
+ override: true
+ - name: Install Rust ${{ matrix.toolchain }} with thumbv6m-none-eabi
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: ${{ matrix.toolchain }}
+ target: thumbv6m-none-eabi
+ override: true
+ - uses: actions-rs/cargo@v1
+ with:
+ command: install
+ args: microamp-tools --version 0.1.0-alpha.3
+
+ - name: Check multi-core examples
+ run: |
+ cd heterogeneous
+ exs=(
+ smallest
+ x-init-2
+ x-init
+ x-schedule
+ x-spawn
+ )
+ for ex in ${exs[@]}; do
+ cargo-microamp --example=$ex --target thumbv7m-none-eabi,thumbv6m-none-eabi --check
+ done
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
new file mode 100644
index 00000000..297bff06
--- /dev/null
+++ b/.github/workflows/docs.yml
@@ -0,0 +1,93 @@
+name: Docs
+
+on:
+ push:
+ branches:
+ - master
+ - ghatest
+ pull_request:
+ branches:
+ - master
+ - ghatest
+
+env:
+ CARGO_TERM_COLOR: always
+
+jobs:
+ docs:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Set up Python 3.x
+ uses: actions/setup-python@v2
+ with:
+ # Semantic version range syntax or exact version of a Python version
+ python-version: '3.x'
+ # Optional - x64 or x86 architecture, defaults to x64
+ architecture: 'x64'
+
+ # You can test your matrix by printing the current Python version
+ - name: Display Python version
+ run: python -c "import sys; print(sys.version)"
+
+ - name: Install dependencies
+ run: pip install git+https://github.com/linkchecker/linkchecker.git
+
+ - name: Remove cargo-config
+ run: rm -f .cargo/config
+
+ - name: Build docs
+ run: cargo doc
+
+ - name: Check links
+ run: |
+ td=$(mktemp -d)
+ cp -r target/doc $td/api
+ linkchecker $td/api/rtfm/
+ linkchecker $td/api/cortex_m_rtfm_macros/
+
+ mdbook:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Set up Python 3.x
+ uses: actions/setup-python@v2
+ with:
+ # Semantic version range syntax or exact version of a Python version
+ python-version: '3.x'
+ # Optional - x64 or x86 architecture, defaults to x64
+ architecture: 'x64'
+
+ # You can test your matrix by printing the current Python version
+ - name: Display Python version
+ run: python -c "import sys; print(sys.version)"
+
+ - name: Install dependencies
+ run: pip install git+https://github.com/linkchecker/linkchecker.git
+
+ - name: mdBook Action
+ uses: peaceiris/actions-mdbook@v1.1.11
+ with:
+ mdbook-version: '0.3.1'
+
+ - name: Build book in English
+ run: cd book/en && mdbook build
+
+ - name: Build book in Russian
+ run: cd book/ru && mdbook build
+
+ - name: Check links
+ run: |
+ td=$(mktemp -d)
+ mkdir $td/book
+ cp -r book/en/book $td/book/en
+ cp -r book/ru/book $td/book/ru
+ cp LICENSE-* $td/book/en
+ cp LICENSE-* $td/book/ru
+
+ linkchecker $td/book/en/
+ linkchecker $td/book/ru/
diff --git a/.github/workflows/properties/build.properties.json b/.github/workflows/properties/build.properties.json
new file mode 100644
index 00000000..e447a1ed
--- /dev/null
+++ b/.github/workflows/properties/build.properties.json
@@ -0,0 +1,6 @@
+{
+ "name": "Build",
+ "description": "Build and test a Rust project with Cargo.",
+ "iconName": "rust",
+ "categories": ["Rust"]
+}
diff --git a/.github/workflows/properties/docs.properties.json b/.github/workflows/properties/docs.properties.json
new file mode 100644
index 00000000..a9a052c4
--- /dev/null
+++ b/.github/workflows/properties/docs.properties.json
@@ -0,0 +1,6 @@
+{
+ "name": "Docs",
+ "description": "Build the books.",
+ "iconName": "rust",
+ "categories": ["Rust"]
+}
diff --git a/.github/workflows/properties/publish.properties.json b/.github/workflows/properties/publish.properties.json
new file mode 100644
index 00000000..fa9b8cda
--- /dev/null
+++ b/.github/workflows/properties/publish.properties.json
@@ -0,0 +1,6 @@
+{
+ "name": "Publish",
+ "description": "Publish the books and docs.",
+ "iconName": "rust",
+ "categories": ["Rust"]
+}
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 00000000..7436bf88
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,94 @@
+name: Publish
+
+on:
+ push:
+ branches:
+ - master
+
+jobs:
+ deploy:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Set up Python 3.x
+ uses: actions/setup-python@v2
+ with:
+ # Semantic version range syntax or exact version of a Python version
+ python-version: '3.x'
+ # Optional - x64 or x86 architecture, defaults to x64
+ architecture: 'x64'
+
+ # You can test your matrix by printing the current Python version
+ - name: Display Python version
+ run: python -c "import sys; print(sys.version)"
+
+ - name: mdBook Action
+ uses: peaceiris/actions-mdbook@v1.1.11
+ with:
+ mdbook-version: '0.3.1'
+ # mdbook-version: 'latest'
+
+ - name: Remove cargo-config
+ run: rm -f .cargo/config
+
+ - name: Build docs
+ run: cargo doc
+
+ - name: Build books
+ run: |
+ langs=( en ru )
+ latest=0.5
+ vers=( 0.4.x )
+
+ # Create directories
+ td=$(mktemp -d)
+ mkdir -p $td/$latest/book/
+ cp -r target/doc $td/$latest/api
+
+ # sed fixes
+ sed 's|URL|rtfm/index.html|g' redirect.html > $td/$latest/api/index.html
+ sed 's|URL|0.5|g' redirect.html > $td/index.html
+ sed 's|URL|book/en|g' redirect.html > $td/$latest/index.html
+
+ # Build books
+ for lang in ${langs[@]}; do
+ ( cd book/$lang && mdbook build )
+ cp -r book/$lang/book $td/$latest/book/$lang
+ cp LICENSE-* $td/$latest/book/$lang/
+ done
+
+ # Build older versions
+ root=$(pwd)
+ for ver in ${vers[@]}; do
+ prefix=${ver%.*}
+
+ mkdir -p $td/$prefix/book
+ src=$(mktemp -d)
+ curl -L https://github.com/rtfm-rs/cortex-m-rtfm/archive/v${ver}.tar.gz | tar xz --strip-components 1 -C $src
+
+ pushd $src
+ rm -f .cargo/config
+ cargo doc || cargo doc --features timer-queue
+ cp -r target/doc $td/$prefix/api
+ sed 's|URL|rtfm/index.html|g' $root/redirect.html > $td/$prefix/api/index.html
+ for lang in ${langs[@]}; do
+ ( cd book/$lang && mdbook build )
+ cp -r book/$lang/book $td/$prefix/book/$lang
+ cp LICENSE-* $td/$prefix/book/$lang/
+ done
+ sed 's|URL|book/en|g' $root/redirect.html > $td/$prefix/index.html
+ popd
+
+ rm -rf $src
+ done
+
+ # Forward CNAME file
+ cp CNAME $td/
+ mv $td/ bookstodeploy
+
+ - name: Deploy
+ uses: peaceiris/actions-gh-pages@v3
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: ./bookstodeploy
diff --git a/.travis.yml b/.travis.yml
index 1bb25051..c2651307 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -37,6 +37,7 @@ before_install:
install:
- bash ci/install.sh
- export PATH="$PATH:$PWD/qemu"
+ - export PATH="$PATH:$PWD/mdbook-bin"
script:
- bash ci/script.sh
diff --git a/Cargo.toml b/Cargo.toml
index ce371f93..fbc56c47 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -39,6 +39,10 @@ name = "t-cfg"
required-features = ["__v7"]
[[example]]
+name = "t-cfg-resources"
+required-features = ["__min_r1_43"]
+
+[[example]]
name = "t-schedule"
required-features = ["__v7"]
@@ -47,12 +51,15 @@ name = "types"
required-features = ["__v7"]
[dependencies]
-cortex-m = "0.6.0"
+cortex-m = "0.6.2"
cortex-m-rtfm-macros = { path = "macros", version = "0.5.0" }
rtfm-core = "0.3.0"
cortex-m-rt = "0.6.9"
heapless = "0.5.0"
+[build-dependencies]
+version_check = "0.9"
+
[dependencies.microamp]
optional = true
version = "0.1.0-alpha.2"
@@ -74,6 +81,7 @@ heterogeneous = ["cortex-m-rtfm-macros/heterogeneous", "microamp"]
homogeneous = ["cortex-m-rtfm-macros/homogeneous"]
# used for testing this crate; do not use in applications
__v7 =[]
+__min_r1_43 =[]
[profile.release]
codegen-units = 1
diff --git a/book/en/src/by-example/app.md b/book/en/src/by-example/app.md
index f6871942..2450c59a 100644
--- a/book/en/src/by-example/app.md
+++ b/book/en/src/by-example/app.md
@@ -70,7 +70,7 @@ so it must run forever.
When no `idle` function is declared, the runtime sets the [SLEEPONEXIT] bit and
then sends the microcontroller to sleep after running `init`.
-[SLEEPONEXIT]: https://developer.arm.com/products/architecture/cpu-architecture/m-profile/docs/100737/0100/power-management/sleep-mode/sleep-on-exit-bit
+[SLEEPONEXIT]: https://developer.arm.com/docs/100737/0100/power-management/sleep-mode/sleep-on-exit-bit
Like in `init`, `static mut` variables will be transformed into `&'static mut`
references that are safe to access.
@@ -103,10 +103,10 @@ mut` variables are safe to use within a hardware task.
```
``` console
-$ cargo run --example interrupt
+$ cargo run --example hardware
{{#include ../../../../ci/expected/hardware.run}}```
-So far all the RTFM applications we have seen look no different that the
+So far all the RTFM applications we have seen look no different than the
applications one can write using only the `cortex-m-rt` crate. From this point
we start introducing features unique to RTFM.
@@ -115,7 +115,7 @@ we start introducing features unique to RTFM.
The static priority of each handler can be declared in the `task` attribute
using the `priority` argument. Tasks can have priorities in the range `1..=(1 <<
NVIC_PRIO_BITS)` where `NVIC_PRIO_BITS` is a constant defined in the `device`
-crate. When the `priority` argument is omitted the priority is assumed to be
+crate. When the `priority` argument is omitted, the priority is assumed to be
`1`. The `idle` task has a non-configurable static priority of `0`, the lowest
priority.
@@ -135,17 +135,17 @@ The following example showcases the priority based scheduling of tasks.
```
``` console
-$ cargo run --example interrupt
+$ cargo run --example preempt
{{#include ../../../../ci/expected/preempt.run}}```
Note that the task `gpiob` does *not* preempt task `gpioc` because its priority
is the *same* as `gpioc`'s. However, once `gpioc` terminates the execution of
-task `gpiob` is prioritized over `gpioa`'s due to its higher priority. `gpioa`
+task, `gpiob` is prioritized over `gpioa` due to its higher priority. `gpioa`
is resumed only after `gpiob` terminates.
One more note about priorities: choosing a priority higher than what the device
supports (that is `1 << NVIC_PRIO_BITS`) will result in a compile error. Due to
-limitations in the language the error message is currently far from helpful: it
+limitations in the language, the error message is currently far from helpful: it
will say something along the lines of "evaluation of constant value failed" and
the span of the error will *not* point out to the problematic interrupt value --
we are sorry about this!
diff --git a/book/en/src/by-example/resources.md b/book/en/src/by-example/resources.md
index b33ca9bb..db7630ea 100644
--- a/book/en/src/by-example/resources.md
+++ b/book/en/src/by-example/resources.md
@@ -11,7 +11,7 @@ All resources are declared as a single `struct` within the `#[app]`
pseudo-module. Each field in the structure corresponds to a different resource.
Resources can optionally be given an initial value using the `#[init]`
attribute. Resources that are not given an initial value are referred to as
-*late* resources and are covered in more detail in a follow up section in this
+*late* resources and are covered in more detail in a follow-up section in this
page.
Each context (task handler, `init` or `idle`) must declare the resources it
@@ -31,7 +31,7 @@ access to a resource named `shared`.
$ cargo run --example resource
{{#include ../../../../ci/expected/resource.run}}```
-Note that the `shared` resource cannot accessed from `idle`. Attempting to do
+Note that the `shared` resource cannot be accessed from `idle`. Attempting to do
so results in a compile error.
## `lock`
@@ -75,14 +75,14 @@ $ cargo run --example lock
## Late resources
-Late resources are resources that are not given an initial value at compile
-using the `#[init]` attribute but instead are initialized are runtime using the
+Late resources are resources that are not given an initial value at compile time
+using the `#[init]` attribute but instead are initialized at runtime using the
`init::LateResources` values returned by the `init` function.
Late resources are useful for *moving* (as in transferring the ownership of)
peripherals initialized in `init` into interrupt handlers.
-The example below uses late resources to stablish a lockless, one-way channel
+The example below uses late resources to establish a lockless, one-way channel
between the `UART0` interrupt handler and the `idle` task. A single producer
single consumer [`Queue`] is used as the channel. The queue is split into
consumer and producer end points in `init` and then each end point is stored
diff --git a/book/ru/src/by-example/app.md b/book/ru/src/by-example/app.md
index 7dc08127..884257dd 100644
--- a/book/ru/src/by-example/app.md
+++ b/book/ru/src/by-example/app.md
@@ -66,7 +66,7 @@ $ cargo run --example init
Когда функция `idle` не определена, рантайм устанавливает бит [SLEEPONEXIT], после чего
отправляет микроконтроллер в состояние сна после выполнения `init`.
-[SLEEPONEXIT]: https://developer.arm.com/products/architecture/cpu-architecture/m-profile/docs/100737/0100/power-management/sleep-mode/sleep-on-exit-bit
+[SLEEPONEXIT]: https://developer.arm.com/docs/100737/0100/power-management/sleep-mode/sleep-on-exit-bit
Как и в `init`, переменные `static mut`будут преобразованы в ссылки `&'static mut`
с безопасным доступом.
diff --git a/build.rs b/build.rs
index 14c3d248..fee1a6a5 100644
--- a/build.rs
+++ b/build.rs
@@ -1,8 +1,13 @@
use std::env;
+use version_check;
fn main() {
let target = env::var("TARGET").unwrap();
+ if version_check::Channel::read().unwrap().is_nightly() {
+ println!("cargo:rustc-cfg=rustc_is_nightly")
+ }
+
if target.starts_with("thumbv6m") {
println!("cargo:rustc-cfg=armv6m")
}
diff --git a/ci/install.sh b/ci/install.sh
index 54701224..624efd87 100644
--- a/ci/install.sh
+++ b/ci/install.sh
@@ -15,7 +15,6 @@ main() {
fi
rustup target add $TARGET
-
mkdir qemu
curl -L https://github.com/japaric/qemu-bin/raw/master/14.04/qemu-system-arm-2.12.0 > qemu/qemu-system-arm
chmod +x qemu/qemu-system-arm
@@ -23,7 +22,13 @@ main() {
pip install linkchecker --user
fi
- install_crate mdbook 0.3.1
+ # Download binary mdbook and add to path
+ curl -L https://github.com/rust-lang/mdBook/releases/download/v0.3.1/mdbook-v0.3.1-x86_64-unknown-linux-gnu.tar.gz > mdbook.tar.gz
+ tar -xf mdbook.tar.gz
+ mkdir -p mdbook-bin
+ mv mdbook mdbook-bin/
+
+ #install_crate mdbook 0.3.1
}
main
diff --git a/ci/script.sh b/ci/script.sh
index 78341e1b..7743b8ba 100644
--- a/ci/script.sh
+++ b/ci/script.sh
@@ -36,6 +36,12 @@ main() {
mkdir -p ci/builds
+ # Current MSRV cannot handle profiles, remove compilation optimisations
+ if [[ $TRAVIS_RUST_VERSION == 1.*.* ]]; then
+ echo "Removing optimisation profiles"
+ sed -i '/^\[profile.*build-override]$/,/^$/{/^#/!{/^$/!d}}' Cargo.toml
+ fi
+
if [ $T = x86_64-unknown-linux-gnu ]; then
if [[ $TRAVIS_RUST_VERSION == 1.*.* ]]; then
# test on a fixed version (MSRV) to avoid problems with changes in rustc diagnostics
@@ -44,6 +50,13 @@ main() {
fi
if [ $TRAVIS_RUST_VERSION = nightly ]; then
+ # Tests where required MSRV > 1.36
+ #local exs=(
+ #)
+ #for ex in ${exs[@]}; do
+ # cargo check --example $ex --target $T
+ #done
+
# multi-core compile-pass tests
pushd heterogeneous
local exs=(
@@ -89,8 +102,18 @@ main() {
if [ $TARGET = thumbv6m-none-eabi ]; then
cargo check --target $T --examples
+
+ # Check examples with specific features not compatible with MSRV
+ if [[ $TRAVIS_RUST_VERSION != 1.*.* ]]; then
+ cargo check --target $T --examples --features __min_r1_43
+ fi
else
cargo check --target $T --examples --features __v7
+
+ # Check examples with specific features not compatible with MSRV
+ if [[ $TRAVIS_RUST_VERSION != 1.*.* ]]; then
+ cargo check --target $T --examples --features __v7,__min_r1_43
+ fi
fi
cargo check -p homogeneous --target $T --examples
diff --git a/examples/schedule.rs b/examples/schedule.rs
index 97818e36..d5de9dbf 100644
--- a/examples/schedule.rs
+++ b/examples/schedule.rs
@@ -1,9 +1,11 @@
//! examples/schedule.rs
+#![deny(unsafe_code)]
#![deny(warnings)]
#![no_main]
#![no_std]
+use cortex_m::peripheral::DWT;
use cortex_m_semihosting::hprintln;
use panic_halt as _;
use rtfm::cyccnt::{Instant, U32Ext as _};
@@ -15,11 +17,12 @@ const APP: () = {
fn init(mut cx: init::Context) {
// Initialize (enable) the monotonic timer (CYCCNT)
cx.core.DCB.enable_trace();
- // required on devices that software lock the DWT (e.g. STM32F7)
- unsafe { cx.core.DWT.lar.write(0xC5ACCE55) }
+ // required on Cortex-M7 devices that software lock the DWT (e.g. STM32F7)
+ DWT::unlock();
cx.core.DWT.enable_cycle_counter();
// semantically, the monotonic timer is frozen at time "zero" during `init`
+ // NOTE do *not* call `Instant::now` in this context; it will return a nonsense value
let now = cx.start; // the start time of the system
hprintln!("init @ {:?}", now).unwrap();
diff --git a/examples/t-cfg-resources.rs b/examples/t-cfg-resources.rs
new file mode 100644
index 00000000..a8efe79e
--- /dev/null
+++ b/examples/t-cfg-resources.rs
@@ -0,0 +1,36 @@
+//! [compile-pass] check that `#[cfg]` attributes applied on resources work
+//!
+#![no_main]
+#![no_std]
+
+use panic_halt as _;
+
+#[rtfm::app(device = lm3s6965)]
+const APP: () = {
+ struct Resources {
+ // A resource
+ #[init(0)]
+ shared: u32,
+
+ // A conditionally compiled resource behind feature_x
+ #[cfg(feature = "feature_x")]
+ x: u32,
+
+ dummy: (),
+ }
+
+ #[init]
+ fn init(_: init::Context) -> init::LateResources {
+ init::LateResources {
+ // The feature needs to be applied everywhere x is defined or used
+ #[cfg(feature = "feature_x")]
+ x: 0,
+ dummy: (), // dummy such that we have at least one late resource
+ }
+ }
+
+ #[idle]
+ fn idle(_cx: idle::Context) -> ! {
+ loop {}
+ }
+};
diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs
index 02138481..60074849 100644
--- a/macros/src/codegen.rs
+++ b/macros/src/codegen.rs
@@ -39,7 +39,8 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
let (const_app_init, root_init, user_init, call_init) =
init::codegen(core, app, analysis, extra);
- let (const_app_post_init, post_init_stmts) = post_init::codegen(core, analysis, extra);
+ let (const_app_post_init, post_init_stmts) =
+ post_init::codegen(core, &app, analysis, extra);
let (const_app_idle, root_idle, user_idle, call_idle) =
idle::codegen(core, app, analysis, extra);
diff --git a/macros/src/codegen/init.rs b/macros/src/codegen/init.rs
index fc2faa34..534b79b0 100644
--- a/macros/src/codegen/init.rs
+++ b/macros/src/codegen/init.rs
@@ -44,8 +44,12 @@ pub fn codegen(
.iter()
.map(|name| {
let ty = &app.late_resources[name].ty;
+ let cfgs = &app.late_resources[name].cfgs;
- quote!(pub #name: #ty)
+ quote!(
+ #(#cfgs)*
+ pub #name: #ty
+ )
})
.collect::<Vec<_>>()
})
diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs
index 19773e45..b816e072 100644
--- a/macros/src/codegen/post_init.rs
+++ b/macros/src/codegen/post_init.rs
@@ -1,11 +1,13 @@
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
+use rtfm_syntax::ast::App;
use crate::{analyze::Analysis, check::Extra, codegen::util};
/// Generates code that runs after `#[init]` returns
pub fn codegen(
core: u8,
+ app: &App,
analysis: &Analysis,
extra: &Extra,
) -> (Vec<TokenStream2>, Vec<TokenStream2>) {
@@ -16,8 +18,13 @@ pub fn codegen(
if let Some(late_resources) = analysis.late_resources.get(&core) {
for name in late_resources {
// if it's live
+ let cfgs = app.late_resources[name].cfgs.clone();
if analysis.locations.get(name).is_some() {
- stmts.push(quote!(#name.as_mut_ptr().write(late.#name);));
+ // Need to also include the cfgs
+ stmts.push(quote!(
+ #(#cfgs)*
+ #name.as_mut_ptr().write(late.#name);
+ ));
}
}
}
diff --git a/macros/src/codegen/resources.rs b/macros/src/codegen/resources.rs
index 8cb788d1..83bfabd7 100644
--- a/macros/src/codegen/resources.rs
+++ b/macros/src/codegen/resources.rs
@@ -101,9 +101,15 @@ pub fn codegen(
));
let ptr = if expr.is_none() {
- quote!(#name.as_mut_ptr())
+ quote!(
+ #(#cfgs)*
+ #name.as_mut_ptr()
+ )
} else {
- quote!(&mut #name)
+ quote!(
+ #(#cfgs)*
+ &mut #name
+ )
};
const_app.push(util::impl_mutex(
diff --git a/src/cyccnt.rs b/src/cyccnt.rs
index 338bbbea..6bc2ef0a 100644
--- a/src/cyccnt.rs
+++ b/src/cyccnt.rs
@@ -30,6 +30,10 @@ pub struct Instant {
impl Instant {
/// Returns an instant corresponding to "now"
+ ///
+ /// *HEADS UP* this function can, and will, return nonsensical values if called within `init`.
+ /// Only use it in `idle` and tasks. In `init`, use the `init::Context.start` field, or the
+ /// `CYCCNT::zero` function, instead of this function
pub fn now() -> Self {
Instant {
inner: DWT::get_cycle_count() as i32,