C ++中的中断服务程序

时间:2016-07-19 19:08:57

标签: c++ delegates interrupt-handling isr

对于实时嵌入式系统,我试图提供一个中断处理程序,它允许注册任何非静态方法指针(当然还有对象的实例), ,当发生中断时。

在C中,这很容易做到,例如:

CALayer

Afaik,这符合这个调用C ++在调用非静态方法时隐式执行的操作。

然而,C ++编译器拒绝将方法指针强制转换为函数指针(至少我发现没办法这样做) - 这当然是可以理解的,但在我的情况下会产生相反的效果。

有没有办法像C一样直接模拟C ++ this-call? 我知道代表,但是我的编译器仅限于C ++ 98,没有boost库等;甚至自定义轻量级实现,例如谢尔盖梁赞诺夫的不可能快速的C ++代表,如果可能的话,提供一些我想避免的开销。

1 个答案:

答案 0 :(得分:1)

方法始终包含隐藏的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()
实现

以执行ISRHandlerClassISRHandlerClass的孩子需要做的任何事情。

你几乎被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;