Skip to content

Commit f8c79fe

Browse files
authored
Merge pull request #555 from Dirbaio/migration-giude
Release v1.0.0
2 parents 0dec059 + 11c8b9e commit f8c79fe

File tree

13 files changed

+202
-67
lines changed

13 files changed

+202
-67
lines changed

.github/workflows/test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ jobs:
4545
- uses: dtolnay/[email protected]
4646
- run: >
4747
cargo test
48-
-p embedded-hal:1.0.0-rc.3
48+
-p embedded-hal:1.0.0
4949
-p embedded-hal-bus
5050
-p embedded-hal-nb
5151
-p embedded-io

README.md

+4-15
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
55
This project is developed and maintained by the [HAL team](https://github.com/rust-embedded/wg#the-hal-team).
66

7+
> [!IMPORTANT]
8+
> 📣 `embedded-hal` v1.0 is now released! Check out the [announcement blog post](https://blog.rust-embedded.org/embedded-hal-v1/), the [API documentation](https://docs.rs/embedded-hal) and the [migration guide](docs/migrating-from-0.2-to-1.0.md).
9+
710
## Scope
811

912
`embedded-hal` serves as a foundation for building an ecosystem of platform-agnostic drivers.
@@ -38,24 +41,10 @@ The main `embedded-hal` project is not tied to a specific execution model like
3841
| [embedded-io-async](./embedded-io-async) | [![crates.io](https://img.shields.io/crates/v/embedded-io-async.svg)](https://crates.io/crates/embedded-io-async) | [![Documentation](https://docs.rs/embedded-io-async/badge.svg)](https://docs.rs/embedded-io-async) | I/O traits, async version |
3942
| [embedded-io-adapters](./embedded-io-adapters) | [![crates.io](https://img.shields.io/crates/v/embedded-io-adapters.svg)](https://crates.io/crates/embedded-io-adapters) | [![Documentation](https://docs.rs/embedded-io-adapters/badge.svg)](https://docs.rs/embedded-io-adapters) | Adapters between the [`embedded-io`](https://crates.io/crates/embedded-io) and [`embedded-io-async`](https://crates.io/crates/embedded-io-async) traits and other IO traits (`std`, `tokio`, `futures`...) |
4043

41-
## Releases
42-
43-
At the moment we are working towards a `1.0.0` release (see [#177]). During this process we will
44-
release alpha versions like `1.0.0-alpha.1` and `1.0.0-alpha.2`.
45-
Alpha releases are **not guaranteed** to be compatible with each other.
46-
They are provided as early previews for community testing and preparation for the final release.
47-
If you use an alpha release, we recommend you choose an exact version specification in your
48-
`Cargo.toml` like: `embedded-hal = "=1.0.0-alpha.9"`
49-
50-
See [this guide](docs/version-policy.md) for a way to implement both an `embedded-hal` `0.2.x`
51-
version and an `-alpha` version side by side in a HAL.
52-
53-
[#177]: https://github.com/rust-embedded/embedded-hal/issues/177
54-
5544
## Documents
5645

46+
- [Migrating from v0.2 to v1.0](docs/migrating-from-0.2-to-1.0.md).
5747
- [How-to: add a new trait](docs/how-to-add-a-new-trait.md)
58-
- [Version policy](docs/version-policy.md)
5948
- [MSRV](docs/msrv.md)
6049

6150
## Implementations and drivers

MIGRATING-0.2-1.0.md renamed to docs/migrating-from-0.2-to-1.0.md

+163-11
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@
1515
- [Fallibility](#fallibility)
1616
- [SPI transfer return type](#spi-transfer-return-type)
1717
- [Error type bounds](#error-type-bounds)
18+
- [GPIO traits now require `&mut self`](#gpio-traits-now-require-mut-self)
1819
- [Prelude](#prelude)
1920
- [Removed blanket implementations](#removed-blanket-implementations)
2021
- [Cargo Features](#cargo-features)
2122
- [Companion crates](#companion-crates)
23+
- [Supporting both 0.2 and 1.0 in the same HAL](#supporting-both-02-and-10-in-the-same-hal)
24+
- [`embedded-hal-compat`](#embedded-hal-compat)
2225

2326
## Overview and reasoning
2427

@@ -41,7 +44,7 @@ For `embedded-hal` 1.0, we decided to drop the first goal, targeting only the se
4144
- The second goal delivers much more value. Being able to use any driver together with any HAL crate, out of the box, and across the entire Rust Embedded ecosystem, is just plain awesome.
4245

4346
This refocusing on drivers is the root cause of many of the changes between `embedded-hal` 0.2 and 1.0:
44-
- [Associated type compatibiilty](#removed-traits)
47+
- [Associated type compatibility](#removed-traits)
4548
- [Trait fragmentation](#trait-organization)
4649
- [Bus/device separation](#bus-device-separation)
4750
- [Fallibility](#fallibility)
@@ -91,7 +94,7 @@ These traits have been removed in the 1.0.0 release, with no replacement for now
9194
- [`watchdog::Watchdog`][watchdog]
9295

9396
Please find a general [roadmap with further guidance here][roadmap-rm-traits] about
94-
whether and how to get these traits back in a future release
97+
whether and how to get these traits back in a future release.
9598

9699
If you are a generic driver author and need one of them, we would like to hear from you. Please add your use case to the appropriate issue for the trait affected.
97100

@@ -328,6 +331,95 @@ fn set_some_parameter(&mut self) -> Result<(), Self::Error> {
328331
}
329332
```
330333

334+
## GPIO traits now require `&mut self`
335+
336+
Methods on `InputPin` and `State` now take `&mut self` instead of `&self`, to allow implementations to
337+
have mutable state or access exclusive resources.
338+
339+
**For HAL implementors**: You should not need to do any changes, since `&mut self` is strictly more permissive
340+
for implementations.
341+
342+
For ease of use, you might want to provide inherent methods that take `&self` if the hardware permits it. In this case,
343+
you might need to do `&*self` to call them from the trait methods. Otherwise Rust will resolve the
344+
method call to the trait method, causing infinite recursion.
345+
346+
```rust
347+
struct HalPin;
348+
349+
impl HalPin {
350+
fn is_high(&self) -> bool {
351+
true
352+
}
353+
354+
fn is_low(&self) -> bool {
355+
true
356+
}
357+
}
358+
359+
impl InputPin for HalPin {
360+
fn is_high(&mut self) -> Result<bool, Self::Error> {
361+
// Needs `&*self` so that the inherent `is_high` is picked.
362+
Ok((&*self).is_high())
363+
}
364+
365+
fn is_low(&mut self) -> Result<bool, Self::Error> {
366+
Ok((&*self).is_low())
367+
}
368+
}
369+
```
370+
371+
**For driver authors**: If your driver does not need sharing input pins, you should be able to upgrade without any changes.
372+
If you do need to share input pins, the recommended solution is wrapping them with a `RefCell`.
373+
374+
Note that if you need to share multiple objects, you should prefer using a single `RefCell` wherever possible to reduce RAM
375+
usage. Make an "inner" struct with all the objects that need sharing, and wrap it in a single `RefCell`. Below is an example
376+
skeleton of a keypad driver using row/column multiplexing, sharing multiple `InputPin`s and `OutputPin`s with a single `RefCell`:
377+
378+
```rust
379+
use core::cell::RefCell;
380+
381+
use embedded_hal::digital::{ErrorType, InputPin, OutputPin};
382+
383+
pub struct Keypad<O: OutputPin, I: InputPin, const NCOLS: usize, const NROWS: usize> {
384+
inner: RefCell<KeypadInner<O, I, NCOLS, NROWS>>,
385+
}
386+
387+
struct KeypadInner<O: OutputPin, I: InputPin, const NCOLS: usize, const NROWS: usize> {
388+
cols: [O; NCOLS],
389+
rows: [I; NROWS],
390+
}
391+
392+
pub struct KeypadInput<'a, O: OutputPin, I: InputPin, const NCOLS: usize, const NROWS: usize> {
393+
inner: &'a RefCell<KeypadInner<O, I, NCOLS, NROWS>>,
394+
row: usize,
395+
col: usize,
396+
}
397+
398+
impl<'a, O: OutputPin, I: InputPin, const NCOLS: usize, const NROWS: usize> ErrorType for KeypadInput<'a, O, I, NCOLS, NROWS> {
399+
type Error = core::convert::Infallible;
400+
}
401+
402+
impl<'a, O: OutputPin, I: InputPin, const NCOLS: usize, const NROWS: usize> InputPin for KeypadInput<'a, O, I, NCOLS, NROWS> {
403+
fn is_high(&mut self) -> Result<bool, Self::Error> {
404+
Ok(!self.is_low()?)
405+
}
406+
407+
fn is_low(&mut self) -> Result<bool, Self::Error> {
408+
let inner = &mut *self.inner.borrow_mut();
409+
let row = &mut inner.rows[self.row];
410+
let col = &mut inner.cols[self.col];
411+
412+
// using unwrap for demo purposes, you should propagate errors up instead.
413+
col.set_low().unwrap();
414+
let out = row.is_low().unwrap();
415+
col.set_high().unwrap();
416+
417+
Ok(out)
418+
}
419+
}
420+
```
421+
422+
331423
## Prelude
332424

333425
The prelude has been removed because it could make method calls ambiguous, since the method names are now
@@ -359,16 +451,76 @@ experiment externally, and merge when some kind of feasibility had been proven.
359451

360452
## Companion crates
361453

362-
The `embedded-hal` project now spans several crates, where some functionality has been moved out from the main `embedded-hal` crate to separate crates as detailed above. Here is the full listing of crates:
454+
The `embedded-hal` project now spans several crates, where some functionality has been moved out from the main `embedded-hal` crate to separate crates as detailed above.
455+
456+
Different crates are released independently. The main `embedded-hal-*` trait crates have reached 1.0 maturity, others will become 1.0 as time passes.
457+
458+
Here is the full listing of crates:
363459

364460
| Crate | crates.io | Docs | |
365461
|-|-|-|-|
366-
| [embedded-hal](./embedded-hal) | [![crates.io](https://img.shields.io/crates/v/embedded-hal.svg)](https://crates.io/crates/embedded-hal) | [![Documentation](https://docs.rs/embedded-hal/badge.svg)](https://docs.rs/embedded-hal) | Core traits, blocking version |
367-
| [embedded-hal-async](./embedded-hal-async) | [![crates.io](https://img.shields.io/crates/v/embedded-hal-async.svg)](https://crates.io/crates/embedded-hal-async) | [![Documentation](https://docs.rs/embedded-hal-async/badge.svg)](https://docs.rs/embedded-hal-async) | Core traits, async version |
368-
| [embedded-hal-nb](./embedded-hal-nb) | [![crates.io](https://img.shields.io/crates/v/embedded-hal-nb.svg)](https://crates.io/crates/embedded-hal-nb) | [![Documentation](https://docs.rs/embedded-hal-nb/badge.svg)](https://docs.rs/embedded-hal-nb) | Core traits, polling version using the `nb` crate |
369-
| [embedded-hal-bus](./embedded-hal-bus) | [![crates.io](https://img.shields.io/crates/v/embedded-hal-bus.svg)](https://crates.io/crates/embedded-hal-bus) | [![Documentation](https://docs.rs/embedded-hal-bus/badge.svg)](https://docs.rs/embedded-hal-bus) | Utilities for sharing SPI and I2C buses |
370-
| [embedded-can](./embedded-can) | [![crates.io](https://img.shields.io/crates/v/embedded-can.svg)](https://crates.io/crates/embedded-can) | [![Documentation](https://docs.rs/embedded-can/badge.svg)](https://docs.rs/embedded-can) | Controller Area Network (CAN) traits |
371-
| [embedded-io](./embedded-io) | [![crates.io](https://img.shields.io/crates/v/embedded-io.svg)](https://crates.io/crates/embedded-io) | [![Documentation](https://docs.rs/embedded-io/badge.svg)](https://docs.rs/embedded-io) | I/O traits (read, write, seek, etc.), blocking and nonblocking version. |
372-
| [embedded-io-async](./embedded-io-async) | [![crates.io](https://img.shields.io/crates/v/embedded-io-async.svg)](https://crates.io/crates/embedded-io-async) | [![Documentation](https://docs.rs/embedded-io-async/badge.svg)](https://docs.rs/embedded-io-async) | I/O traits, async version |
373-
| [embedded-io-adapters](./embedded-io-adapters) | [![crates.io](https://img.shields.io/crates/v/embedded-io-adapters.svg)](https://crates.io/crates/embedded-io-adapters) | [![Documentation](https://docs.rs/embedded-io-adapters/badge.svg)](https://docs.rs/embedded-io-adapters) | Adapters between the [`embedded-io`](https://crates.io/crates/embedded-io) and [`embedded-io-async`](https://crates.io/crates/embedded-io-async) traits and other IO traits (`std`, `tokio`, `futures`...) |
462+
| [embedded-hal](../embedded-hal) | [![crates.io](https://img.shields.io/crates/v/embedded-hal.svg)](https://crates.io/crates/embedded-hal) | [![Documentation](https://docs.rs/embedded-hal/badge.svg)](https://docs.rs/embedded-hal) | Core traits, blocking version |
463+
| [embedded-hal-async](../embedded-hal-async) | [![crates.io](https://img.shields.io/crates/v/embedded-hal-async.svg)](https://crates.io/crates/embedded-hal-async) | [![Documentation](https://docs.rs/embedded-hal-async/badge.svg)](https://docs.rs/embedded-hal-async) | Core traits, async version |
464+
| [embedded-hal-nb](../embedded-hal-nb) | [![crates.io](https://img.shields.io/crates/v/embedded-hal-nb.svg)](https://crates.io/crates/embedded-hal-nb) | [![Documentation](https://docs.rs/embedded-hal-nb/badge.svg)](https://docs.rs/embedded-hal-nb) | Core traits, polling version using the `nb` crate |
465+
| [embedded-hal-bus](../embedded-hal-bus) | [![crates.io](https://img.shields.io/crates/v/embedded-hal-bus.svg)](https://crates.io/crates/embedded-hal-bus) | [![Documentation](https://docs.rs/embedded-hal-bus/badge.svg)](https://docs.rs/embedded-hal-bus) | Utilities for sharing SPI and I2C buses |
466+
| [embedded-can](../embedded-can) | [![crates.io](https://img.shields.io/crates/v/embedded-can.svg)](https://crates.io/crates/embedded-can) | [![Documentation](https://docs.rs/embedded-can/badge.svg)](https://docs.rs/embedded-can) | Controller Area Network (CAN) traits |
467+
| [embedded-io](../embedded-io) | [![crates.io](https://img.shields.io/crates/v/embedded-io.svg)](https://crates.io/crates/embedded-io) | [![Documentation](https://docs.rs/embedded-io/badge.svg)](https://docs.rs/embedded-io) | I/O traits (read, write, seek, etc.), blocking and nonblocking version. |
468+
| [embedded-io-async](../embedded-io-async) | [![crates.io](https://img.shields.io/crates/v/embedded-io-async.svg)](https://crates.io/crates/embedded-io-async) | [![Documentation](https://docs.rs/embedded-io-async/badge.svg)](https://docs.rs/embedded-io-async) | I/O traits, async version |
469+
| [embedded-io-adapters](../embedded-io-adapters) | [![crates.io](https://img.shields.io/crates/v/embedded-io-adapters.svg)](https://crates.io/crates/embedded-io-adapters) | [![Documentation](https://docs.rs/embedded-io-adapters/badge.svg)](https://docs.rs/embedded-io-adapters) | Adapters between the [`embedded-io`](https://crates.io/crates/embedded-io) and [`embedded-io-async`](https://crates.io/crates/embedded-io-async) traits and other IO traits (`std`, `tokio`, `futures`...) |
470+
471+
## Supporting both 0.2 and 1.0 in the same HAL
472+
473+
It is strongly recommended that HAL implementation crates provide implementations for both the `embedded-hal` v0.2 and v1.0 traits.
474+
This allows users to use drivers using either version seamlessly.
475+
476+
The way you do it is adding a dependency on both versions in `Cargo.toml` like this:
477+
478+
```toml
479+
[dependencies]
480+
embedded-hal-02 = { package = "embedded-hal", version = "0.2.7", features = ["unproven"] }
481+
embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
482+
```
483+
484+
This allows you to refer to the v0.2 traits under the `embedded_hal_02` name, and the v1.0 traits under
485+
`embedded_hal_1`. Implement both versions on the same struct. For example, for an input pin:
486+
487+
```rust
488+
/// The HAL's input pin struct
489+
struct Input {...}
490+
491+
/// Implement the v0.2 traits on the struct.
492+
impl embedded_hal_02::digital::v2::InputPin for Input {
493+
type Error = Infallible;
494+
495+
fn is_high(&self) -> Result<bool, Self::Error> {
496+
...
497+
}
498+
499+
fn is_low(&self) -> Result<bool, Self::Error> {
500+
...
501+
}
502+
}
503+
504+
/// ... and implement the v1.0 traits on the *same* struct.
505+
impl embedded_hal_1::digital::ErrorType for Input {
506+
type Error = Infallible;
507+
}
508+
509+
impl embedded_hal_1::digital::InputPin for Input {
510+
fn is_high(&mut self) -> Result<bool, Self::Error> {
511+
...
512+
}
513+
514+
fn is_low(&mut self) -> Result<bool, Self::Error> {
515+
...
516+
}
517+
}
518+
```
519+
520+
## `embedded-hal-compat`
521+
522+
For HAL implementation crates that haven't been updated yet, [embedded-hal-compat](https://github.com/ryankurte/embedded-hal-compat)
523+
provides shims to support interoperability between `embedded-hal` v0.2 and v1.0.
374524

525+
This allows using a driver requiring v1.0 with a HAL crate implementing only v0.2 or vice-versa, (generally) without alteration.
526+
See the [docs](https://docs.rs/embedded-hal-compat/) for examples.

docs/version-policy.md

-26
This file was deleted.

embedded-hal-async/CHANGELOG.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10-
No unreleased changes
10+
No unreleased changes yet.
11+
12+
## [v1.0.0] - 2023-12-28
13+
14+
- Updated `embedded-hal` to version `1.0.0`.
1115

1216
## [v1.0.0-rc.3] - 2023-12-14
1317

@@ -86,7 +90,8 @@ No unreleased changes
8690
First release to crates.io
8791

8892

89-
[Unreleased]: https://github.com/rust-embedded/embedded-hal/compare/embedded-hal-async-v1.0.0-rc.3...HEAD
93+
[Unreleased]: https://github.com/rust-embedded/embedded-hal/compare/embedded-hal-async-v1.0.0...HEAD
94+
[v1.0.0]: https://github.com/rust-embedded/embedded-hal/compare/embedded-hal-async-v1.0.0-rc.3...embedded-hal-async-v1.0.0
9095
[v1.0.0-rc.3]: https://github.com/rust-embedded/embedded-hal/compare/embedded-hal-async-v1.0.0-rc.2...embedded-hal-async-v1.0.0-rc.3
9196
[v1.0.0-rc.2]: https://github.com/rust-embedded/embedded-hal/compare/embedded-hal-async-v1.0.0-rc.1...embedded-hal-async-v1.0.0-rc.2
9297
[v1.0.0-rc.1]: https://github.com/rust-embedded/embedded-hal/compare/embedded-hal-async-v0.2.0-alpha.2...embedded-hal-async-v1.0.0-rc.1

embedded-hal-async/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ license = "MIT OR Apache-2.0"
1111
name = "embedded-hal-async"
1212
readme = "README.md"
1313
repository = "https://github.com/rust-embedded/embedded-hal"
14-
version = "1.0.0-rc.3"
14+
version = "1.0.0"
1515
rust-version = "1.75"
1616

1717
[features]
1818
defmt-03 = ["dep:defmt-03", "embedded-hal/defmt-03"]
1919

2020
[dependencies]
21-
embedded-hal = { version = "=1.0.0-rc.3", path = "../embedded-hal" }
21+
embedded-hal = { version = "1.0.0", path = "../embedded-hal" }
2222
defmt-03 = { package = "defmt", version = "0.3", optional = true }

embedded-hal-bus/CHANGELOG.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
99

1010
No unreleased changes
1111

12+
## [v0.1.0] - 2023-12-28
13+
14+
- Updated `embedded-hal` to version `1.0.0`.
15+
1216
## [v0.1.0-rc.3] - 2023-12-14
1317

1418
- Updated `embedded-hal` to version `1.0.0-rc.3`.
@@ -52,7 +56,8 @@ No unreleased changes
5256

5357
First release to crates.io
5458

55-
[Unreleased]: https://github.com/rust-embedded/embedded-hal/compare/embedded-hal-bus-v0.1.0-rc.3...HEAD
59+
[Unreleased]: https://github.com/rust-embedded/embedded-hal/compare/embedded-hal-bus-v0.1.0...HEAD
60+
[v0.1.0]: https://github.com/rust-embedded/embedded-hal/compare/embedded-hal-bus-v0.1.0-rc.3...embedded-hal-bus-v0.1.0
5661
[v0.1.0-rc.3]: https://github.com/rust-embedded/embedded-hal/compare/embedded-hal-bus-v0.1.0-rc.2...embedded-hal-bus-v0.1.0-rc.3
5762
[v0.1.0-rc.2]: https://github.com/rust-embedded/embedded-hal/compare/embedded-hal-bus-v0.1.0-rc.1...embedded-hal-bus-v0.1.0-rc.2
5863
[v0.1.0-rc.1]: https://github.com/rust-embedded/embedded-hal/compare/embedded-hal-bus-v0.1.0-alpha.3...embedded-hal-bus-v0.1.0-rc.1

embedded-hal-bus/Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@ license = "MIT OR Apache-2.0"
1212
name = "embedded-hal-bus"
1313
readme = "README.md"
1414
repository = "https://github.com/rust-embedded/embedded-hal"
15-
version = "0.1.0-rc.3"
15+
version = "0.1.0"
1616

1717
[features]
1818
std = []
1919
async = ["dep:embedded-hal-async"]
2020
defmt-03 = ["dep:defmt-03", "embedded-hal/defmt-03", "embedded-hal-async?/defmt-03"]
2121

2222
[dependencies]
23-
embedded-hal = { version = "=1.0.0-rc.3", path = "../embedded-hal" }
24-
embedded-hal-async = { version = "=1.0.0-rc.3", path = "../embedded-hal-async", optional = true }
23+
embedded-hal = { version = "1.0.0", path = "../embedded-hal" }
24+
embedded-hal-async = { version = "1.0.0", path = "../embedded-hal-async", optional = true }
2525
critical-section = { version = "1.0" }
2626
defmt-03 = { package = "defmt", version = "0.3", optional = true }
2727

0 commit comments

Comments
 (0)