C++ ISR using class method?

那年仲夏 提交于 2019-12-12 17:15:54

问题


Is it possible to use a class method as the Interrupt Service Routine?

I have an ISR written and working in C using a function:

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

I've tried in C++ to create a method (prototype):

    void interrupt far ISR(...);

Then the implementation:

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

But I get all sorts of errors when I try to use this with 'setvect':

    setvect(muint16Vector, &ISR);

I'm trying to write a class to service a serial port, the ISR would service the Rx of data from the port. The ISR would then use instance specific members.

I have 3 serial ports, so I would like to create 3 instances of the class.


回答1:


With the information given in the comments, this is a possible solution:

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);
}



回答2:


You just need to create a global variable which is the instance to invoke upon:

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);



回答3:


The real answer is 'No' it is not possible in C++ to use a method as the ISR handler directly.

You have to resort to standard C functions and then with glue in the ISR function, reference the required object.

It ends up as quite a messy solution.




回答4:


There's an old Dr. Dobbs article that covers this well, along with a good explanation of the issues involved: Implementing Interrupt Service Routines in C++



来源:https://stackoverflow.com/questions/41184234/c-isr-using-class-method

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!