What is a good methodology for object oriented peripheral code in C?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-06-05 2:03 PM
I have a project that involves a STM32F7 controlling a stepper motor through GPIO. I have now been tasked with redesigning it with a ST L6470, a motor control IC which has a SPI interface. I would like have a shared codebase so that a simple #define could be used at compile time to choose between GPIO or SPI code depending on the board used. Examples of polymorphism in C such as the linux device driver code and GObject are difficult to understand and perhaps not a good example for microcontroller code.
The solution must be C11 compatible and compiled in IAR EWARM.
- Labels:
-
STM32F7 Series
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-06-05 2:16 PM
Keep It Simple is the best of methodologies for embedded C.
Another is to make it Somebody Else's Problem (hire a contractor, let him sweat instead of you).
-- pa
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-06-05 4:29 PM
OOD sounds like a bit of overkill for a motor controller.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-06-05 8:53 PM
OOD is needed only if You have multiple motor instances in one project. In C it can be implemented by defining a structure for object and passing a pointer to it in API functions. If it's only one motor instance in a project, then make one .h file with API definition (set of functions) and multiple .c files for different API implementations. To switch between .c files with a #define, put #ifdef/#endif pair on top/bottom of .c files so that unneeded files are effectively empty.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-06-06 8:03 AM
Unclear what you want to do and where OO makes things more modular.
More details are needed.
Are the higher level source code the same and plumbing below either to GPIO or SPI?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-06-06 9:14 AM
OOP in C is doable, but for small projects, not likely worth the complexity. However, you can gain many of the advantages of OOP through well structured code, using opaque data types, and using C’s built-in techniques for separating private/public interfaces. Don’t worry about inheritance, use composition instead. Those steps alone keep C plain and simple for none-OOP readers, but give OOP-experienced folks a lot of the “structure�? they like to see.
As for polymorphism, there are fancy ways, but in your case, I’m inclined to think #ifdef is suitable. I use it a lot for the same purpose you’re looking at (building with various optional hardware drivers).
I have a master mProject.h file which declares project level constants. That file #includes mLocal.h which is specifically for the purpose of triggering versions of builds.
(I prefix our code with a “namespace�? of “m�? so I can easily identify “ours�? vs. “theirs.�?)
Two techniques come to mind:
In mProject.h, before mLocal.h is included, you have
// Define a build options to choose from, and a build variable
#define mMOTOR_CTLR_GPIO (1U)
#define mMOTOR_CTLR_SPI (2U)
#define mBUILD_WITH_MTR_CTLR_TYPE mMOTOR_CTLR_GPIO // this is the default build
In mLocal.h you have
// Affirm or override the mProject build variable in your own personalized mLocal file
#undef mBUILD_WITH_MTR_CTLR_TYPE
#define mBUILD_WITH_MTR_CTLR_TYPE mMOTOR_CTLR_SPI // this overrides mProject.h
Next, in your application code files, where you might have
#include “mCtlr_motorGpio.h�?
You would now have
// The file to include is determined based on your build option variable
#if (mBUILD_WITH_MTR_CTLR_TYPE == mMOTOR_CTLR_SPI)
#include “mCtlr_motorSpi.h�?
#else
#include “mCtlr_motorGpio.h�?
#endif
Obviously you could skip mLocal.h and use just mProject.h. However, the advantages of mLocal.h are
- mProject.h is always defined as the baseline default and doesn’t get butchered by whoever needed a special version and didn’t undo the changes. (mLocal.h needs to exist, but it doesn’t need any content.)
- mLocal.h is NOT checked into source code control so that each developer can have their own version to manage local builds during development.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-06-06 9:53 AM
Think it just needs to use structures passed as pointers, and not use a shed load of global variables.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-06-06 11:01 AM
Yes that's how I do my real-time (audio) designs. A proper OOD design would add too much non-determism to the timing which I imagine would be bad for a motor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-06-07 8:15 AM
This is a tempting solution for the short term, but multiple motors is a possibility in the future.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-06-07 8:20 AM
Right, I don't need a complete OO solution. I am thinking just a shared structure with pointers to the to functions that each codebase would have such as:
initialize
start motion
stop motion
is moving
