-
Notifications
You must be signed in to change notification settings - Fork 237
Closed
Milestone
Description
I'm working on a project in which I've defined an ActuatorMotor
which wraps a Pwm
channel on my device. As I'm refactoring to make ActuatorMotor
generic over the specific Pwm
hardware, I've found it annoying that all Pwm
functions take Pwm::Channel
by move.
Here's an example:
struct ActuatorMotor<P: Pwm> {
pwm: P,
channel: P::Channel,
}
impl<P: Pwm> ActuatorMotor<P>
{
fn set_velocity(&mut self, v: Velocity) {
// do stuff with velocity or whatever to get duty
let duty = todo!();
self.pwm.set_duty(self.channel, duty);
// error: can't move out of self.channel
}
}
A workaround that seems to work for now is to make channel
store a closure which spits out instances of Pwm::Channel
i.e. Fn() -> P::Channel
. At a first glance, requiring a Clone
and/or Copy
bound on Pwm::Channel
would solve my problem, or altering the method signatures in Pwm
to instead take &mut Pwm::Channel
instead of by move.
Metadata
Metadata
Assignees
Labels
No labels
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
[-]Creating abstractions over Pwm trait not ideal[/-][+]Creating abstractions over Pwm trait is not ideal[/+]ryankurte commentedon Aug 17, 2020
huh this can be frustrating! while we don't currently require
Clone
orCopy
bounds fromembedded-hal
, if these are currently implemented for the types you require could you partially resolve this with awhere: P::Channel = Clone
(I can't remember the exact syntax for this, sorry if it's not quite right) bound on yourActuatorMotor
impl?eldruin commentedon Aug 17, 2020
Have you tried
PwmPin
?amiraeva commentedon Aug 17, 2020
Thanks to both of you for getting back to me. The closure approach got too noisy, so I gave up and settled on using
PwmPin
. I just figured I'd chime in on my experience usingPwm
in its current state before it gets stabilized. Why can't it takeChannel
as an&mut
argument just likeadc::Oneshot
does for thepin
argument in its methods?eldruin commentedon Aug 17, 2020
Thank you @amiraeva.
I would be fine with changing the methods to accept a mutable reference channel but we should see how that fits for HAL implementations for MCUs.
Swap PWM channel argument to reference per rust-embedded#244
Capture
trait requires moving/copying channel argument #249David-OConnor commentedon Oct 12, 2020
Possibly related: It's not always ideal to represent PWM as a pin. For example, in STM32, PWM is controlled by timer peripherals. In F3, the PWM module used raw pointers so it could make it fit with the channel paradigm. I ended up adding PWM functionality to the timer struct, and was unable to make it work with the channel-based EH traits.
ryankurte commentedon Oct 12, 2020
interesting experience, are you able to share this code? it's an interesting use case, in my experience with PWM / timers it is not uncommon to run 2+ channels of PWM from a single timer but, the configuration changes between them tend to be somewhat restricted.
David-OConnor commentedon Oct 12, 2020
stm32-rs/stm32f3xx-hal#141
Discussion in there is also relevant; has comments from me and the original, EH/channel-based PWM module author. You'll see the crux of the issue is that the trait is channel-based, while most of the settings for STM32 MCUs are not.
Eg, compare the code in that PR to the
pwm.rs
module, which uses the EH trait: https://github.com/stm32-rs/stm32f3xx-hal/blob/master/src/pwm.rsSwap PWM channel argument to reference per rust-embedded#244
Merge #246
eldruin commentedon Jul 9, 2021
Fixed in #246