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

RTIC v2 RTC monotonic drivers #804

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

kyp44
Copy link
Contributor

@kyp44 kyp44 commented Dec 21, 2024

Summary

Adds RTC-based RTIC v2 monotonics drivers.

This addresses issue #765 and is the culmination of a lot of discussion there.

Note that it was decided along with the RTIC team that ATSAMD RTIC monotonics should be released as part of the HAL instead of in rtic-monotonics.

Note that this release of the monotonics is opinionated in the sense that only the best monotonic is provided for each chip variant. See the module documentation of rtc::rtic for details. For reference, the alternative of releasing two monotonics, one for each RTC mode, is preserved in the rtic-v2-rtc-monotonics-full branch. Compare the module documentation of rtc::rtic in that branch for details on why there is clearly a best choice for each chip variant.

Checklist

  • All new or modified code is well documented, especially public items
  • No new warnings or clippy suggestions have been introduced - CI will deny clippy warnings by default!

Dan Whitman and others added 9 commits December 11, 2024 14:43
… and macros, now uses type-level programming to specify the RTC clock source at compile time.
…lication in the HAL.

* Moves the two monotonics into their own files so that the `rtc::rtic` main module file is not so large and unwieldy.
* Adds thorough documentation to the `rtc::rtic` module and its items, discussing the differences between the two monotonics, and how to use the macros to create them.
…lication.

* Finally achieves ostensibly robust operation for both monotonics in which they can operate solidly for at least 12 hours under very heavy task load.
* Adds in instrumentation to monitor the monotonics and panic with useful debugging messages if an abnormal condition or stall is detected.
…lication.

* Major refactor to decouple the RTC mode from the monotonic backend type (basic or half-period counting).
* This enables using half-period counting in mode 0 for SAMx5x chips without duplicating as much mode.
* Updates and expands the documentation to account for the changes.
* Leaves in the monitor instrumentation so it is captured in the new form.
… that the monotonics have been thoroughly tested.
…ons and moves RTIC-specific things, so they can be used for other purposes as well.
…sing the best RTC mode for the chip variant. Updates the documentation accordingly.
…ng things with the `build-all.py` script.

* Renames the `wait_for_count_change` to `_wait_for_count_change` function name to suppress an unused warning for SAMD11/21 chips.
* Fixes the `metro_m0` example `blinky_rtic.rs` to fix an RTIC v1 item location change.
@kyp44
Copy link
Contributor Author

kyp44 commented Dec 21, 2024

Ok, I just discovered a stress test freezing issue when building in release mode, which I had not really tested before. Please do not merge until I get this fixed.

@jbeaurivage
Copy link
Contributor

@kyp44 does the last commit address all the freezing issues? I'm hoping to have the time to read the PR in detail soon™.

@kyp44
Copy link
Contributor Author

kyp44 commented Dec 23, 2024

@jbeaurivage Yeah, this does fix the issue, which, despite taking me hours to troubleshoot, was a very simple fix. I am still letting the stress test run for a long period of time, but I am 98% confident that there will not be further issues. I like to wait at least 36 hours to get a hardware counter rollover to be sure. Here is a timer showing how much time is left. If you want to be sure not to waste any of your time, wait until this timer is done, and I will check in and confirm that it's still going.

Copy link
Contributor

@jbeaurivage jbeaurivage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a few comments, some of which require changes, and some of which are at your discretion. But overall well done, this is some quality work!

Ideally I'd like to somehow get this tested on a thumbv6 target as a sanity check before merging.

By the way @kyp44, am I correct in my understanding that there are no breaking changes in this PR?

Comment on lines +81 to +84
/// Sets this mode in the CTRL register.
unsafe fn set_mode(rtc: &Rtc);
/// Sets a compare value.
unsafe fn set_compare(rtc: &Rtc, number: usize, value: Self::Count);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, I would suggest adding a # Safety section to the doc comments, explaining why these functions are unsafe and what are the invariants that must be upheld.

Comment on lines +120 to +121
/// TODO: This probably needs to be modernized (e.g. it does not implement
/// half-period counting) or deprecated/removed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm partial to adding a #[deprecated] attribute. Then we can yeet it at the next opportune occasion.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we choose to deprecate the item, its removal should be requested in #784.

Comment on lines +170 to +176
pub mod prelude {
pub use super::rtc_clock;
pub use crate::rtc_monotonic;
pub use rtic_time::Monotonic;

pub use fugit::{self, ExtU32, ExtU32Ceil, ExtU64, ExtU64Ceil};
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to start bikeshedding here, but I'm not a big fan of preludes in general. Although here, we already reexport fugit in lib.rs, so there's potential for conflict if a user does this:

use atsamd_hal::fugit::ExtU32;
use atsamd_hal::rtc::rtic::prelude::*;

Comment on lines +316 to +318
const fn cortex_logical2hw(logical: u8, nvic_prio_bits: u8) -> u8 {
((1 << nvic_prio_bits) - logical) << (8 - nvic_prio_bits)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is already a very similar function in the HAL (here). If you're up for it, it would be nice to consolidate them to avoid duplication.

/// This function was copied from the private function in `rtic-monotonics`.
unsafe fn set_monotonic_prio(prio_bits: u8, interrupt: impl cortex_m::interrupt::InterruptNumber) {
extern "C" {
static RTIC_ASYNC_MAX_LOGICAL_PRIO: u8;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An extern static is pretty unusual in Rust. I've personally scratched my head for a while on exactly this RTIC_ASYNC_MAX_LOGICAL_PRIO thing not so long ago. I would definitely explain in the docs somewhere what this u8 means, and that rtic will initialize the static, but users writing rtic-less apps should set the static themselves using

#[no_mangle]
pub static RTIC_ASYNC_MAX_LOGICAL_PRIO: u8 = (something);

@jbeaurivage
Copy link
Contributor

Oh also, not a big deal at all, but #[hal_macro_helper] is meant to be able to add the #[hal_cfg] attribute to blocks and statements inside functions, since that's not currently supported by the compiler (apart from the #[cfg] attribute) . For items outside of functions, simply doing use atsamd_hal_macros::hal_cfg is sufficient.

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

Successfully merging this pull request may close these issues.

2 participants