-
Notifications
You must be signed in to change notification settings - Fork 143
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
Passing refrences to Gpio pin port deifinitons to classes #275
Comments
You can pass the GPIOs function, for example |
That makes me really sad :/ why is it expensive if you pass by reference? class RGB_LED
private:
}; |
Then the Gpio class would need virtual functions, that each specific pin would implement. Those vtables add up to a lot of space, and are especially slow on AVRs. It also prevents efficient implementation of You can make RGB_LED a template class and pass all the GPIOs as template arguments, or create your own GPIO interface with virtual functions and wrap the modm GPIO classes into that. |
For reference, this is the fancy stuff you can build with our GPIOs: #19 (comment) |
Ah i didn't consider the AVR case... Thank you again for all that you have done with this project. It's very nice :D |
For more reference, these are all platform specific GPIO functions that you'd need to implement with virtual functions. ~25 vtable entries at 4B each is 100B per GPIO class, thus for a LQFP100 package with maybe 80 GPIOs, that would be ~8kB just vtables. Although arguably you wouldn't use all 80 pins in your program, but just 10 GPIOs is 1kB vtables. There's probably more overhead though than just vtables. A better way (and how it's usually done) is to encode the port/pin into an integer (uint8_t with high nibble for port, low nibble for pin) and then compute the register access at runtime. This works really well for STM32, since the GPIO registers are super regular, but on AVRs, the IO space is crammed full of random bits, and you need a lot of special cases. But I agree that we need a dynamic GPIO API going forward. |
Yeah, that's how libopencm does it. But they don't join the port and pin into one variable so you have to send a port and a pin variable for each pin. Kind of annoying. I'm with you on the dynamic allocation as one of the strongpoints of C++ is the use of dynamic variables for code reuse. Even with the 8kB of overhead most modern processors have quite a bit of memory and storage. I think it might be worth it. |
In that case, create a VirtualGpio class with all the functions you need, the use a |
I'm not quite sure I follow. But I'll try! |
Also i just realized how this project was built using lbuild (i didn't know what it was before but having used jekyl i understand its power). That's sexy af. I'm used to hand rolling C++ because of the dynamic aspect. Maybe that would be the way to go. I'm so lost haha. |
Here is a full implementation of such a VirtualGpio for the ELVA project (a research model railway): https://gist.github.com/salkinium/4eb42cc3d964338d6b92a7df1e0d24ab |
Damn, I must be really dumb 😆 . I kind of understand what you're talking about now. Just seems like a really complicated way of doing something that should be simple :/ . Thank you again for your help :D |
This stuff is difficult to learn, it took me a decade to get to this point. You're not dumb!
Unfortunately this is on purpose, modm wasn't designed for a dynamic runtime, instead moving a lot of things into compile time or even code gen time (in Python via lbuild). This makes it much easier to use on very low resource devices (we started on AVRs and still fully support them), but obviously much more difficult for other use-cases. I'm very much aware of the limitations of this method, and am actively working on a better balance between an "all template HAL" and an "all runtime HAL". My initial explorations show a really good compromise between the two. |
Ah but I have been doing this for much longer than 10 years 😆 . Yeah, there is a huge benefit to statically compiled code. I'm actually thinking about using lbuild to make some generic devices (RGB led, Motor, buttons etc) . But i think it would take too long to get into it. I don't have much time to do this. |
Also that gist is missing the hardware.hpp. I'm pretty sure it's intentional. I'm still figuring it out 😆 . |
I just wanted to show you that you can then use the base class |
Yeah, I know. I tried declaring everything but I'm still getting type errors. I guess I just don't understand templates well enough. reverts back to old project quietly weeps |
I'm sorry, modm is very research-y… hard to compete with all the other libs out there 😢.
While My |
No it's a very good library. For sure better than anything else out there. But my coding style depends so heavily on dynamic code reuse that it doesn't really work for me. Surely better for smaller projects. Everything works as needed. |
i just don't understand. hardware_io.cpp:111:9: error: 'GpioControl' in namespace 'elva' does not name a type. What object type is GpioControl supposed to be. I'm lost i really feel bad bothering you on this. Do you have a btc address ? |
I yanked that very quickly from the project into a Gist, it was meant more as an inspiration. But here's a compiling and tested example on my modm fork, see the |
The VirtualGpio class should work for all STM32, except maybe the F1 series, since that has a mildly different hardware implementation. What device are you using? |
I'm using an stm32f071v8. Thanks, I was inspired, just lost. |
That works :D Thank you so very much! |
I just realized this is even worse for the Timers haha. Guess I'll have to do a massive switch case or something... |
I mean, modm really goes out of its way to NOT use C++ polymorphism with virtual interfaces, so you're going to encounter these issues over and over again. |
I'm closing this issue since I think the original issue has been resolved. You can of course still continue commenting! |
@salkinium not related but I'm trying to understand how to pass timer channels to different timer inputs. I have a channel 3 pin in that i want to pass to channel 1 for the encoder. looking at the timer diagram there seems to be a link. |
We don't have an API for that, you need to set the registers directly. It's on my radar, but requires a lot of data (so has a dependency on modm-devices). |
Ah understood :) thanks I just changed it in hardware for now lol |
Implementing a generic API for timers is probably not possible and in my opinion the wrong attempt of abstraction. On STM32 every timer and every channel sometimes has different features/options and behaves slightly different. I could imagine a platform independent API which provides a PWM signal with adjustable frequency and duty cycle at one pin. |
@rleh yeah you're actually right, It was still a better option since i was able to get two identical timers for my operations. |
Can't wait for RISC-V to come and fix everything lol |
Hello, I have an led array that has Rgb leds and i was wondering if I could pass a gpio to a function. It seems that gpios are set to a specific definition at compile time but there's no generic gpio class i can reference in my function definition? I'm not sure if this is the same as #201... Sorry...
The text was updated successfully, but these errors were encountered: