使用 class 方法的 C++ ISR?

C++ ISR using class method?

是否可以使用 class 方法作为中断服务程序?

我有一个 ISR 编写并使用函数在 C 中工作:

    static void interrupt far ISR(...) {}

我尝试在 C++ 中创建一个方法(原型):

    void interrupt far ISR(...);

然后执行:

    #pragma interrupt
    void interrupt far MyClass::ISR(...) {
    ...
    }

但是当我尝试将其与 'setvect' 一起使用时出现各种错误:

    setvect(muint16Vector, &ISR);

我正在尝试编写一个 class 来为串行端口提供服务,ISR 将为来自该端口的 Rx 数据提供服务。然后,ISR 将使用特定于实例的成员。

我有3个串口,所以我想创建3个class实例。

您只需要创建一个全局变量,它是要调用的实例:

class Handler {
  void ISR(...) {}
};

static unique_ptr<Handler> g_handler;

#pragma interrupt
extern "C" static void interrupt far ISR(...) {
  if (g_handler)
    g_handler->ISR(...);
}

g_handler = std::make_unique<Handler>();
setvect(muint16Vector, &ISR);

根据评论中给出的信息,这是一个可能的解决方案:

class SerialPort
{
public:
    // Unrelated functions...

    void isr();  // The serial interrupt handler

    // Other unrelated stuff...
};

std::array<SerialPort, 3> serial_ports;  // Or SerialPort serial_ports[3];

static void serial_isr(int const port_index)
{
    // Common code for all serial ports that for some reason
    // can't be in the class...

    serial_ports[port_index].isr();  // Call actual ISR
}

extern "C" void interrupt serial_isr_1()
{
    // Special code for only this serial port...

    serial_isr(0);
}

extern "C" void interrupt serial_isr_2()
{
    // Special code for only this serial port...

    serial_isr(1);
}

extern "C" void interrupt serial_isr_3()
{
    // Special code for only this serial port...

    serial_isr(2);
}

真正的答案是 'No' 在 C++ 中不可能直接使用方法作为 ISR 处理程序。

您必须求助于标准 C 函数,然后在 ISR 函数中使用胶水,引用所需的对象。

结果是一个相当混乱的解决方案。

Dobbs 博士的一篇旧文章对此进行了很好的介绍,并对所涉及的问题进行了很好的解释:Implementing Interrupt Service Routines in C++