最近,我们有了一个想法,使用模板创建裸机开发的通用高性能抽象。高性能裸金属抽象
通常每芯片制造提供了C头是这样的:
//Following structure is POD so we can rely on its memory layout
struct Periphery{
volatile uint32_t reg1;
volatile uint32_t reg2;
};
#define PERIPHERY0BASE 0x000000ab //address where does registers of periphery start
#define PERIPHERY1BASE 0x000000cd
static Periphery* PERIPHERY0 = (Periphery*)(PERIPHERY0BASE);
//or
#define PERIPHERY1 (Periphery*)(PERIPHERY1BASE)
我们的想法是再创造司机这是具体的,但一般对于给定的外围类型的平台:
template<int addr>
PeripheryDriver{
static inline void doSomething(int foo){
(PERIPHERY0*)(addr)->reg1 = foo;
}
}
//typedefs for different peripheries of the same type
typedef Periphery<PERIPHERY0BASE> Periphery0;
typedef Periphery<PERIPHERY1BASE> Periphery1;
这将是再用于平台独立模块,如下所示:
template<class P>
class DriverUser{
DriverUser(){
P::doSomething(0x00);
}
};
Po整体来说,我们可以从一个平台上的单个外围进行抽象,从而为所有具有相同结构的周边创建通用驱动程序,例如一个处理器系列中的定时器,Uarts等。此外,它允许我们创建高性能的平台独立的模块如我们可以例如创建高性能引脚访问的是用汇编语言编写,但同时高度可重用的高效:
//normally would be in PCB specific header
typedef Pin<Port0, Pin0> Pin0;
typedef Pin<Port1, Pin7> Pin1;
//application specific code
typedef Pin0 TxPin;
typedef Pin1 RxPin;
void main(){
SoftwareUart<TxPin,RxPin> my_uart(115200);
my_uart.send("hello world");
}
然后可以实现SoftwareUart完全独立于平台,但写入High到TxPin将与汇编器一样高效,而不使用宏。
我们的问题是,在某些平台上,制造商的头文件不包含 宏,它们将为地址定义名称,但只有宏已经是地址已经转换为指针的宏,因此我们不能将它们用作模板参数。 如PERIPHERY0BASE是不是只能PERIHPERY0
我的问题是,如果有可能是其将保持效率?(除改写寄存器定义)在C++ 11我想用constexpr创建功能,将任何解决办法 获得可作为模板参数的静态结构的地址。不幸的是,我们不能指望C++ 11的可用性。有任何想法吗?我们是否需要修改/编写我们自己的注册欺诈?
对不起,题外话。而且你的概念似乎完全忽略了内置模块,设备特定等。 – Olaf
在寄存器层的抽象并没有多大意义,因为很难找到任何跨平台匹配的外设寄存器。在芯片供应商产品线或某个供应商的一系列产品中,确定您可能会发现它们更常见。如果你想抽象一个uart,你可以用一个init来抽象它,写字符,读字符层不在寄存器层。 gpio,定时器等也是如此。 –
您的所有代码都已损坏,没有'volatile'声明。 – Lundin