使用 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++
是否可以使用 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++