I would like effectively map structures with registers to a memory. Actually I have working code like this:
Structure with registers for a peripheral:
struct Periph {
volatile uint32_t REG1;
volatile uint32_t REG2;
};
In device is this peripheral two times located on two different addresses in memory, so define these addresses:
static constexpr size_t PERIPH1_BASE = 0x40000000;
static constexpr size_t PERIPH2_BASE = 0x40001000;
Then I have a driver which can use any of these registers:
template<size_t Base> struct Driver {
inline Periph &r() {
return *reinterpret_cast<Periph *>(base);
}
void setFoo(uint32_t x) {
r().REG1 = x;
}
uint32_t getBar() {
return r().REG2;
}
};
To use this driver is simple, only need set address of certain peripheral to template:
Driver<PERIPH1_BASE> drv;
uint32_t x = drv.getBar();
drv.setFoo(x);
...
If compiler merge all inline functions after optimization then this method works very effectively with registers and without any overhead.
But this is not very safe, because I can set to Driver
any address from different peripheral.
My Idea to improve this is to put reference to a structure as template argument, but without success.
First I defined references to registers:
static Periph &PERIPH1 = *reinterpret_cast<Periph *>(PERIPH1_BASE);
static Periph &PERIPH2 = *reinterpret_cast<Periph *>(PERIPH2_BASE);
This is working, I can directly access these registers like:
PERIPH2.REG1 = 123;
But I have no idea how to pass these references to template argument, my attempt is following:
template<Periph &r> struct Driver {
void setFoo(uint32_t x) {
r.REG1 = x;
}
uint32_t getBar() {
return r.REG2;
}
};
Driver<PERIPH2> drv;
drv.setFoo(x);
From this I get following error:
`error: the value of 'PERIPH2' is not usable in a constant expression`
If I define PERIPH2 as constexpr then I get another error:
`error: reinterpret_cast from integer to pointer`
... So how to put reference to an object as template argument? Or an idea or suggestion to make this better.
Also here exists lot of other solutions (like put reference to a Driver constructor...), but this slow down access to registers.
Thanks for any help.
Aucun commentaire:
Enregistrer un commentaire