【问题标题】:Best way to design a Hardware abstraction layer设计硬件抽象层的最佳方法
【发布时间】:2015-07-10 17:25:13
【问题描述】:

我正在尝试将硬件抽象层添加到 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
};

【问题讨论】:

  • 嗯,这可能是预处理器宏允许的用例之一,并让用户将特定目标平台绑定作为-D 编译器选项。
  • 这是一个想法,但并不理想。如何定义引脚,一个在 GPIOA 上,另一个在 GPIOB 上?
  • 也可以使用typedefusing 键入别名可能会有所帮助。
  • 你会使用吗?我发布的 pdf 使用 using 关键字指定了 regs,如下所示:using MODER15=reg_t&lt;rw_t, 0x48001400, 30, 2&gt; 但我改变了它,试图允许使用某种指针,但失败了。
  • “你会使用吗?” 好吧,如前所述:在某些目标平台#define 依赖于config.h 标头中,您的HAL 的客户端应该@ 987654332@.

标签: c++ embedded


【解决方案1】:

这会有帮助吗? 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);

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

【讨论】:

  • 仅供参考,这不应该是一个答案。您可能应该编辑您的问题并向其添加其他信息,而不是添加此答案。
猜你喜欢
  • 2017-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多