设计硬件抽象层的最佳方法

时间:2015-07-10 17:25:13

标签: c++ embedded

我正在尝试将硬件抽象层添加到ST32F0微控制器中。 为了访问寄存器,我在这里使用方法布局:

https://github.com/kensmith/cortex-from-scratch
https://yogiken.files.wordpress.com/2010/02/c-register-access.pdf

我面临的问题是需要创建一个通用类GPIO(例如),它允许操作所有GPIO端口(即GPIOA,GPIOB,GPIOC ......)。 在当前实现中,寄存器被描述为:

STM32LIB                  ::REG                ::GPIOF          ::MODER_D
   |                         |                     |                 |
The LIB namespace  The registers namespace   the GPIOx struct    The register i'm interested
//if i want to access the MODER_D on GPIOA i would write
STM32LIB::REG::GPIOA::MODER_D.set();
//or GPIOB
STM32LIB::REG::GPIOB::MODER_D.set();

我想尽可能让用户保持清洁。像这样:

GPIO LED;
LED.init(PA_5,GPIO::PIN_OUTPUT,GPIO::PullDefault,GPIO::Slow);
LED.ON();

我不希望让用户知道任何模板,但如果需要,那就好了。最重要的是用户不需要做这样的事情:

GPIO<GPIOA,2> LED; // <-- This is OK(ish)
...
LED<GPIOA,2>.ON(); // <-- This is not...

我知道我可以使用模板,但我不喜欢写相同的函数X次,只需更改B和C的GPIOA参数...

这是我声明所有外设寄存器的hpp文件。https://github.com/joaoc/STM32LIB/blob/baremetal/stm32Lib/HAL/Include/RegisterAccess/MCU/hpp/STM32F030.hpp

一个小例子是:

struct GPIOF{
   struct MODER{
    static reg_t<rw_t, 0x48001400, 30, 2> MODER15;
    static reg_t<rw_t, 0x48001400, 28, 2> MODER14;
    //...
   };
   static reg_t<rw_t, 0x48001400, 0, 32> MODER_D
};

1 个答案:

答案 0 :(得分:0)

这会有帮助吗? http://torjo.blogspot.pt/2007/10/template-construct.html

我不完全理解该链接中解释的方法,但这个想法可以帮助我......

我不知道它是否清楚,但我知道这是什么东西:

class GPIO{
\\ ...
   void ON(){
      STM32LIB::REG::GPIOx::BSRR_D.write(gpio_mask);
   }
}

如果我将LED实例化为

GPIO LED(GPIOA,3,...);
LED.ON();

然后ON功能上的GPIOx将转换为GPIOA。 我需要有可能做到这一点:

GPIO LED_GREEN(GPIOA,3,...);
GPIO LED_RED(GPIOB,2,...);
LED_GREEN.ON(); //-> this would translate to STM32LIB::REG::GPIOA::BSRR_D.write(gpio_mask);
LED_RED.ON(); //and this to STM32LIB::REG::GPIOB::BSRR_D.write(gpio_mask);

请记住,我可以改变我在发布链接的标题上声明寄存器的方式。我想要一种方法来制作我想要的东西,请记住这是一个嵌入式程序。如果可能在编译器阶段进行更改...