Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hot take: the way avr-hal uses features is frustrating #602

Open
innermatrix opened this issue Nov 17, 2024 · 5 comments
Open

Hot take: the way avr-hal uses features is frustrating #602

innermatrix opened this issue Nov 17, 2024 · 5 comments

Comments

@innermatrix
Copy link

innermatrix commented Nov 17, 2024

As I am sure you know, the recommended way to use features is to make them additive, and to avoid mutually exclusive features. However, avr-hal relies heavily on non-additive mutually exclusive features. I find this to be a pain.

This setup works great as long as you are building a crate that generates one executable for one board. It doesn't work great if you are

  • writing a library on top of avr-hal, because it forces the library into the same disrecommended mutually-exclusive feature behavior.
  • writing a crate that outputs multiple executables for different MCUs

The core issue — as I see it — is not that avr-hal is using features, it's the way it's using them. Specifically, avr-hal has some symbols whose implementation is selected mutually-exclusively using a feature — for example, Pins in atmega-hal. The fact that atmega-hal supports multiple MCUs, but can only ever export one Pins symbol, is at the root of the conflict.

IMO a better way to manage this would be to use features as they are intended: a feature flag selects whether a piece of functionality is included in the library, but allows multiple features to be selected. For example, I should be able to select both atmega32u4 and atmega328 features — and if I do, instead of them fighting over who gets to control the global Pins symbol, I should get both atmega32u4::Pins and atmega328::Pins symbols.

Taking this all the way up to the board level, what this would mean is that I would be able to use arduino-hal.features = ["atmega32u4", "atmega328"] when importing arduino-hal— which would indicate that I want arduino-hal to include support for both of those MCUs (using features additively, as they were intended) — and then in my main.rs I would write

#[cfg(any(feature = "atmega328"))]
use arduino_hal::atmega328 as board;

#[cfg(any(feature = "atmega32u4"))]
use arduino_hal::atmega32u4 as board;

I think this would completely eliminate all the shenanigans with mutually-exclusive features, and simplify the experience for anyone trying to use avr-hal in a non-trivial way.

Thoughts?

@stappersg
Copy link
Contributor

stappersg commented Nov 18, 2024 via email

@innermatrix
Copy link
Author

@stappersg I have started this work in #603

That PR only changes the feature-specific pins! macros in attiny-hal and atmega-hal. I have follow-on PRs that I already started working on for refactoring other aspects — you can see the current PR stack at innermatrix#1 (comment).

My current overall plan is:

  • Maintain the current behavior (with conflicting MCU-specific or board-specific globals) behind a feature flag (named deprecated-globals)
  • Enhance each crate so that if deprecated-globals is off the crate can be built to support any number of MCUs/boards

After I am done with that we can figure out what the plan is for if/when to fully remove the deprecated-globals functionality; that would be a breaking change, and I would leave decisions about that up to the maintainers. Up until that point I plan to maintain backwards compatibility.

I am structuring this as a PR stack, of which the PR above is the first. The full PR stack is linked in #603 if you want to peek ahead to where I am going with this and offer early feedback, but you can also ignore it for now if you prefer 🙂 If there is some other structure you'd prefer for this work, let me know.

@stappersg
Copy link
Contributor

stappersg commented Nov 21, 2024 via email

@innermatrix
Copy link
Author

innermatrix commented Nov 24, 2024

Alrighty, I have a coherent plan and will soon be sending along some PRs that put this into place.

  • v0.1.x: current version
  • v0.2.x: PRs ready
  • v0.3.x: PR ready (Turn off deprecated globals by default in attiny_hal, atmega_hal, and arduino_hal #612)
    • Changes: deprecated-globals turned off by default.
    • Impact on current users of the crate
      • Compiler errors if they are using deprecated globals and haven't added deprecated-globals to dependency features
      • Required changes:
        • Preferred: replace attiny_hal::Pins with use attiny_hal::attiny85 as hal; and hal::Pins and similar
        • Alternate: add deprecated-globals to dependency features, and continue with no code changes
  • v0.4.x: PR ready (Remove deprecated globals #613)
    • Changes: deprecated-globals removed
    • Impact on current users of the crate
      • Compiler errors if they are using deprecated globals
      • Required changes: replace attiny_hal::Pins with use attiny_hal::attiny85 as hal; and hal::Pins and similar

@innermatrix
Copy link
Author

@stappersg Hi again! I just put up my remaining PRs for this refactor, and updated the thread to reflect that. See above for more details; the TLDR is

  1. Crates v0.2: add opt-in ability to build without conflicting globals (Refactored attiny_hal for additive features #605, Refactored atmega_hal for additive features #606, Refactored arduino_hal for additive features #611)
  2. Crates v0.3: change conflicting globals to opt-out (Turn off deprecated globals by default in attiny_hal, atmega_hal, and arduino_hal #612)
  3. Crates v0.4: remove conflicting globals (Remove deprecated globals #613)

When you are able to, I would appreciate a review — these PRs (and especially the first three) had to move a lot of code around and therefore will end up having a lot of conflicts with other WIP. I will happily that on the responsibility to resolve those conflicts in order to get this work incorporated, but I am hoping to avoid doing that maintenance for an extended period of time. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants