I'm writing a real-time operating system for microcontrollers in C++11 - distortos. Currently I'm thinking about a C++ framework for various peripherals. The most basic peripheral which I would like to have there are input/output pins. Because such input/output pins can both be built into the chip or be external (I2C expanders, shift registers, ...) I plan to implement interfaces for them with pure abstract classes.These are some of mine requirements:some pins can only be inputs and it shouldn't be possible to (easily) change their direction - for example if you change the direction of pin connected to push-button to output you can irreversibly damage the chip, the board or the device that is connected to the other side of the wire;some pins can only be outputs and it shouldn't be possible to (easily) change their direction - if you are using a HC595 shift register then this can only be output and nothing more;some pins can change their direction freely - this is required if you want to implement software I2C or software 1-wire;Initially I have thought about doing it like this:The most basic interface class would be InputPin - it would only support reading the state of the pin.Second interface class would be OutputPin - it would inherit from InputPin (as you can read the value of pin configured as output) and also add the ability to write the value.Third interface class - InputOutputPin would inherit from OutputPin and also provide a function to change direction.Such approach has a very nice feature that I can use use any derived class in function that requires one of the bases. But actually there is one substitution that is not always correct - using InputOutputPin in a function that requires OutputPin can be a problem when the instance of InputOutputPin is currently configured to be an input...I've tried googling around for some inspiration and it seems that there is not much to use. ARM's mbed framework has 3 completely unrelated classes (there is no inheritance there) - one for in, one for out and one for in/out. Most of the code that I found has only one class that is for in/out. I've actually found an article about exactly the same issue that I'm facing - http://www.embeddedrelated.com/showarticle/108.php . The solution presented there doesn't suit my needs - in a multi-threaded environment the operation of changing the direction of the pin is not so simple and usually requires exclusive access to configuration registers (the change is a read-modify-write operation).I wouldn't like to implement any solution where the functions could fail (for example return error codes when the operation is not possible) - this would really complicate the usage.Implementing a type-conversion operator - so that conversion from InputOutputPin to OutputPin would be done in a function which also makes sure the direction is correct - is error prone, because the reference to OutputPin can be stored for later use and at that time the direction may have changed again.Maybe I should just simplify the hierarchy - OutputPin and InputOutputPin would both inherit from InputPin (this would always be correct), so OutputPin wouldn't be a base for InputOutputPin. This looses some of the flexibility, but I'm not sure that such substitution would be required anyway.
Pure abstract classes for input-, output- and bidirectional-pin of microcontroller
c++;embedded systems;abstract class