嵌入式:如何在 C++17 中用 lambda(指向成员的指针)替换中断向量调用

问题描述 投票:0回答:1

目前我有一个问题。我想替换外设驱动程序的中断向量目标调用。现在有效的是:

namespace test
{
  class PortDriver{
  public:
      using InterruptHandler = void(*)();

      constexpr explicit PortDriver(const uint16_t targetAddress) {
          // Assign the interrupt handler directly to the target address
          *reinterpret_cast<InterruptHandler*>(targetAddress) = irqPort;
      }

      static void irqPort(void) 
      {
          ...
      }
  };

但这不是我想要的。我想用指向成员函数的指针实例化它。所以当我这样做时:

    constexpr uint16_t targetAddress1 = 0xFFD8;
    PortDriver<targetAddress1> port1Driver;

    constexpr uint16_t targetAddress2 = 0xFF09;
    PortDriver<targetAddress2> port2Driver;

我想要为必须创建的两个中断向量创建两个 irq 函数。由于性能问题,最好是在编译时。

我不知道这是否以及如何运作。也许用 lambda 但我不知道怎么做。

它应该看起来像这样:

template <uint16_t TargetAddress>
class PortDriver {
public:
    using InterruptHandler = void(*)();
    constexpr explicit PinDriver() {
        // Assign the interrupt handler using a lambda function
        *reinterpret_cast<InterruptHandler*>(TargetAddress) = [this]() { irqHandler(); };
    }

    void irqHandler() {
       ...
    } 
};

但这不能编译

lambda c++17 embedded interrupt pointer-to-member
1个回答
0
投票

也许是这样的:

template <uint16_t TargetAddress>
class PortDriver {
public:
    using InterruptHandler = void(*)();

    static void Register() {
        *reinterpret_cast<InterruptHandler*>(TargetAddress) = irqHandlerTrampoline;
    }

    static PortDriver& Instance() {
      static PortDriver driver;
      return driver;
    }

    static void irqHandlerTrampoline() {
      Instance().irqHandler();
    }

    void irqHandler() {
       // ...
    } 
};

// To initialize, call
PortDriver<targetAddress1>::Register();

基本上,将每个端口的驱动程序变成单例;我认为每个端口有多个驱动程序是没有意义的。

© www.soinside.com 2019 - 2024. All rights reserved.