Skip to content

Commit

Permalink
Merge #176
Browse files Browse the repository at this point in the history
176:  implement RFCs 147 and 155, fix #141, etc. r=japaric a=japaric

This PR:

- Implements RFC 147: "all functions must be safe"

- Implements RFC 155: "explicit Context parameter"

- Implements the pending breaking change #141: reject assign syntax in `init`
  (which was used to initialize late resources)

- Refactors code generation to make it more readable -- there are no more random
  identifiers in the output -- and align it with the book description of RTFM
  internals (see PR #175).

- Makes the framework hard depend on `core::mem::MaybeUninit` and thus will
  require nightly until that API is stabilized.

- Fixes a ceiling analysis bug where the priority of the system timer was not
  considered in the analysis (TODO backport this into the v0.4.x branch).

- Shrinks the size of all the internal queues by turning `AtomicUsize` indices
  into `AtomicU8`s.

- Removes the integration with `owned_singleton`.

closes #141
closes #147
closes #155

Additionally:

- This changes CI to push v0.5.x docs to
  https://japaric.github.io/rtfm5/book/en/ -- we need to do this because our
  official docs are hosted on https://japaric.github.io/cortex-m-rtfm and we
  need to keep them on v0.4.x until we release v0.5.0

- I propose that we use the master branch to develop the upcoming v0.5.0.

- I have created a branch v0.4.x for backports; new v0.4.x releases will come
  from that branch.

r? @korken89 @TeXitoi, sorry for doing all the impl work in a single commit --
I know that makes things harder to review for you.

Suggestions for compile-pass and compile-fail tests are welcome


Co-authored-by: Jorge Aparicio <jorge@japaric.io>
  • Loading branch information
bors[bot] and japaric committed May 1, 2019
2 parents e6fb2f2 + ccd7f45 commit bc024f1
Show file tree
Hide file tree
Showing 97 changed files with 3,045 additions and 2,967 deletions.
12 changes: 6 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ language: rust
matrix:
include:
# NOTE used to build docs on successful merges to master
- env: TARGET=x86_64-unknown-linux-gnu
# - env: TARGET=x86_64-unknown-linux-gnu

- env: TARGET=thumbv6m-none-eabi
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
# - env: TARGET=thumbv6m-none-eabi
# if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)

- env: TARGET=thumbv7m-none-eabi
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
# - env: TARGET=thumbv7m-none-eabi
# if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)

- env: TARGET=x86_64-unknown-linux-gnu
rust: nightly
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
# if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)

- env: TARGET=thumbv6m-none-eabi
rust: nightly
Expand Down
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,35 @@ This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

## v0.5.0 - 2019-??-?? (ALPHA pre-release)

### Changed

- [breaking-change][] [RFC 155] "explicit `Context` parameter" has been
implemented.

[RFC 155]: https://github.com/japaric/cortex-m-rtfm/issues/155

- [breaking-change][] [RFC 147] "all functions must be safe" has been
implemented.

[RFC 147]: https://github.com/japaric/cortex-m-rtfm/issues/147

- All the queues internally used by the framework now use `AtomicU8` indices
instead of `AtomicUsize`; this reduces the static memory used by the
framework.

### Removed

- [breaking-change] the integration with the `owned_singleton` crate has been
removed. You can use `heapless::Pool` instead of `alloc_singleton`.

- [breaking-change] late resources can no longer be initialized using the assign
syntax. `init::LateResources` is the only method to initialize late resources.
See [PR #140] for more details.

[PR #140]: https://github.com/japaric/cortex-m-rtfm/pull/140

## [v0.4.3] - 2019-04-21

### Changed
Expand Down
17 changes: 12 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ license = "MIT OR Apache-2.0"
name = "cortex-m-rtfm"
readme = "README.md"
repository = "https://github.com/japaric/cortex-m-rtfm"
version = "0.4.3"
version = "0.5.0-alpha.1"

[lib]
name = "rtfm"
Expand All @@ -25,6 +25,12 @@ required-features = ["timer-queue"]
name = "periodic"
required-features = ["timer-queue"]

[[example]]
name = "pool"
# this example doesn't need this feature but only works on ARMv7-M
# specifying the feature here avoids compiling this for ARMv6-M
required-features = ["timer-queue"]

[[example]]
name = "schedule"
required-features = ["timer-queue"]
Expand All @@ -36,12 +42,13 @@ required-features = ["timer-queue"]
[dependencies]
cortex-m = "0.5.8"
cortex-m-rt = "0.6.7"
cortex-m-rtfm-macros = { path = "macros", version = "0.4.3" }
heapless = "0.4.1"
owned-singleton = "0.1.0"
cortex-m-rtfm-macros = { path = "macros", version = "0.5.0-alpha.1" }

[dependencies.heapless]
features = ["smaller-atomics", "min-const-fn"]
version = "0.4.3"

[dev-dependencies]
alloc-singleton = "0.1.0"
cortex-m-semihosting = "0.3.2"
lm3s6965 = "0.1.3"
panic-halt = "0.2.0"
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ A concurrency framework for building real time systems.

## Requirements

- Rust 1.31.0+
- Rust 1.36.0+

- Applications must be written using the 2018 edition.

## [User documentation](https://japaric.github.io/cortex-m-rtfm/book/en)
## [User documentation](https://japaric.github.io/rtfm5/book/en)

## [API reference](https://japaric.github.io/cortex-m-rtfm/api/rtfm/index.html)
## [API reference](https://japaric.github.io/rtfm5/api/rtfm/index.html)

## Acknowledgments

Expand Down
1 change: 0 additions & 1 deletion book/en/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
- [Resources](./by-example/resources.md)
- [Tasks](./by-example/tasks.md)
- [Timer queue](./by-example/timer-queue.md)
- [Singletons](./by-example/singletons.md)
- [Types, Send and Sync](./by-example/types-send-sync.md)
- [Starting a new project](./by-example/new.md)
- [Tips & tricks](./by-example/tips.md)
Expand Down
11 changes: 5 additions & 6 deletions book/en/src/by-example/app.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,14 @@ not required to use the [`cortex_m_rt::entry`] attribute.

Within the pseudo-module the `app` attribute expects to find an initialization
function marked with the `init` attribute. This function must have signature
`[unsafe] fn()`.
`fn(init::Context) [-> init::LateResources]`.

This initialization function will be the first part of the application to run.
The `init` function will run *with interrupts disabled* and has exclusive access
to Cortex-M and device specific peripherals through the `core` and `device`
variables, which are injected in the scope of `init` by the `app` attribute. Not
all Cortex-M peripherals are available in `core` because the RTFM runtime takes
ownership of some of them -- for more details see the [`rtfm::Peripherals`]
struct.
variables fields of `init::Context`. Not all Cortex-M peripherals are available
in `core` because the RTFM runtime takes ownership of some of them -- for more
details see the [`rtfm::Peripherals`] struct.

`static mut` variables declared at the beginning of `init` will be transformed
into `&'static mut` references that are safe to access.
Expand All @@ -61,7 +60,7 @@ $ cargo run --example init

A function marked with the `idle` attribute can optionally appear in the
pseudo-module. This function is used as the special *idle task* and must have
signature `[unsafe] fn() - > !`.
signature `fn(idle::Context) - > !`.

When present, the runtime will execute the `idle` task after `init`. Unlike
`init`, `idle` will run *with interrupts enabled* and it's not allowed to return
Expand Down
4 changes: 2 additions & 2 deletions book/en/src/by-example/new.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ $ rm memory.x build.rs
`timer-queue` feature.

``` console
$ cargo add cortex-m-rtfm
$ cargo add cortex-m-rtfm --allow-prerelease
```

4. Write your RTFM application.
Expand All @@ -49,7 +49,7 @@ Here I'll use the `init` example from the `cortex-m-rtfm` crate.

``` console
$ curl \
-L https://github.com/japaric/cortex-m-rtfm/raw/v0.4.0/examples/init.rs \
-L https://github.com/japaric/cortex-m-rtfm/raw/v0.5.0-alpha.1/examples/init.rs \
> src/main.rs
```

Expand Down
12 changes: 6 additions & 6 deletions book/en/src/by-example/resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ have enough information to optimize the access to the shared data.
The `app` attribute has a full view of the application thus it can optimize
access to `static` variables. In RTFM we refer to the `static` variables
declared inside the `app` pseudo-module as *resources*. To access a resource the
context (`init`, `idle`, `interrupt` or `exception`) must first declare the
context (`init`, `idle`, `interrupt` or `exception`) one must first declare the
resource in the `resources` argument of its attribute.

In the example below two interrupt handlers access the same resource. No `Mutex`
Expand All @@ -30,7 +30,7 @@ $ cargo run --example resource

The priority of each handler can be declared in the `interrupt` and `exception`
attributes. It's not possible to set the priority in any other way because the
runtime takes ownership of the `NVIC` peripheral; it's also not possible to
runtime takes ownership of the `NVIC` peripheral thus it's also not possible to
change the priority of a handler / task at runtime. Thanks to this restriction
the framework has knowledge about the *static* priorities of all interrupt and
exception handlers.
Expand Down Expand Up @@ -71,10 +71,10 @@ $ cargo run --example lock

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 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!
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!

## Late resources

Expand Down
26 changes: 0 additions & 26 deletions book/en/src/by-example/singletons.md

This file was deleted.

32 changes: 27 additions & 5 deletions book/en/src/by-example/tips.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ of tasks.

You can use conditional compilation (`#[cfg]`) on resources (`static [mut]`
items) and tasks (`fn` items). The effect of using `#[cfg]` attributes is that
the resource / task will *not* be injected into the prelude of tasks that use
them (see `resources`, `spawn` and `schedule`) if the condition doesn't hold.
the resource / task will *not* be available through the corresponding `Context`
`struct` if the condition doesn't hold.

The example below logs a message whenever the `foo` task is spawned, but only if
the program has been compiled using the `dev` profile.
Expand All @@ -37,7 +37,7 @@ the program has been compiled using the `dev` profile.
## Running tasks from RAM

The main goal of moving the specification of RTFM applications to attributes in
RTFM v0.4.x was to allow inter-operation with other attributes. For example, the
RTFM v0.4.0 was to allow inter-operation with other attributes. For example, the
`link_section` attribute can be applied to tasks to place them in RAM; this can
improve performance in some cases.

Expand Down Expand Up @@ -78,8 +78,6 @@ $ cargo nm --example ramfunc --release | grep ' bar::'

## `binds`

**NOTE**: Requires RTFM ~0.4.2

You can give hardware tasks more task-like names using the `binds` argument: you
name the function as you wish and specify the name of the interrupt / exception
in the `binds` argument. Types like `Spawn` will be placed in a module named
Expand All @@ -91,3 +89,27 @@ after the function, not the interrupt / exception. Example below:
``` console
$ cargo run --example binds
{{#include ../../../../ci/expected/binds.run}}```

## Indirection for faster message passing

Message passing always involves copying the payload from the sender into a
static variable and then from the static variable into the receiver. Thus
sending a large buffer, like a `[u8; 128]`, as a message involves two expensive
`memcpy`s. To minimize the message passing overhead one can use indirection:
instead of sending the buffer by value, one can send an owning pointer into the
buffer.

One can use a global allocator to achieve indirection (`alloc::Box`,
`alloc::Rc`, etc.), which requires using the nightly channel as of Rust v1.34.0,
or one can use a statically allocated memory pool like [`heapless::Pool`].

[`heapless::Pool`]: https://docs.rs/heapless/0.4.3/heapless/pool/index.html

Here's an example where `heapless::Pool` is used to "box" buffers of 128 bytes.

``` rust
{{#include ../../../../examples/pool.rs}}
```
``` console
$ cargo run --example binds
{{#include ../../../../ci/expected/pool.run}}```
3 changes: 1 addition & 2 deletions book/en/src/by-example/types-send-sync.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ write plain functions that take them as arguments.
The API reference specifies how these types are generated from the input. You
can also generate documentation for you binary crate (`cargo doc --bin <name>`);
in the documentation you'll find `Context` structs (e.g. `init::Context` and
`idle::Context`) whose fields represent the variables injected into each
function.
`idle::Context`).

The example below shows the different types generates by the `app` attribute.

Expand Down
3 changes: 3 additions & 0 deletions book/en/src/preface.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ There is a translation of this book in [Russian].

[Russian]: ../ru/index.html

**HEADS UP** This is an **alpha** pre-release; there may be breaking changes in
the API and semantics before a proper release is made.

{{#include ../../../README.md:5:46}}

{{#include ../../../README.md:52:}}
3 changes: 2 additions & 1 deletion ci/after-success.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ main() {
./ghp-import/ghp_import.py $td

set +x
git push -fq https://$GH_TOKEN@github.com/$TRAVIS_REPO_SLUG.git gh-pages && echo OK
# NOTE push documentation to a different repository
git push -fq https://$GH_TOKEN@github.com/japaric/rtfm5.git gh-pages && echo OK

rm -rf $td
}
Expand Down
2 changes: 2 additions & 0 deletions ci/expected/pool.run
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bar(0x2000008c)
foo(0x20000110)
36 changes: 27 additions & 9 deletions ci/script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,13 @@ main() {
message
capacity

singleton

types
not-send
not-sync
shared-with-init

generics
pool
ramfunc
)

Expand All @@ -121,6 +120,31 @@ main() {
continue
fi

if [ $ex = pool ]; then
if [ $TARGET != thumbv6m-none-eabi ]; then
local td=$(mktemp -d)

local features="$nightly,timer-queue"
cargo run --example $ex --target $TARGET --features $features >\
$td/pool.run
grep 'foo(0x2' $td/pool.run
grep 'bar(0x2' $td/pool.run
arm-none-eabi-objcopy -O ihex target/$TARGET/debug/examples/$ex \
ci/builds/${ex}_${features/,/_}_debug_1.hex

cargo run --example $ex --target $TARGET --features $features --release >\
$td/pool.run
grep 'foo(0x2' $td/pool.run
grep 'bar(0x2' $td/pool.run
arm-none-eabi-objcopy -O ihex target/$TARGET/release/examples/$ex \
ci/builds/${ex}_${features/,/_}_release_1.hex

rm -rf $td
fi

continue
fi

if [ $ex != types ]; then
arm_example "run" $ex "debug" "$nightly" "1"
arm_example "run" $ex "release" "$nightly" "1"
Expand All @@ -140,13 +164,7 @@ main() {
continue
fi

if [ $ex = singleton ]; then
# singleton build is currently not reproducible due to
# https://github.com/japaric/owned-singleton/issues/2
continue
fi

if [ $ex != types ]; then
if [ $ex != types ] && [ $ex != pool ]; then
arm_example "build" $ex "debug" "$nightly" "2"
cmp ci/builds/${ex}_${nightly/nightly/nightly_}debug_1.hex \
ci/builds/${ex}_${nightly/nightly/nightly_}debug_2.hex
Expand Down

0 comments on commit bc024f1

Please sign in to comment.