2011-09-26 58 views
1

我有一個叫做interrupt_Foo() {...}的中斷函數,它在1秒過去時打開一個標誌,並且一個用戶定義的函數foo_calling() {...}調用另一個函數foo_called() {...}。我想在1秒鐘內停止foo_called()的過程。中斷退出功能

的代碼片段可如下闡述進一步我需要:

void interrupt interrupt_foo() { 
    ... 
    if(1 second has elapsed) { 
     flag1s = 1; 
    } else { 
     flag1s = 0; 
    } 
} 

void foo_calling() { 
    // need something here to stop the process of foo_called() 
    ... 
    (*fptr_called)(); // ptr to function which points to foo_called 
    ... 
} 

void foo_called() { 
    // or something here to stop the process of this function 
    ... 
    // long code 
    ... 
} 

這是實時操作系統,以便輪詢1個第二標誌內foo_called()在代碼中的一些部分是不希望的。請幫忙。

+2

否則怎麼你所期望的功能停止不投票的標誌?你寧願殺死線程嗎?這聽起來不像是最好的選擇恕我直言。 –

+0

這是我的問題。由於這是針對微控制器(即PIC)的,所以線程可能具有複雜的實現。如果在微控制器中做先發制人的RTOS似乎是不可能的,那麼我會採用輪詢而不是最後的手段。 –

+1

我和傑夫在一起,我認爲解決這個問題的唯一方法就是通過查詢這個變量。根據foo_called()中的內容,有很多聰明的方法可以進行輪詢,比如使用標記值或類似的東西。我看到你解決這個問題的唯一方法是,如果你正在編寫/編輯實時操作系統,並以某種方式改變信號處理程序中的TCB,並且有一種聰明的方法來管理它。 – dbeer

回答

2

如果你願意寫不可移植的代碼,並且在部署之前測試赫克出來,如果處理器支持的話,有可能是一個解決方案。

當中斷處理程序被調用時,返回地址必須存儲在某個地方。如果這是您的代碼可以查詢的位置 - 就像堆棧中的固定偏移量 - 那麼您可以將該地址與函數佔用的範圍進行比較,以確定是否正在執行foo_called。您可以通過存儲虛擬地址,編譯,解析映射文件,然後更新地址並重新編譯來獲取函數的地址。

然後,如果你的處理器支持的話,你可以用foo_called最後一條指令(一個或多個)地址替換返回地址。 (確保包含堆棧清理和註冊恢復代碼。)。然後正常退出中斷,中斷處理邏輯將代碼返回到中斷函數的結尾。

如果返回地址沒有存儲在堆棧中,但在一個不可寫的寄存器,你仍然可以強制退出的功能 - 如果可執行代碼在內存writrable。只需將指令存儲在interruupt的返回地址,然後用跳轉到函數結束的跳轉指令覆蓋它。在呼叫者代碼中,添加一個檢測器來恢復覆蓋的指令。

1

我希望你的RTOS具有某種定時信號/中斷,你可以用它來通知你當了1秒鐘過去了。例如,如果它是一個實時的UNIX/Linux,那麼您將爲SIGALRM設置一個信號處理程序一秒鐘。在Linux的RT版本上,此信號比非RT版本具有更多的粒度和更好的保證。但是,將信號設置爲略低於一秒並且忙等待(循環)直到達到一秒鐘仍然是一個好主意。