register.h
Kod: Zaznacz cały
#ifndef REGISTER_H_
#define REGISTER_H_
#include <stdint.h>
class Register
{
public:
uint8_t Data;
void Get(uint8_t (*Geter)(Register&));
void Set(void (*Setter)(Register&, uint8_t));
uint8_t Get(void);
void Set(uint8_t);
private:
uint8_t (*Geter)(Register&);
void (*Setter)(Register&, uint8_t);
};
#endif /* REGISTER_H_ */
register.cpp
Kod: Zaznacz cały
#include "register.h"
#include "stddef.h"
uint8_t Register::Get(void)
{
if(this->Geter != NULL)
{
return this->Geter(*this);
}
else
{
return Data;
}
}
void Register::Set(uint8_t value)
{
if(this->Setter != NULL)
{
this->Setter(*this, value);
}
else
{
Data = value;
}
}
void Register::Get(uint8_t (*Geter)(Register&))
{
this->Geter = Geter;
}
void Register::Set(void (*Setter) (Register&,uint8_t))
{
this->Setter = Setter;
}
No i teraz tworzę sobie "mapę rejestrów":
register_map.h
Kod: Zaznacz cały
#ifndef REGISTER_MAP_H_
#define REGISTER_MAP_H_
#include "register.h"
class RegisterMap
{
public:
RegisterMap();
Register * const ByIndex[64] = {
&IN, &OUTMH, &OUTML, itd...
};
Register IN;
Register OUTMH;
Register OUTML;
itd...
};
#endif /* REGISTER_MAP_H_ */
Implementacja getterów i setterów:
Kod: Zaznacz cały
#include "register_map.h"
RegisterMap::RegisterMap()
{
//IN
IN.Get([](Register& reg) -> uint8_t
{
return reg.Data;
//albo odczyt z rejestrów procesora/układów peryferyjnych/cokolwiek...
});
IN.Set([](Register& reg, uint8_t value) -> void
{
reg.Data = value;
//tu może być wywołanie funkcji ustawiającej port jako wejście...
});
//OUTMH
OUTMH.Get([](Register& reg) -> uint8_t
{
return reg.Data;
});
OUTMH.Set([](Register& reg, uint8_t value) -> void
{
reg.Data = value;
});
//OUTML
OUTML.Get([](Register& reg) -> uint8_t
{
return reg.Data;
});
OUTML.Set([](Register& reg, uint8_t value) -> void
{
reg.Data = value;
});
itd...
}
Potem w mainie:
Kod: Zaznacz cały
Registers.IN.Set(8);
Registers.ByIndex[0]->Set(8);
uint8_t a = Registers.IN.Get();
uint8_t b = Registers.ByIndex[0]->Get();
To taka wstępna koncepcja i ma pewne wady:
- wskaźniki siedzą w ramie
- rejestry są tylko ośmiobitowe
Podejrzewam, że drugi problem rozwiąże zastosowanie szablonu? ale nie wiem jak zrobić, żeby wskaźniki były const. Zakładam oczywiście, że przypięte funkcje Get i Set nie będą zmieniane w trakcie pracy programu.