简体   繁体   English

如何在C ++中生成中断处理程序的编译时数组?

[英]How can I generate a compile-time array of interrupt handlers in C++?

I'd like to be able to write my ISR in one place: 我希望能够在一个地方编写我的ISR:

some_collection TimerHandlers;    

// added to ISR table in linker script
void rawTimerIRQHandler() {
    call_each_handler_in(handlers);
}

Such that I can then register handlers in other files 这样我就可以在其他文件中注册处理程序

// file1.cpp
void ledTimerHandler1() {

}
register(ledTimerHandler1); //or in an init function if not possible here
// file2.cpp
void ledTimerHandler2() {

}
register(ledTimerHandler2); //or in an init function if not possible here

And when the hardware jumps to rawTimerIRQHandler , it executes ledTimerHandler1 and ledTimerHandler2 in some arbitrary order. 当硬件跳转到rawTimerIRQHandler ,它将以任意顺序执行ledTimerHandler1ledTimerHandler2


Obviously, I can implement this using something similar to a vector<void(*)()> , but since the number of these handlers is known at compile-time, is there any way I can generate an array (or template linked list) at compile-time? 显然,我可以使用类似于vector<void(*)()>来实现此目的,但是由于这些处理程序的数量在编译时是已知的,因此有什么方法可以生成数组(或模板链接列表)在编译时? I'd like to avoid the dynamic memory allocation that comes with vector . 我想避免vector附带的动态内存分配。

I'm open to using template<> , #define , or even GCC-specific attributes to acheive this goal. 我愿意使用template<> ,# #define甚至GCC特定的属性来实现此目标。

The scaffolding's a bit tedious but once it's done the usage couldn't be simpler: 脚手架有点乏味,但是一旦完成,使用起来再简单不过了:

// example.h:
#include "Registered.h"
struct example : Registered<example> {};
// main.cc:
#include <iostream>
#include "example.h"

int main ()
{
    for ( auto p = example::registry; p; p=p->chain )
        std::cout << p << '\n';
}
// Registered.h : 
template<class registered>
struct Registered {
     static registered *registry;
     registered *chain;
     Registered() : chain(registry) {registry=static_cast<registered*>(this);}
};
// example.cc:
#include "example.h"
template<> example *Registered<example>::registry = 0;

static struct example first, second, third;  // these can be defined anywhere w/ static duration

edit: moved the first,second,third declaration/definitions to satisfy my inner pedant 编辑:移动first,second,third声明/定义,以满足我的内心学究

Absolutley. 绝对的。 If I understand correctly, you just want a fixed array of function pointers to your handlers. 如果我理解正确,则只需要指向处理程序的固定函数指针数组即可。 Using C++11 syntax, and assuming 3 handlers just for the sake of the example, 使用C ++ 11语法,并仅出于示例目的假设3个处理程序,

#include <array>

const std::array<HandlerPtr, 3> handlers= {&ledTimerHandler1, &ledTimerHandler2, &ledTimerHandler3};

or using more classic C/C++ syntax 或使用更经典的C / C ++语法

const HandlerPtr handlers[] = {&ledTimerHandler1, &ledTimerHandler2, &ledTimerHandler3};

Based off jthill's answer, here's what I'll probably end up using (since I don't need a generic form): 根据jthill的回答,以下是我可能最终会使用的内容(因为我不需要通用形式):

struct timer_handler {
    static timer_handler *first = 0;
    timer_handler *next;
    void (*f)();
public:
    timer_handler(void (*f)()) : next(first), f(f) { first = this;}

    // connect this to the interrupt vector
    static inline void executeAll() {
        auto p = first;
        while(p) {
            p->f();
            p = p->next;
        }
    }
};
//a.cpp
void foo() {

}
timer_handler tfoo = foo;
//b.cpp
void bar() {

}
timer_handler tbar = bar;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM