目前我有一个问题。我想替换外设驱动程序的中断向量目标调用。现在有效的是:
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() {
...
}
};
但这不能编译
也许是这样的:
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();
基本上,将每个端口的驱动程序变成单例;我认为每个端口有多个驱动程序是没有意义的。