|
| 1 | +# Cortex-M library development now possible on beta and the path towards stable embedded Rust |
| 2 | + |
| 3 | +> 2018-05-13 |
| 4 | +
|
| 5 | +> **TL;DR** |
| 6 | +> |
| 7 | +> * 1.27 = embedded (Cortex-M) *library* development on stable |
| 8 | +> * 1.28 or 1.29 = embedded (Cortex-M) *application* development on stable |
| 9 | +> * We are making breaking changes in the ecosystem in order to move towards development on the |
| 10 | +> stable channel |
| 11 | +> * If you are a crate maintainer / author, make sure you test your crates with the new versions of |
| 12 | +> `cortex-m` (and similar) on the current `beta` release of Rust |
| 13 | +> * If the latest version of a dependency doesn't compile on `beta`, file an issue and/or ping us on |
| 14 | +> the #rust-embedded IRC channel |
| 15 | +> * Thanks for your patience! |
| 16 | +
|
| 17 | +We are happy to announce that *library* development for the Cortex-M targets is now possible on the |
| 18 | +beta channel! :tada: |
| 19 | + |
| 20 | +For example, to cross compile a library crate for the Cortex-M3 you would run these commands: |
| 21 | + |
| 22 | +``` console |
| 23 | +$ # switch to the beta channel |
| 24 | +$ rustup default beta |
| 25 | + |
| 26 | +$ # install the rust-std component (pre-compiled core) for the target |
| 27 | +$ rustup target add thumbv7m-none-eabi |
| 28 | + |
| 29 | +$ # get some source to build |
| 30 | +$ cargo clone cortex-m --vers 0.5.0 && cd cortex-m |
| 31 | + |
| 32 | +$ # then It Just Works |
| 33 | +$ cargo build --target thumbv7m-none-eabi |
| 34 | +``` |
| 35 | + |
| 36 | +What about embedded *application* development? There is just a single unstable feature that prevents |
| 37 | +us from building a `no_std` binary on stable: the `panic_fmt` lang item. This unstable feature will |
| 38 | +soon be removed in favor of the `#[panic_implementation]` feature ([implementation PR]), which is |
| 39 | +slated for stabilization in time for the edition release (we are hoping to stabilize it as early as |
| 40 | +1.28 but we'll see). |
| 41 | + |
| 42 | +[implementation PR]: https://github.com/rust-lang/rust/pull/50338 |
| 43 | + |
| 44 | +## Making the Cortex-M ecosystem work on stable |
| 45 | + |
| 46 | +"`no_std` binaries are *possible* on stable" is very different from "*my* embedded application |
| 47 | +builds on stable". The later requires all the dependencies to also compile on stable. So we are |
| 48 | +starting to migrate the Cortex-M ecosystem to work on stable. All the crates listed below are now |
| 49 | +compiling on the beta channel. |
| 50 | + |
| 51 | +Legend: `crate-name` - link to CHANGELOG - link to stabilization PR - ~removed unstable features~ |
| 52 | + |
| 53 | +- [`cortex-m-quickstart`][c0] - [CHANGELOG][ch0] - [PR][p0] |
| 54 | + |
| 55 | +[c0]: https://docs.rs/cortex-m-quickstart/~0.3 |
| 56 | +[ch0]: https://github.com/japaric/cortex-m-quickstart/blob/master/CHANGELOG.md#v030---2018-05-12 |
| 57 | +[p0]: https://github.com/japaric/cortex-m-quickstart/pull/29 |
| 58 | + |
| 59 | +- [`cortex-m-rt`][c1] - [CHANGELOG][ch1] - [PR][p1] - ~asm!~ ~core_intrinsics~ ~global_asm!~ |
| 60 | + ~lang_items~ ~linkage~ ~naked_functions~ ~used~ |
| 61 | + |
| 62 | +[c1]: https://crates.io/crates/cortex-m-rt/0.5.0 |
| 63 | +[ch1]: https://github.com/japaric/cortex-m-rt/blob/master/CHANGELOG.md#v050---2018-05-12 |
| 64 | +[p1]: https://github.com/japaric/cortex-m-rt/pull/69 |
| 65 | + |
| 66 | +- [`cortex-m-semihosting`][c2] - [CHANGELOG][ch2] - [PR][p2] |
| 67 | + |
| 68 | +[c2]: https://crates.io/crates/cortex-m-semihosting/0.3.0 |
| 69 | +[ch2]: https://github.com/japaric/cortex-m-semihosting/blob/master/CHANGELOG.md#v030---2018-05-10 |
| 70 | +[p2]: https://github.com/japaric/cortex-m-semihosting/pull/16 |
| 71 | + |
| 72 | +- [`cortex-m`][c3] - [CHANGELOG][ch3] - [PR][p3] - ~asm!~ ~const_fn~ |
| 73 | + |
| 74 | +[c3]: https://crates.io/crates/cortex-m/0.5.0 |
| 75 | +[ch3]: https://github.com/japaric/cortex-m/blob/master/CHANGELOG.md#v050---2018-05-11 |
| 76 | +[p3]: https://github.com/japaric/cortex-m/pull/88 |
| 77 | + |
| 78 | +- [`embedded-hal`][c4] - [CHANGELOG][ch4] - [PR][p4] - ~never_type~ |
| 79 | + |
| 80 | +[c4]: https://crates.io/crates/embedded-hal/0.2.0 |
| 81 | +[ch4]: https://github.com/japaric/embedded-hal/blob/master/CHANGELOG.md#v020---2018-05-12 |
| 82 | +[p4]: https://github.com/japaric/embedded-hal/pull/80 |
| 83 | + |
| 84 | +- [`f3`][c5] - [CHANGELOG][ch5] - [PR][p5] |
| 85 | + |
| 86 | +[c5]: https://crates.io/crates/f3/0.6.0 |
| 87 | +[ch5]: https://github.com/japaric/f3/blob/master/CHANGELOG.md#v060---2018-05-12 |
| 88 | +[p5]: https://github.com/japaric/f3/pull/93 |
| 89 | + |
| 90 | +- [`l3gd20`][c6] - [CHANGELOG][ch6] - [PR][p6] - ~Unsized~ |
| 91 | + |
| 92 | +[c6]: https://crates.io/crates/l3gd20/0.2.0 |
| 93 | +[ch6]: https://github.com/japaric/l3gd20/blob/master/CHANGELOG.md#v020---2018-05-12 |
| 94 | +[p6]: https://github.com/japaric/l3gd20/pull/4 |
| 95 | + |
| 96 | +- [`lsm303dlhc`][c7] - [CHANGELOG][ch7] - [PR][p7] - ~Unsized~ |
| 97 | + |
| 98 | +[c7]: https://crates.io/crates/lsm303dlhc/0.2.0 |
| 99 | +[ch7]: https://github.com/japaric/lsm303dlhc/blob/master/CHANGELOG.md#v020---2018-05-12 |
| 100 | +[p7]: https://github.com/japaric/lsm303dlhc/pull/4 |
| 101 | + |
| 102 | +- [`stm32f103xx`][c8] - [CHANGELOG][ch8] - [PR][p8] - ~const_fn~ ~global_asm!~ ~try_from~ |
| 103 | + ~use_extern_macros~ ~used~ |
| 104 | + |
| 105 | +[c8]: https://crates.io/crates/stm32f103xx/0.10.0 |
| 106 | +[ch8]: https://github.com/japaric/stm32f103xx/blob/master/CHANGELOG.md#v0100---2018-05-12 |
| 107 | +[p8]: https://github.com/japaric/stm32f103xx/pull/24 |
| 108 | + |
| 109 | +- [`stm32f30x-hal`][c9] - [CHANGELOG][ch9] - [PR][p9] - ~never_type~ |
| 110 | + |
| 111 | +[c9]: https://crates.io/crates/stm32f30x-hal/0.2.0 |
| 112 | +[ch9]: https://github.com/japaric/stm32f30x-hal/blob/master/CHANGELOG.md#v020---2018-05-12 |
| 113 | +[p9]: https://github.com/japaric/stm32f30x-hal/pull/25 |
| 114 | + |
| 115 | +- [`stm32f30x`][c10] - [CHANGELOG][ch10] - [PR][p10] - ~const_fn~ ~global_asm!~ ~try_from~ |
| 116 | + ~use_extern_macros~ ~used~ |
| 117 | + |
| 118 | +[c10]: https://crates.io/crates/stm32f30x/0.7.0 |
| 119 | +[ch10]: https://github.com/japaric/stm32f30x/blob/master/CHANGELOG.md#v070---2018-05-12 |
| 120 | +[p10]: https://github.com/japaric/stm32f30x/pull/16 |
| 121 | + |
| 122 | +- [`svd2rust`][c11] (output of) - [CHANGELOG][ch11] - [PR][p11] - ~const_fn~ ~global_asm!~ |
| 123 | + ~try_from~ ~use_extern_macros~ ~used~ |
| 124 | + |
| 125 | +[c11]: https://crates.io/crates/svd2rust/0.13.0 |
| 126 | +[ch11]: https://github.com/japaric/svd2rust/blob/master/CHANGELOG.md#v0130---2018-05-12 |
| 127 | +[p11]: https://github.com/japaric/svd2rust/pull/203 |
| 128 | + |
| 129 | +There's a lot of breaking changes there but the most visible one is `cortex-m-rt` because it changes |
| 130 | +how applications are structured. Check the [`cortex-m-quickstart`][c0] template for instructions on |
| 131 | +how to set up an embedded application using the latest versions of everything. |
| 132 | + |
| 133 | +There are still a lot of crates that will need to be updated to work on beta. Among the more general |
| 134 | +purpose ones we have [`heapless`] and [`cortex-m-rtfm`], which needs to be update to work with |
| 135 | +`cortex-m-rt` v0.5.0. |
| 136 | + |
| 137 | +[`heapless`]: https://crates.io/crates/heapless |
| 138 | +[`cortex-m-rtfm`]: https://crates.io/crates/cortex-m-rtfm |
| 139 | + |
| 140 | +### How you can help us |
| 141 | + |
| 142 | +Try to compile your Cortex-M crate using the beta channel! If your crate is an application the build |
| 143 | +will certainly fail, but check if all the dependencies, excluding the [panic handler crate][phc], |
| 144 | +compile on beta. If any dependency doesn't compile on the beta channel let the author know, but |
| 145 | +first check if there's a new version of the crate that already compiles on the beta channel. And if |
| 146 | +you feel up to the task you could even send a PR to the dependency to make it compile on beta -- the |
| 147 | +list of stabilization PRs in the previous section may give you a clue on how to move the crate to |
| 148 | +beta. |
| 149 | + |
| 150 | +If you are the author of a Cortex-M device crate, a crate generated using `svd2rust`, moving it to |
| 151 | +stable only requires regenerating it using `svd2rust` v0.13.0. Do note that the generation process |
| 152 | +[has changed] for the Cortex-M target; also make sure you bump the minor version when you publish a |
| 153 | +new version. |
| 154 | + |
| 155 | +[has changed]: https://docs.rs/svd2rust/0.13.0/svd2rust/#usage |
| 156 | + |
| 157 | +If you are the author of a driver crate or a HAL implementation, please update your crate to use |
| 158 | +v0.2.0 of `embedded-hal` and test that it builds on beta. Make sure you bump the minor version when |
| 159 | +you publish a new version of your crate -- bumping the version of the `embedded-hal` dependency is a |
| 160 | +breaking change (drivers that depend on `embedded-hal` v0.1.0 can't be used with HAL implementation |
| 161 | +crates that depend on `embedded-hal` v0.2.0). |
| 162 | + |
| 163 | +If you are porting an application to the newest `cortex-m-*` crates you may hit these errors: |
| 164 | + |
| 165 | +- "error: requires `start` lang_item" on binary crates. You need to switch from the standard `main` |
| 166 | + interface to `#![no_main]` + `entry!`. Use the [examples][qse] in the quickstart template as a |
| 167 | + reference. |
| 168 | + |
| 169 | +[qse]: https://docs.rs/cortex-m-quickstart/0.3.0/cortex_m_quickstart/examples/_0_minimal/index.html |
| 170 | + |
| 171 | +- "error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple |
| 172 | + variants". `const fn` is not a stable feature so it's not used in the API by default. The |
| 173 | + `cortex-m` provides a `"const-fn"` feature to opt into this unstable feature and expose `const` |
| 174 | + functions in the API; other dependencies should / probably provide a similar feature. |
| 175 | + |
| 176 | +## What does this all mean for you? |
| 177 | + |
| 178 | +To those of you who have been doing embedded development on nightly: things will get *much easier* |
| 179 | +from now on. We have reduced the number of unstable features in core crates of the Cortex-M |
| 180 | +ecosystem to **zero**. Although you will have to continue to use nightly for application development |
| 181 | +you can expect zero breakage from these crates when updating the nightly compiler. There is one |
| 182 | +expected breakage coming soon though: `panic_fmt` will be removed as announced above. This will |
| 183 | +break the [panic handler crates][phc]; however, the breakage will be isolated to those crates and |
| 184 | +the fix will consist of simply updating the dependency version. |
| 185 | + |
| 186 | +[phc]: https://crates.io/keywords/panic-impl |
| 187 | + |
| 188 | +To those of you who have been meaning to dive into embedded Rust development: we'll soon be done |
| 189 | +with our "embedded Rust on stable" tasks and we'll move our focus to documenting the embedded |
| 190 | +development process, tooling and ecosystem. The [embedded Rust book][book] will become the resource |
| 191 | +to get started on embedded Rust, but it doesn't quite exist right now. |
| 192 | + |
| 193 | +[book]: https://github.com/rust-lang-nursery/embedded-wg/blob/master/books/embedded-rust-book/README.md |
| 194 | + |
| 195 | +## What about architectures other than ARM Cortex-M? |
| 196 | + |
| 197 | +The path carved for ARM Cortex-M can be followed by the other architectures (ARM Cortex-R, AVR, |
| 198 | +MSP430, RISCV, etc.). Each architecture presents its own extra set of challenges though: |
| 199 | + |
| 200 | +- MSP430 being the second oldest embedded / `no_std` target is the closest one to make it to stable |
| 201 | + (as a tier 2 target) by the edition release. The main blocker is that `extern "msp430-interrupt"` |
| 202 | + is not available on stable but I think that may be possible to work around using external C / |
| 203 | + assembly files + FFI. |
| 204 | + |
| 205 | +- Both AVR and RISCV are blocked from being included in the Rust compiler due to either the |
| 206 | + immaturity of the LLVM backend or LLVM backend bugs. Not many (embedded) Rust developers can also |
| 207 | + hack LLVM backends so we are short handed on the AVR front; OTOH, the RISCV is being actively |
| 208 | + developed by third parties so it's probably just a matter of time before we add it to rustc. |
| 209 | + |
| 210 | +- ARM Cortex-R LLVM backend is probably in good shape due to the similarities between its |
| 211 | + instruction set and the ARM Cortex-M instruction set, so adding the target to the compiler should |
| 212 | + be straightforward. However, the crate ecosystem is nonexistent at this point so there's a lot of |
| 213 | + work to be done on that front. |
| 214 | + |
| 215 | +--- |
| 216 | + |
| 217 | +This work is part of the [embedded WG][ewg] effort towards [making embedded development possible on |
| 218 | +the stable channel][stable]. (We are almost done! :tada:) |
| 219 | + |
| 220 | +[ewg]: https://github.com/rust-lang-nursery/embedded-wg |
| 221 | +[stable]: https://github.com/rust-lang-nursery/embedded-wg |
0 commit comments