rust-embedded / embedded-hal

A Hardware Abstraction Layer (HAL) for embedded systems
Apache License 2.0
1.86k stars 185 forks source link

embedded-hal-bus no longer builds with target thumbv6m-none-eabi #598

Open Tschrock opened 2 months ago

Tschrock commented 2 months ago

Added embedded-hal-bus = "0.2.0" to my project and it failed to build. Using target thumbv7m-none-eabi works, using target thumbv6m-none-eabi fails. Version 0.1.0 works.

Trying to build the latest master branch:

./embedded-hal-bus> cargo build --target thumbv6m-none-eabi
   Compiling embedded-hal v1.0.0 (/home/cyber/Documents/VSCode/embedded-hal/embedded-hal)
   Compiling portable-atomic v1.6.0
   Compiling embedded-io-adapters v0.6.1 (/home/cyber/Documents/VSCode/embedded-hal/embedded-io-adapters)
   Compiling embedded-io-async v0.6.1 (/home/cyber/Documents/VSCode/embedded-hal/embedded-io-async)
   Compiling embedded-hal-async v1.0.0 (/home/cyber/Documents/VSCode/embedded-hal/embedded-hal-async)
   Compiling nb v1.1.0
   Compiling embedded-io v0.6.1 (/home/cyber/Documents/VSCode/embedded-hal/embedded-io)
   Compiling embedded-hal-bus v0.2.0 (/home/cyber/Documents/VSCode/embedded-hal/embedded-hal-bus)
   Compiling critical-section v1.1.2
   Compiling embedded-can v0.4.1 (/home/cyber/Documents/VSCode/embedded-hal/embedded-can)
   Compiling embedded-hal-nb v1.0.0 (/home/cyber/Documents/VSCode/embedded-hal/embedded-hal-nb)
error[E0599]: no method named `compare_exchange` found for struct `portable_atomic::AtomicBool` in the current scope
   --> embedded-hal-bus/src/i2c/atomic.rs:122:14
    |
120 | /         self.bus
121 | |             .busy
122 | |             .compare_exchange(
    | |             -^^^^^^^^^^^^^^^^ method not found in `AtomicBool`
    | |_____________|
    | 

error[E0599]: no method named `compare_exchange` found for struct `portable_atomic::AtomicBool` in the current scope
   --> embedded-hal-bus/src/spi/atomic.rs:127:14
    |
125 | /         self.bus
126 | |             .busy
127 | |             .compare_exchange(
    | |             -^^^^^^^^^^^^^^^^ method not found in `AtomicBool`
    | |_____________|
    | 

For more information about this error, try `rustc --explain E0599`.
error: could not compile `embedded-hal-bus` (lib) due to 2 previous errors

Seems to be caused by #593

https://github.com/rust-embedded/embedded-hal/blob/a0ccb6579669804e9be723912ed645a16362c8a6/embedded-hal-bus/src/spi/atomic.rs#L125-L133

https://github.com/rust-embedded/embedded-hal/blob/a0ccb6579669804e9be723912ed645a16362c8a6/embedded-hal-bus/src/i2c/atomic.rs#L120-L128

ARMv6-M does not have atomic CAS, so portable_atomic does not implement AtomicBool::compare_exchange on this target.

Rahix commented 2 months ago

I guess the most straight forward solution to fix this regression would be to add a feature-flag for AtomicDevice. We did the same thing back in shared-bus to cater for platforms without the necessary atomics support.

Another solution would be to allow using AtomicDevice on single-core microcontrollers by use of critical sections instead of real atomics. Not sure how best to expose this API-wise, though.

Rahix commented 2 months ago

Also, maybe a lesson learned from this regression could be that we need to set up CI infrastructure in embedded-hal to check builds on all relevant targets? There may be more subtle incompatibilities between platforms that could hit in this way, I think.

dan-corneanu commented 2 months ago

I have stumbled upon this issue right now. Is there any workaround for the time being?

adamgreig commented 2 months ago

Because AtomicDevice uses the portable-atomic crate, you can enable support for CAS on targets that don't normally have it with either the critical-section or unsafe-assume-single-core features: https://crates.io/crates/portable-atomic#optional-features-critical-section

Having to add an explicit dependency on portable-atomic and enable the feature just to get this crate to build isn't great, but it should work as a workaround now.

adamgreig commented 1 month ago

We discussed this in today's meeting and the plan is: