C++中的中断服务例程
Interrupt service routine in C++
对于实时嵌入式系统,我试图提供一个中断处理程序,它允许注册任何非静态方法指针(当然还有对象的实例),当中断发生时,它会被调用。
在C中,这很容易做到,例如:
void (*func)(void*) = 0; // <- method to be called goes here
void* instance; // <- instance for this-call goes here
void InterruptHandler()
{
func(instance);
}
当然,这符合C++在调用非静态方法时隐式执行的this调用。
然而,C++编译器拒绝将方法指针转换为函数指针(至少我没有找到这样做的方法)——这当然是可以理解的,但在我的情况下会适得其反。
有什么方法可以像在C中那样直接模拟C++这个调用吗?我知道委托,但我的编译器仅限于C++98,没有boost库等;甚至自定义的轻量级实现,例如Sergey Ryazanov的Impossibly Fast C++Delegates,也提供了我希望尽可能避免的一定开销。
方法总是包含一个隐藏的this
参数,以提供对被调用对象的访问。要从一个中断处理程序中调用一个类,该类期望C或类似C的调用行为,所列参数和所需参数之间的对应关系为1:1,则必须提供类似C的行为。这意味着没有隐藏参数的自由函数或静态方法。
这意味着,如果不深入研究关于未定义行为的假设,就无法将方法分配给函数指针。
但是,如果对象可用,则可以让静态方法或自由函数调用对象上的方法。
给定
void (*func)(void*)
当void *
是指向用户提供的控制信息的指针时,简单的解决方案是形式的静态方法或自由函数
void handlerCaller(void* userp)
{
ISRHandlerClass * handlerp = (ISRHandlerClass *) userp;
handlerp->isrhandler(); // tiny bit may be lost here to subclass look-up
}
和
void isrhandler()
实现为执行检查ISRHandlerClass
或ISRHandlerClass
的子级需要执行的任何操作
你几乎被handlerCaller
或类似的东西卡住了,所以这是你无法避免的开销。其余的取决于您希望ISR接口的通用性
一个简单的通用ISR处理程序基类:
class ISRHandlerClass
{
public:
virtual ~ISRHandlerClass()
{
}
// pure virtual to be implemented by specialized handler
virtual void isrhandler() = 0;
};
和一个同样简单的实现
class FooHandler: public ISRHandlerClass
{
public:
void isrhandler() //override tag if you've got 'em
{
// read Foo and store in buffer to be processed by lower priority task
}
};
但是,如果你想抛弃泛化而追求速度,就不要考虑子类。如果需要多个处理程序调用程序,则需要为其牺牲空间。
void FooHandlerCaller(void* userp)
{
FooHandler * handlerp = (FooHandler *) userp;
handlerp->isrhandler();
}
void BarHandlerCaller(void* userp)
{
BarHandler * handlerp = (BarHandler *) userp;
handlerp->isrhandler();
}
或
template <class TYPE>
void handlerCaller(void* userp)
{
TYPE * handlerp = (TYPE *) userp;
handlerp->isrhandler();
}
使用
class FooHandler
{
public:
void isrhandler()
{
// read Foo and store in buffer to be processed by lower priority task
}
};
void (*func)(void*) = handlerCaller<FooHandler>;
FooHandler handler;
void* instance = (void *)&handler;
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- c++类声明时,相同的例程,不同的成员变量类型
- C++为线程工作动态地分割例程
- 子例程,不使用 pow,并带有参数和返回
- 直接在RcppArmadillo中调用LAPACK例程
- 如何将C++子例程链接到 x86 程序集程序?
- PX 转换例程编译问题
- 如何使用 SIGINT 在第二个线程中断 getchar
- 成功完成TLS握手后,服务器关闭时出现错误的SSL例程:SSL3_GET_RECORD:错误的版本号
- 只允许授权代码调用库中的例程
- JNI 不满意链接错误: 动态链接库 (DLL) 初始化例程失败
- 调用子例程时类型不匹配
- 将分配给C++数组传递给 Fortran 子例程
- 如果在例程中,Gdb 会在错误时中断
- 将方法附加到 c++11 中的中断例程
- 在中断例程中使用C++对象(和volatile)的正确方法是什么
- 中断 arduino 例程以运行基于延迟的慢速进程
- 我的中断例程无法正确访问数组
- 作为中断服务例程的静态模板成员函数
- C++中的中断服务例程