-
Notifications
You must be signed in to change notification settings - Fork 151
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
"Safe" pin manipulation not actually safe #178
Comments
Same thing with these other 3 calls:
So the final value of ODR will be the last write operation: I think you meant to use |
Ok, I agree that that would get me the expected results, but it still seems wrong that calling a safe method called "set_bit" would change any other memory. |
@robomancer-or: I stumbled across the same at first, but it's all documented in the svd2rust docs:
It doesn't really change any other memory, because |
Lol, it's documented, and therefore a feature and definitely not a bug! I still challenge this design choice for several reasons, but I'm very new to the language, so if it seems like I'm missing some important idea about safety I almost certainly am (please let me know):
|
I would like if the discussion could stay a bit more objective, I never said that everything is fine and not a bug if it's documented somewhere. I just tried to describe you the functionality of
That's your good right, and better solutions (naming included) are always welcome.
That's not true at all, calling
That's discussable and as I said above, improvements are always welcome.
There is, it's called Sorry if I can't help you further. Maybe you can explain what you understand under |
Oh, I'm sorry, I was trying to be playful. There's a somewhat widely known saying (at least in the US) that if it's documented it's a feature rather than a bug. I didn't mean anything by it. What I was saying is that HIDDEN could have contained My understanding of safety is that it entails different parts of the code being unable to step on each others feet (one example of which being mutating state that somewhere else thinks it owns). If GPIOA 1-5 are being used for the Ethernet MAC, and I want to add support for USB OTG on GPIOA 9-12, the two drivers shouldn't be able to clobber one another. In the present state of things this can't happen only because we're operating at the register level, but do we really want a situation where using Ethernet MAC on 5 of the pins means I can't use the other 11 pins for anything? |
It is possible (but not very easy with modify/write). However you can solve it easily, but just like with wrapping C in rust you will have to make a higher-level abstraction, see for example https://github.com/japaric/stm32f103xx-hal/blob/master/src/gpio.rs#L78. This may be hard to parse but it enables zen-main165 which then leads to zen-main274 and finally passing it off (safely) to zen-main297. |
If the signature of the closure changes, your code wouldn't compile anymore, or I don't get your point here.
This is a different story and it was discussed in other places, too. I think you are expecting too much from the automatically generated code here, it's only the first (low-level) hardware abstraction layer and it provides some nice features that you won't get (easily) with |
Yeah, it definitely wouldn't compile, but when I'm reading code I'm not JIT compiling it in my head, I glance at a thing and expect its meaning to be evident. In this case the meaning isn't evident because it depends on factors elsewhere in the code (worse, due to the naming it seems evident what the code does, so you have to learn what not to do the hard way). I'm talking about clarity and doing what the consumer expects, not about theoretical correctness.
Doesn't that assume MCUs will only ever have reset values that are both valid, and any one register swap away from valid? |
Following this argumentation, every closure or callback driven interface ẁill be By the way, this issue might be of interest for you. |
Are you suggesting marking the method as
If you are referring to It's the closure that sets the context of how
The second line of the crate documentation of all device crates generated using svd2rust have a link to svd2rust register-level API documentation.
But it doesn't; it literally means write this |
I'm not suggesting anything beyond what I said; it seems wrong that a function called |
I do like the p.GPIOE.odr.write(|reset| reset.odr10().set_bit());
p.GPIOE.odr.write(|reset| reset.odr11().set_bit());
p.GPIOE.odr.write(|reset| reset.odr12().set_bit());
p.GPIOE.odr.write(|reset| reset.odr13().set_bit()); (or something similar that shows that the closure argument is the reset value) in all places, especially the examples in the docs. |
So this might be me setting something up wrong, but if so I really don't see what it is... here's how to recreate the bug:
I'm testing this on an STM32F407 with LEDs on the obvious pins
`fn main() {
let p = stm32f40x::Peripherals::take().unwrap();
p.RCC.ahb1enr.write(|w| w.gpioeen().enabled());
unsafe {
p.GPIOE.moder.modify(|r, w| w.bits(r.bits() | 0x0550_0000));
p.GPIOE.otyper.modify(|r, w| w.bits(r.bits() & 0b11_0000_1111_1111_11));
}
p.GPIOE.odr.write(|w| w.odr10().set_bit());
p.GPIOE.odr.write(|w| w.odr11().set_bit());
p.GPIOE.odr.write(|w| w.odr12().set_bit());
p.GPIOE.odr.write(|w| w.odr13().set_bit());
loop {
asm::nop();
}
}
`
Expected behavior: all 4 LEDs off (they're low side switched).
Observed behavior: only the LED connected to GPIOE_13 is off. You can modulate which LED is off by commenting out odrX set_bit calls that come after the target LED in the code.
My guess: the compiler is dicking around because some "don't mess with this" flag is missing
The text was updated successfully, but these errors were encountered: