diff options
-rw-r--r-- | .github/workflows/build.yml | 379 | ||||
-rw-r--r-- | .github/workflows/docs.yml | 93 | ||||
-rw-r--r-- | .github/workflows/properties/build.properties.json | 6 | ||||
-rw-r--r-- | .github/workflows/properties/docs.properties.json | 6 | ||||
-rw-r--r-- | .github/workflows/properties/publish.properties.json | 6 | ||||
-rw-r--r-- | .github/workflows/publish.yml | 94 | ||||
-rw-r--r-- | .travis.yml | 1 | ||||
-rw-r--r-- | Cargo.toml | 21 | ||||
-rw-r--r-- | book/en/src/by-example/app.md | 8 | ||||
-rw-r--r-- | book/en/src/by-example/resources.md | 10 | ||||
-rw-r--r-- | ci/install.sh | 9 | ||||
-rw-r--r-- | ci/script.sh | 16 | ||||
-rw-r--r-- | examples/t-cfg-resources.rs | 52 | ||||
-rw-r--r-- | examples/t-htask-main.rs | 20 | ||||
-rw-r--r-- | examples/t-idle-main.rs | 20 | ||||
-rw-r--r-- | examples/t-init-main.rs | 15 | ||||
-rw-r--r-- | examples/t-stask-main.rs | 24 | ||||
-rw-r--r-- | macros/src/codegen.rs | 5 | ||||
-rw-r--r-- | macros/src/codegen/dispatchers.rs | 2 | ||||
-rw-r--r-- | macros/src/codegen/idle.rs | 2 | ||||
-rw-r--r-- | macros/src/codegen/init.rs | 8 | ||||
-rw-r--r-- | macros/src/codegen/post_init.rs | 7 | ||||
-rw-r--r-- | src/lib.rs | 1 |
23 files changed, 755 insertions, 50 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 @@ -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"] @@ -77,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 @@ -88,3 +93,19 @@ members = [ "homogeneous", "macros", ] + +# do not optimize proc-macro deps or build scripts +[profile.dev.build-override] +codegen-units = 16 +debug = false +debug-assertions = false +opt-level = 0 +overflow-checks = false + + +[profile.release.build-override] +codegen-units = 16 +debug = false +debug-assertions = false +opt-level = 0 +overflow-checks = false diff --git a/book/en/src/by-example/app.md b/book/en/src/by-example/app.md index 00e00519..2450c59a 100644 --- a/book/en/src/by-example/app.md +++ b/book/en/src/by-example/app.md @@ -106,7 +106,7 @@ mut` variables are safe to use within a hardware task. $ 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. @@ -140,12 +140,12 @@ $ cargo run --example preempt 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/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 7b86e52a..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 @@ -96,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/t-cfg-resources.rs b/examples/t-cfg-resources.rs index 86b5ea20..a8efe79e 100644 --- a/examples/t-cfg-resources.rs +++ b/examples/t-cfg-resources.rs @@ -5,36 +5,32 @@ use panic_halt as _; -#[cfg(rustc_is_nightly)] -mod example { +#[rtfm::app(device = lm3s6965)] +const APP: () = { + struct Resources { + // A resource + #[init(0)] + shared: u32, - #[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, - // A conditionally compiled resource behind feature_x - #[cfg(feature = "feature_x")] - x: u32, - - dummy: (), - } + 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 - } + #[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 {} - } - }; -} + #[idle] + fn idle(_cx: idle::Context) -> ! { + loop {} + } +}; diff --git a/examples/t-htask-main.rs b/examples/t-htask-main.rs new file mode 100644 index 00000000..d229d818 --- /dev/null +++ b/examples/t-htask-main.rs @@ -0,0 +1,20 @@ +#![deny(unsafe_code)] +#![deny(warnings)] +#![no_main] +#![no_std] + +use cortex_m_semihosting::debug; +use panic_semihosting as _; + +#[rtfm::app(device = lm3s6965)] +const APP: () = { + #[init] + fn init(_: init::Context) { + rtfm::pend(lm3s6965::Interrupt::UART0) + } + + #[task(binds = UART0)] + fn main(_: main::Context) { + debug::exit(debug::EXIT_SUCCESS); + } +}; diff --git a/examples/t-idle-main.rs b/examples/t-idle-main.rs new file mode 100644 index 00000000..d1bb1483 --- /dev/null +++ b/examples/t-idle-main.rs @@ -0,0 +1,20 @@ +#![deny(unsafe_code)] +#![deny(warnings)] +#![no_main] +#![no_std] + +use cortex_m_semihosting::debug; +use panic_semihosting as _; + +#[rtfm::app(device = lm3s6965)] +const APP: () = { + #[init] + fn init(_: init::Context) { + } + + #[idle] + fn main(_: main::Context) -> ! { + debug::exit(debug::EXIT_SUCCESS); + loop {} + } +}; diff --git a/examples/t-init-main.rs b/examples/t-init-main.rs new file mode 100644 index 00000000..e0d94d5f --- /dev/null +++ b/examples/t-init-main.rs @@ -0,0 +1,15 @@ +#![deny(unsafe_code)] +#![deny(warnings)] +#![no_main] +#![no_std] + +use cortex_m_semihosting::debug; +use panic_semihosting as _; + +#[rtfm::app(device = lm3s6965)] +const APP: () = { + #[init] + fn main(_: main::Context) { + debug::exit(debug::EXIT_SUCCESS); + } +}; diff --git a/examples/t-stask-main.rs b/examples/t-stask-main.rs new file mode 100644 index 00000000..b55161ea --- /dev/null +++ b/examples/t-stask-main.rs @@ -0,0 +1,24 @@ +#![deny(unsafe_code)] +#![deny(warnings)] +#![no_main] +#![no_std] + +use cortex_m_semihosting::debug; +use panic_semihosting as _; + +#[rtfm::app(device = lm3s6965)] +const APP: () = { + #[init(spawn = [main])] + fn init(cx: init::Context) { + cx.spawn.main().ok(); + } + + #[task] + fn main(_: main::Context) { + debug::exit(debug::EXIT_SUCCESS); + } + + extern "C" { + fn UART0(); + } +}; diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index 7d0d1220..80e65cd4 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, &app, 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); @@ -74,6 +75,8 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { #section #cfg_core unsafe extern "C" fn #main() -> ! { + let _TODO: () = (); + #(#assertion_stmts)* #(#pre_init_stmts)* diff --git a/macros/src/codegen/dispatchers.rs b/macros/src/codegen/dispatchers.rs index 9a9cb102..1400786b 100644 --- a/macros/src/codegen/dispatchers.rs +++ b/macros/src/codegen/dispatchers.rs @@ -141,7 +141,7 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream #let_instant #fq.split().0.enqueue_unchecked(index); let priority = &rtfm::export::Priority::new(PRIORITY); - #name( + crate::#name( #locals_new #name::Context::new(priority #instant) #(,#pats)* diff --git a/macros/src/codegen/idle.rs b/macros/src/codegen/idle.rs index 35a72523..72432f67 100644 --- a/macros/src/codegen/idle.rs +++ b/macros/src/codegen/idle.rs @@ -72,7 +72,7 @@ pub fn codegen( )); let locals_new = locals_new.iter(); - let call_idle = quote!(#name( + let call_idle = quote!(crate::#name( #(#locals_new,)* #name::Context::new(&rtfm::export::Priority::new(0)) )); diff --git a/macros/src/codegen/init.rs b/macros/src/codegen/init.rs index f7e4674e..534b79b0 100644 --- a/macros/src/codegen/init.rs +++ b/macros/src/codegen/init.rs @@ -47,9 +47,9 @@ pub fn codegen( let cfgs = &app.late_resources[name].cfgs; quote!( - #(#cfgs)* - pub #name: #ty - ) + #(#cfgs)* + pub #name: #ty + ) }) .collect::<Vec<_>>() }) @@ -109,7 +109,7 @@ pub fn codegen( let locals_new = locals_new.iter(); let call_init = - Some(quote!(let late = #name(#(#locals_new,)* #name::Context::new(core.into()));)); + Some(quote!(let late = crate::#name(#(#locals_new,)* #name::Context::new(core.into()));)); root_init.push(module::codegen(Context::Init(core), needs_lt, app, extra)); diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs index 8578d5ac..b816e072 100644 --- a/macros/src/codegen/post_init.rs +++ b/macros/src/codegen/post_init.rs @@ -16,16 +16,15 @@ pub fn codegen( // initialize late resources 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() { // Need to also include the cfgs stmts.push(quote!( - #(#cfgs)* - #name.as_mut_ptr().write(late.#name); - )); + #(#cfgs)* + #name.as_mut_ptr().write(late.#name); + )); } } } @@ -164,6 +164,7 @@ pub trait Monotonic { /// A marker trait that indicates that it is correct to use this type in multi-core context pub trait MultiCore {} + /// Sets the given `interrupt` as pending /// /// This is a convenience function around |