- there is no implicit inheritance
- there is no polymorphism
- only a very reduced subset of the available values are objects (typically the GUI components)
Object Oriented problem #1 in small (or tiny) scale firmware development is that dynamic memory allocation and small microcontrollers - hmm, well, they just don't mix and match! If you ever have a C compiler that will generate code for malloc()'s and free()'s and you use them as intended, you will end up running out of memory because of fragmentation. You have couple of options here:
1. Don't care if you run out of memory, just manage the reset
2. Do your own simplified memory allocator, which is capable of allocating only for example three different object sizes.
3. Use static memory allocation, but program still in "object'ish fashion"
We have used the option 3 for couple of projects now. I'll explain briefly:
***** object.h *****
typedef struct _object
extern void OBJECT_construct( BYTE meIndex );
extern BYTE OBJECT_getValue( BYTE meIndex );
extern BYTE OBJECT_addValue( BYTE meIndex, BYTE v );
***** object.c *****
#define me myObjects[meIndex]
void OBJECT_construct( BYTE meIndex )
me.theValue = 0;
BYTE OBJECT_getValue( BYTE meIndex )
BYTE OBJECT_addValue( BYTE meIndex, BYTE v )
me.theValue += v;
***** main.c *****
void main( void )
while( 1 )
OBJECT_addValue( 0, 1 );
OBJECT_addValue( 1, 2 );
PORTA = OBJECT_getValue( 0 );
PORTB = OBJECT_getValue( 1 );
We use the word 'me' instead of 'this' because sometimes the code is compiled with C++ compiler. With some more macros you can make the code more readable.
I don't know if this is even object based (propably lots of people say no), but it works for us. It at least enforces capsulation better than relying only on developers discipline. There is an overhead from passing the meIndex -parameter (but it is a BYTE instead of a pointer) and the setters and the getters, but nothings free here - if you haven't noticed.