I want to access STM32F0 peripheral register through C++ templates. A gpio port for example is defined as follows by vendor:
typedef struct { uint32_t PUPDR; uint32_t ODR; ... } GPIO_TypeDef;
#define GPIOA_BASE 0x1000200030004000 // peripheral memory address
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
So you can access hardware registers by GPIOA->ODR
. I created template output class with port and pin as parameter.
template <uint32_t port, uint32_t pin>
class Output {
public:
static set() {
GPIO_Typedef * castedPort = reinterpret_cast<GPIO_TypeDef *>(port);
// set pin
}
};
Output<GPIOA_BASE, 1>::set();
This compiles with Launchpad g++ (g++ (i686-posix-dwarf-rev3, Built by MinGW-W64 project) 4.8.2
).
But I want to use GoogleTest to test my code and so I created a fake register GPIO_TypeDef OutputTestPort;
. But of course this fails.
could not convert template argument ‘OutputTestPort’ to ‘unsigned int’ stm32::Gpio::Output<OutputTestPort, 3>::set();
If I cast pointer to uint32_t
, than it is no constant expression and for template parameter prohibited.
int32_t const port = reinterpret_cast<int32_t>(&OutputTestPort);
stm32::Gpio::Output<port, 3>::set();
error: the value of ‘port’ is not usable in a constant expression stm32::Gpio::Output<port, 3>::set();
So I tried pointer as parameter directly:
template <GPIO_TypeDef * port, uint32_t pin>
class Output {
/* implementation */
};
This works fine for GoogleTest with g++ (Ubuntu 4.9.2-0ubuntu1~14.04) 4.9.2
but know Lauchpad compiler fails:
error: '1207961600u' is not a valid template argument for GPIO_TypeDef*' because it is not the address of a variable
So is there any way to make this work, getting valid code for embedded controller and GoogleTest?
Aucun commentaire:
Enregistrer un commentaire