How to design the class for communicating with different modules

Viewed 66

I have a micro controller board on which are different sub modules. Every module has an address and different registers which can be addressed. For example:

GPIO module
-Address 0x1212
-Registers:
--InputRegister
--OutputRegister

PLL module
-Address 0x2342
-Registers:
--PhaseRegister
--ErrorRegister
--LockedInRegister

These sub modules can be controlled via a UART messages which contain the address, the register and the value to be written.
I need to implement a class to communicate with the micro controller and the modules. The simplest way would be to implement a function like so:

void send_message(int address, int parameter, int value) {
...
}

But then it is possible to issue a write to a random address which does not exist or to a register which does not belong to the selected module.

My Idea would be to implement a base class for the modules and derive a class for every sub module as follows

Class diagram

But then how would one declare the available registers correctly? How can this be implemented in a proper way?

1 Answers

Public inheritances is the strogest relationship available (other then friendeship), if the information are known at compile time, you can have a much loosly coupled code using templates:

#include <iostream>
template<int address, int reg>
struct Module
{
    static constexpr int address_ = address;
    static constexpr int register_ = reg;
};

typedef Module<10, 100> Input;
typedef Module<10, 1000> Output;
typedef Module<20, 100> Phase;
typedef Module<20, 1000> Error;
typedef Module<20, 10000> LockedIn;

template<class Module>
void send_message(int value) 
{
    std::cout << "using address: " << Module::address_ << " at register " <<    Module::register_ << " with value: " << value << std::endl;
}

int main()
{
    send_message<Input>(-100);
    send_message<Output>(-100);
    send_message<Phase>(-100);
    send_message<Error>(-100);
    send_message<LockedIn>(-100);
}

Please note, that it is impossible to send an invalid register/address pair (assuming there is not an error in the typedef to start with).

Inside the microcontroller class you can add a method that transform the client call to the proper send_message call.

Related