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

Added initial watchdog proposal. #76

Merged
merged 1 commit into from
Sep 28, 2018

Conversation

xd009642
Copy link
Contributor

Added initial trait proposal for watchdog timer as mentioned in #75

Copy link

@austinbes austinbes left a comment

Choose a reason for hiding this comment

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

You need to add pub mod watchdog; to src/lib.rs for this file to actually be found and compiled

src/watchdog.rs Outdated


/// A watchdog timer to reset the processor if software is frozen or stalled.
pub trait Watchdog {

Choose a reason for hiding this comment

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

You're going to want to add #[cfg(feature = "unproven")] to this, since it's a new trait

src/watchdog.rs Outdated
/// cannot be stopped
fn start(&mut self);
/// Set the period of the watchdog
fn set_period<T>(&mut self, period: T) where T: Into<Self::Time>;

Choose a reason for hiding this comment

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

Is it expected that Self::Time handles the prevention of invalid periods? Otherwise, set_period would have to be fallible, I think.

Additionally, it seems like this might all be more ergonomic if there was no set_period(), and instead start() took the period as a parameter. With a set-and-forget design like this, I don't see a lot of benefit to separating the act of setting a period into its own operation, but I might be missing something

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure thing, I'll make these changes when I get home from work! With set_period I was considering whether anyone may want to change period after its started. But that may not be supported on everything so I'll change it 👍

@xd009642
Copy link
Contributor Author

xd009642 commented Apr 19, 2018

@austinbes So I've responded to the feedback as well as outcomes of the discussion on the issue. My feeling regarding period correctness is that it should be handled by Self::Time as it could map to types like PLLs which could have a design shared with other timers on the processor.

That's just a gut feeling though I haven't done any analysis on processors other than the ones I've experienced personally. I did mention it on the issue to see if anyone had any firmer thoughts.

src/watchdog.rs Outdated

/// Disables a running watchdog timer so the processor won't be reset.
#[cfg(feature = "unproven")]
pub trait WatchdogEnable {
Copy link
Member

Choose a reason for hiding this comment

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

maybe WatchdogDisable?

Serisium
Serisium previously approved these changes Apr 21, 2018
src/watchdog.rs Outdated

/// Disables a running watchdog timer so the processor won't be reset.
#[cfg(feature = "unproven")]
pub trait WatchdogEnable {

Choose a reason for hiding this comment

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

Shouldn’t this be WatchdogDisable?

@xd009642
Copy link
Contributor Author

xd009642 commented Aug 1, 2018

I haven't heard anymore on this, so is there anything that has to be done to progress it?

@therealprof
Copy link
Contributor

@xd009642 Do you have an example implementation somewhere?

@xd009642
Copy link
Contributor Author

xd009642 commented Aug 3, 2018

No but I'll add one to my own embedded-hal implementation crate and link to it when I have

@xd009642
Copy link
Contributor Author

xd009642 commented Aug 4, 2018

This is a pretty quick implementation and an example showing it used. Ideally I'd have timers etc implemented so I could more scientifically trigger resets etc but I feel this is alright as a proof of concept.

Hal implementation:
https://github.com/xd009642/stm32f469xx-hal/blob/watchdog/src/watchdog.rs

Example usage:
https://github.com/xd009642/stm32f469i-disco/blob/watchdog-test/examples/watchdog.rs

src/watchdog.rs Outdated
pub trait Watchdog {
/// Triggers the watchdog. This must be done once the watchdog is started
/// to prevent the processor being reset.
fn kick(&mut self);
Copy link
Member

Choose a reason for hiding this comment

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

This is just a nitpick, and maybe I'm squeamish, but I don't like the thought of kicking a dog :)

In the LPC82x documentation, this operation is called "feed"; nRF52 calls this "reload". I think "reload" is a better and more descriptive name.

@hannobraun
Copy link
Member

I think this looks reasonable, although I would prefer if kick was changed to reload.

@xd009642 Could you squash the commits? I'd prefer not to merge commits with build errors into master.

@rust-embedded/hal I'd like to get this merged soon. Does anyone have objections?

@therealprof
Copy link
Contributor

@hannobraun FWIW I only know the phrase "kicking the watchdog" (for over 20 years even). I know the term loading only with setting the watchdog timer so naturally I would associate "reloading" with changing the timer value (independent of whether watchdogs actually allow you to do that or not).

I'm not strongly attached to whether we kick the dog or not but deviating from commonly used terminology might create confusion.

@hannobraun
Copy link
Member

@therealprof Good to know. I've heared about kicking the watchdog for the first time in this PR, but I don't have nearly as much experience as you :)

I've also checked the STM32F0x1/STM32F0x2/STM32F0x8 reference manual, and there's no mention of kicking either (the concept doesn't seem to be called anything except "writing to the key register"). And for what it's worth, feeding has more results than kicking on Google (273.000 vs 152.000). Do you think feed would be an acceptable name?

I do find the kicking kind of distasteful, but I don't feel that strongly about it. If you think that kick is the right name, I won't object.

@xd009642
Copy link
Contributor Author

At my workplace we commonly use kick, even in documents sent out to customers and subcontractors. I'd never considered an alternate term it's only ever been kick for me.

That said I checked an STM register manual for the STMF469 and it used the term refresh (just to throw another word into the mix).

I personally prefer kick as a term but I'm fine with whatever is understood by people. So I'll change it to feed and squash the commits and if there are any strong objections I'll just switch it to whatever the consensus is!

This proposes 3 watchdog traits, one to enable the watchdog, one to disable and another to feed or "kick" the watchdog. Traits are currently unproven.
@xd009642
Copy link
Contributor Author

So I did the squash and push and it says I dismissed someones review and requested reviews. I assume this is github doing things automatically and that means it's ready to progress some more 😄

Copy link
Member

@hannobraun hannobraun left a comment

Choose a reason for hiding this comment

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

This looks good to me. I'm happy to merge this as-is, but will hold off for a bit to wait for other feedback.

@hannobraun
Copy link
Member

Thank you, @xd009642! Regarding the name, as I said, I don't feel that strongly, and among the three of us, I'm guessing I have the least experience in the embedded space.

I just noticed that there's something wrong with Travis, but on first glance, it looks like it's not related to this PR. I'll look into it, but not today.

@therealprof
Copy link
Contributor

@hannobraun https://en.wikipedia.org/wiki/Watchdog_timer also mentions "kick" but anyway, LGTM.

@therealprof
Copy link
Contributor

bors r+

bors bot added a commit that referenced this pull request Aug 14, 2018
76: Added initial watchdog proposal. r=therealprof a=xd009642

Added initial trait proposal for watchdog timer as mentioned in #75 

Co-authored-by: xd009642 <danielmckenna93@gmail.com>
@bors
Copy link
Contributor

bors bot commented Aug 14, 2018

Build failed

@xd009642
Copy link
Contributor Author

@hannobraun I did see on the travis log when it failed that "line 14: GH_TOKEN: unbound variable" seems to be the only issue. Although it's in after_success so I wouldn't have personally expected that to result in a failure.

@hannobraun
Copy link
Member

I'll look into it when I get a chance. I'm a bit busy right now though, so it might take a while. If anyone wants to take a look in the meantime, feel free to do so.

@hannobraun
Copy link
Member

So, the problem here is that after_success.sh can push the documentation to the gh-pages branch, but needs an access token to do so. It tries to access a variable called GH_TOKEN, but that doesn't seem to exist. There's configuration (link only works if you have admin access to this repository) that sets this up, but I suspect something might have been lost in the move to the rust-embedded organization.

I'm not sure what to do:

  • I don't know what's wrong with the configuration I linked, and the page says that GitHub services are being deprecated. I suspect we should install Travis as a GitHub app, but I don't think I can do that for the rust-embedded organization.
  • I could add the GH_TOKEN variable in the Travis settings for embedded-hal (again, link only works if you have access), but I don't think I can generate an access token for just this repository. I don't want to add a personal access token there, that anyone with access to that configuration could use.

@japaric If you know what's going, I'd appreciate a hint. If you're unsure yourself, don't worry, I'll take another look when I get the chance.

@astro
Copy link
Contributor

astro commented Aug 30, 2018

You could use moving self to assert you feed a watchdog that must have been started:

/// Feeds an existing watchdog to ensure the processor isn't reset. Sometimes
/// commonly referred to as "kicking" or "refreshing".
#[cfg(feature = "unproven")]
pub trait Watchdog {
    /// Triggers the watchdog. This must be done once the watchdog is started
    /// to prevent the processor being reset.
    fn feed(&mut self);
}

/// Enables A watchdog timer to reset the processor if software is frozen or 
/// stalled.
pub trait WatchdogEnable {
    /// Unit of time used by the watchdog
    type Time;
    /// The started watchdog that should be `feed()`
    type Target: Watchdog;
    /// Starts the watchdog with a given period, typically once this is done 
    /// the watchdog needs to be kicked periodically or the processor is reset. 
    ///
    /// This consumes the value and returns the `Watchdog` trait that you must
    /// `feed()`.
    fn start<T>(self, period: T) -> Self::Target where T: Into<Self::Time>;
}

/// Disables a running watchdog timer so the processor won't be reset.
#[cfg(feature = "unproven")]
pub trait WatchdogDisable {
    type Target: WatchdogEnable;
    /// Disables the watchdog
    ///
    /// This stops the watchdog and returns the `WatchdogEnable` trait so that
    /// it can be started again.
    fn disable(self) -> Self::Target;
}

@hannobraun
Copy link
Member

bors retry

bors bot added a commit that referenced this pull request Sep 28, 2018
76: Added initial watchdog proposal. r=therealprof a=xd009642

Added initial trait proposal for watchdog timer as mentioned in #75 

Co-authored-by: xd009642 <danielmckenna93@gmail.com>
@hannobraun
Copy link
Member

@astro I kinda like your suggestions, but I think we shouldn't hold up this pull request right now. It has been open for a long time and has already been approved.

Would you mind opening a separate issue, so we can discuss your proposal separately?

@bors
Copy link
Contributor

bors bot commented Sep 28, 2018

Build succeeded

@bors bors bot merged commit 040a633 into rust-embedded:master Sep 28, 2018
@astro
Copy link
Contributor

astro commented Sep 29, 2018

@hannobraun not sure if worth the effort if you don't think it's important.

@hannobraun
Copy link
Member

@astro I do think it's important to further improve our traits, and I certainly think it's worth the effort to open an issue. I've gone ahead and done so: #98

But I also think we need to make forward progress. This proposal was in the pipeline for months, has gone through various reviews and iterations, and reached consensus. I think it was time to declare victory.

I'd love to see further improvements, but getting those merged will require another round of reviews, discussions, and more deep thinking. The right place to do this is a new pull request, in my opinion.

bors bot added a commit that referenced this pull request Jul 15, 2020
222: Improve watchdog API design using move semantics r=therealprof a=luojia65

This pull request improved watchdog API design. When starting watchdog, we may convert it into another type. We may implement different functions for this type. Or downstream developers can implement `Watchdog` for only an enabled type, to prevent feed to disabled watchdogs or forget to enable before feeding. If we are able to stop this watchdog, it can be converted into the former type.

If current design still need a same type after the watchdog is enabled, they may use `Target = Self`. In this way we create a fallback for earlier designs. 

A simple proof of concept: [here](https://github.com/gd32v-rust/gd32vf103-hal/blob/new-watchdog-design/src/wdog.rs#L155-L169) (L120-L153 for its `Enable` implementation, and there is `Disable` implementation)

Related issue: #98
Earlier discussion: #76 (comment)

Co-authored-by: luojia65 <me@luojia.cc>
Co-authored-by: Luo Jia <account@luojia.cc>
peckpeck pushed a commit to peckpeck/embedded-hal that referenced this pull request Nov 10, 2022
77: Adapt to embedded-hal-1.0.0-alpha.7 r=posborne a=eldruin

For the iterator methods I just collected the results. I have not looked into really using an iterating interface but merging this would be a first step and if there is interest we can look into that later on.
Fixes rust-embedded#76 

Co-authored-by: Diego Barrios Romero <eldruin@gmail.com>
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.

7 participants