-
Notifications
You must be signed in to change notification settings - Fork 188
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
STM32 family and common HAL drivers #61
Comments
I'm entirely of your way of thinking. As a comparison, ChibiOS has blanket implementations for variants of STM32 peripherals. If you look under I present this not as a potential organizational model, but instead as a vindication of the idea that driver implementations can be profitably shared between many of the STM32 variants. Perhaps it would make sense to implement a number of crates (like |
This is a tricky topic. Whereas other C implementations "profit" from being able to abstract over slight implementation differences, with Rust this is not as easy as the prototype implementation has to be abstract over all of them so every slightly different implementation will typically require a change in the prototype and all of the HAL implementations. I'd love to see this but I'm highly sceptical it can be done. Bring in the wizards! 😉 |
I'm not sure I understand the issue here -- but I could easily be missing some Rust subtlety. My embedded experience is almost entirely in C. In the case of the STM32 family, these are identical individual hardware peripherals -- there's no slight implementation difference required for interfacing with them. I definitely think a hardware peripheral with similar but not identical functionality should be a separate driver. But I also shudder at the idea of maintaining identical driver code across multiple crates. I know that many of the drivers (for instance, |
I'd also really like to see common API/HALs for STM32s and think the ChibiOS implementations are a good example of what could be done. Sadly there end up being a lot of small differences even between apparently identical peripherals. In C this is less of an issue (you just use the registers you want, by name, and they'd better exist) but the svd2rust-generated APIs will differ both in terms of their actual type not being the same object and in terms of them containing different registers or registers with different fields. I found there were surprisingly few STM32 peripherals which were exactly identical even inside families, mostly only the 3rd party ones like CAN and USB. I had a big table of what matched up with what somewhere, I'll try and find it... |
@adamgreig Yes, that's exactly what I'm talking about. Would love to see your table, though I somewhat doubt there'd be a lot of surprises for me. 😉 |
Y'all might be interested in svd2rust#96 which is an ongoing discussion around extraction of common features from processor families and how we can generate / compose them into devices. |
@ryankurte thanks, that is an interesting discussion! I'll have a look over it. I found the tables I made, https://agg.io/u/stm32/stm32f/index.html is the STM32F family overview (go up one level for L/H families), click a family header to get the detail breakdown inside that family. Each unique peripheral (grouped by register names+addresses) is listed on the left, with a green tick against devices that implement it. Click the peripheral to see the registers (grouped by fields) etc. |
I'm looking for the |
@bergus Uhm, I've written a couple of these by now but they're not copied from
|
@therealprof OK, I haven't looked into the more advanced peripherals yet. I just was comparing the basics - timers, gpio - and was looking into I would think that all hal crates should use the same patterns for the same things. And possibly even implement the same traits, imported from something like I am really looking forward to @adamgreig's automatic code generation that knows about the detailed differences (or even can automatically extract them from the device description files), but until that is viable I think we should manually identify the common parts at least for the basic peripherals. OK, enough of telling you what I think you should do. I guess what I am really looking for is a guideline on how to implement a HAL. Specifically, I am using a STM32L432, for which none exists yet. So what is the recommended approach? I have not written much Rust yet, or any MCU low-level stuff, so I am mostly programming by example for now. Which of the patterns that can be found in the existing crates should I follow? Where exactly do I need to watch out for differences, and is the only way to confirm them by comparing the respective programming manuals? (Or: how do I know which parts I can copy&paste?) |
@bergus It's unfortunately not quite so simple. The reason so many different implementation "styles" exist is that there's no one which ultimately fits all, e.g. @japaric seems to prefer to move "ownership" of registers into HAL implementations wherever possible, "split" resources whenever they're shared and only in very circumstances use unsafe APIs to access registers directly. In contrast I prefer to only split resources which are really shared all over the map, move ownership of registers only when there's exactly one single legitimate user of the register, and use unsafe register access everywhere else. Also the HAL implementation depends on the vendor implementation of the peripherals which are dramatically different, so an approach that works nicely for STMicro will absolutely not work for most other manufacturer so it's a bit tricky to provide a general step-by-step documentation.
The STM32L432 is quite similar to all STM32L4 or STM32F4 MCUs so I'd start with one of those. If I was to start one, I'd use a crate, change the peripheral API and all references to it in the code and simply try compiling it. If there're compile errors in the code, fix them; if the compiler is complaining about non-available registers; open the reference manual and adjust accordingly.
Hm, the new book is very early WIP at the moment, I guess the next best thing is to check out
The good thing with is: If it compiles you're most likely on the right path or even fully there. Of course the vendor supplied SVD files are full of errors but most of the stuff is correct and the compiler will watch over the correct use of register fields and names which is a huge thing. |
This repository is focusing on the generic HAL traits rather than generic HAL implementations, hence I'm going to close this now. If you're interested in this (very valid) topic about universal STM32 drivers you're more than welcome to checkout our bundled STM32 efforts in the STM32-rs org. |
61: Fix active low behavior of GPIO output pins r=eldruin a=MorganR When an output pin is in active-low mode, the try_set_low and try_set_high functions currently incorrect behavior. In keeping with the input behavior for `try_is_high` and `try_is_low`, "high" and "low" should refer to the actual output voltage. This works as expected for pins that are not in active-low mode, but if a pin is in active-low mode, then the opposite happens: * calling `try_set_low` sets the voltage high * calling `try_set_high` sets the voltage low This bug and the fix have been verified using [this test program](https://github.com/MorganR/active-low-test). Co-authored-by: Morgan Roff <mroff@google.com>
Hello, everyone,
for one of my boards containing a STM32F405 I'm creating a BSP-Crate and corresponding HAL-Crate and note that the STM32F4 will be able to share some drivers of the HAL with the STM32F3, but some of them are very different, like I2C.
Are there any plans for a better representation of the common features of the STM32 family? It would be quite unpleasant to always have to copy from the stm32f30x-hal. I'm really not a friend of copying code. At this point I would like to offer my help.
Greetings,
Ingo
The text was updated successfully, but these errors were encountered: