我想使用 IO 寄存器(== 静态内存地址)作为模板参数。问题是,寄存器通常被定义为扩展为类似于以下内容的宏(*(volatile uint8_t*)(11 + 0x20))
我不知何故无法正确使用我的模板。
我想编写如下代码:
Foo<PORTB> foo;
这样我就可以轻松更改类使用的 IO 寄存器,而无需任何运行时开销(这对于微控制器至关重要)。
我在下面提供了一个完整的示例:
#include <stdint.h>
#include <stdio.h>
#include <utility>
#define PORTB (*(volatile uint8_t*)(11 + 0x20))
template<volatile uint8_t* PortRegister>
class ControllerPtr final
{
public:
static void SetHigh() { *PortRegister |= 0x2; }
};
template<volatile uint8_t& PortRegister>
class ControllerRef final
{
public:
static void SetHigh() { PortRegister |= 0x2; }
};
int main()
{
ControllerPtr<&PORTB> ptr;
ControllerRef<PORTB> ref;
ptr.SetHigh();
ref.SetHigh();
// Both statements should be equal to:
// PORTB |= 0x2;
}
每当我试图通过时&PORTB
to ControllerPtr
,g++ 无法编译:
error: (volatile uint8_t*)((long int)(11 + 32))
不是有效的模板参数volatile uint8_t* {aka volatile unsigned char*}
因为它不是变量的地址
错误:表达式*(volatile uint8_t*)((long int)(11 + 32))
有副作用
尝试通过时的错误有点不同PORTB
到像使用的引用类型ControllerRef
:
error: *(volatile uint8_t*)((long int)(11 + 32))
不是类型的有效模板参数volatile uint8_t& {aka volatile unsigned char&}
因为它不是一个具有链接的对象
我实际上不明白为什么这个错误是一个错误,因为我没有看到将静态地址传递给模板有任何问题。
非类型模板参数必须是常量表达式,并且不能有reinterpret_cast
在常量表达式内(除非它未被评估)。
由于您已经表示除了通过宏(例如)之外,您无法访问数字地址PORTB
,我建议一个解决方法。尽管PORTB
不能在模板参数中使用,我们可以合成一个可以在模板参数中使用的唯一类型,如下所示:
struct PORTB_tag {
static volatile uint8_t& value() { return PORTB; }
};
template <class PortTag>
class ControllerRef final {
public:
static void SetHigh() { PortTag::value() |= 0x2; }
};
int main() {
ControllerRef<PORTB_tag> ref;
ref.SetHigh();
}
当您有很多端口时,为了节省重复输入,我们可以使用宏:
#define PORT_TAG(port) port_tag_for_ ## port
#define MAKE_PORT_TAG(port) struct port_tag_for_ ## port { \
static volatile uint8_t& value() { return port; } \
}
template <class PortTag>
class ControllerRef final {
public:
static void SetHigh() { PortTag::value() |= 0x2; }
};
MAKE_PORT_TAG(PORTB);
int main() {
ControllerRef<PORT_TAG(PORTB)> ref;
ref.SetHigh();
}
http://coliru.stacked-crooked.com/a/401c0847d77ec0e0
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)