2013-02-28 56 views
5

我希望能寫我的ISR在一個地方:如何在C++中生成中斷處理程序的編譯時數組?

some_collection TimerHandlers;  

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

,這樣我就可以在其他文件

// 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 

而當硬件寄存器處理器跳轉到rawTimerIRQHandler,它以某種任意的順序執行ledTimerHandler1ledTimerHandler2


很顯然,我可以實現這個使用了一種類似於vector<void(*)()>東西,但由於這些處理程序在編譯時已知的數量,有沒有什麼辦法,我可以生成一個數組(或模板鏈表)在編譯時?我想避免vector附帶的動態內存分配。

我願意使用template<>#define甚至GCC特有的屬性來實現這個目標。

+0

[This](http://stackoverflow.com/a/8688526/102441)看起來潛在相關 – Eric 2013-02-28 18:27:30

回答

4

腳手架有點乏味但一旦它的完成使用簡單得不能再簡單:

// 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 

編輯:移動first,second,third聲明/定義來滿足我內心的學究

+0

非常聰明!我不知道爲什麼我沒有看到靜態字段和構造函數作爲創建全局初始狀態的方式。我已經走向鏈接列表。一旦我在我的環境中工作,我會接受。 – Eric 2013-02-28 18:35:26

+0

是否可以將'template <> example * Registered :: registry = 0;'移至'Registered.h'中模板的定義之內? – Eric 2013-02-28 18:38:51

+0

此外,大概我可以在非靜態上下文中使用它,並使每個元素在限制器中自行移除。 – Eric 2013-02-28 23:46:23

1

Absolutley。如果我理解正確,你只需要一個固定的數組指針給你的處理程序。使用C++ 11的語法,並假定3個處理程序只是爲示例的目的,

#include <array> 

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

或使用更經典的C/C++語法

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

我想我錯過了重要的東西在這裏。我寧願不必在一個文件中手動構建數組。我希望在每個文件中定義一些技巧,並讓編譯器(或鏈接器)爲我構建數組。這樣,我就可以從構建中排除測試,並且也可以排除它們的中斷處理程序,而無需進行任何源代碼修改。 – Eric 2013-02-28 18:00:35

+0

我明白了。我不理解這個問題,我很抱歉。 – 2013-02-28 18:00:56

+0

你可能已經幫助澄清了其他人。我很難用言語表達這個問題。 – Eric 2013-02-28 18:02:01

0

基於關閉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;