基於Blackfin構架體系的DSR實現

zenny_chen發表於2007-10-09

        對於作業系統核心有些瞭解的朋友應該對DSR不會感到陌生——Deferred Interrupt Service Routine,即延遲的中斷服務例程。

         對於一些操作較複雜、耗時的操作我們往往想將它從中斷服務例程中拿出來,放在外面完成。這樣可以加快中斷響應時間,對於一些緊迫的事件處理則顯得更為重要。因此應該提供一個DSR這樣的機制。這個在Windows和Linux中均有體現。

        下面我將談談在Blackfin DSP處理器系列中對DSR的一種處理方法。

        其實對於一些並不緊急、完全可以拖後操作的事情甚至可以通過一個任務(執行緒)專門處理這些事件。在Linux中,DSR的處理分為三個不同的機制,其中有一個實際上是在某些檢查點(如系統中斷處理結束後、定時中斷處理結束後、任務排程結束後等等)檢查是否有DSR事件,如果有則處理它們。那麼下面我將基於這種情況作出處理。

 

// 某個中斷處理例程
extern void test(void);

// 軟體中斷處理例程
extern void soft_isr(void);

int main(void)
{
    
// 將test註冊到IVG13系統中斷向量
    *(unsigned long*)0xffe02034 = (unsigned long)&test;
    
    
// 將soft_isr註冊到IVG14軟體中斷向量
    *(unsigned long*)0xffe02038 = (unsigned long)&soft_isr;
    
    
// 開啟所有中斷開關
    *(unsigned long*)0xffe02104 = 0xffff;
    
    
// 直接通過核心將中斷號為13的系統事件中斷髮給核心中斷控制器(這裡模擬一個外部中斷事件)
    asm("raise 13;");
    
    
return 0;
}


 

        以上是一個C檔案。這裡對Blackfin的中斷控制器做一下簡單介紹:Blackfin中斷控制器分為16箇中斷優先順序,0~4是非遮蔽中斷,7到13屬於外部系統中斷,14、15屬於軟體中斷。

        下面貼出核心的彙編部分程式碼:

 

.section program;


.
global _soft_isr;
.
global _user_isr_callback;


// DSR處理函式
execute:

    
// 呼叫使用者的DSR處理例程
    call _user_isr_callback;
    
    
// 作為軟體中斷的引數,這裡0表示準備結束DSR處理
    r0 = 0;
    
    
// 釋出14號中斷(程式碼將跳往_soft_isr)
    raise 14;
        idle;
    
execute.end:



_test:

    .
global _test;
    
    
// 中斷入口,保護相關的暫存器
    [--sp= astat;
    [
--sp= p0;
    [
--sp= r0;
    [
--sp= rets;
    
    
// 這裡用兩個nop表示中斷例程中先處理一些事務
    nop;
    nop;
    
    
// 這裡是關鍵步驟:
    
// 將中斷返回暫存器的值先賦給r0
    r0 = reti;
    
// 將這個值壓棧
    [--sp= r0;
    
    
// r0指向execute子過程的首地址
    r0.h = hi(execute);
    r0.l 
= lo(execute);
    
    
// 將execute的入口地址賦給中斷返回暫存器
    reti = r0;
    
    
// 這裡將返回到execute子過程
    rti;
    
_test.end:



_soft_isr:

    
// 判斷軟體中斷引數
    cc = r0 == 0;
    
if !cc jump SOFT_ISR_OTHER;
    
    
// 如果是作為DSR的結束處理:
    
// 恢復上下文暫存器
    
// 將reti恢復為原來被中斷的下一條指令地址處
    r0 = [sp++];
    reti 
= r0;
    rets 
= [sp++];
    r0 
= [sp++];
    p0 
= [sp++];
    astat 
= [sp++];
    
    
SOFT_ISR_OTHER:

    
// 中斷返回
    rti;
    
_soft_isr.end:


// 使用者DSR處理例程
_user_isr_callback:

    p0 
= 0;
    r0 
= 100;
    r0 
= r0 -|- r0 || [p0++= r0;
    [p0
++= r0;
    
    rts;
    
_user_isr_callback.end:

 

        以上是對中斷處理一結束馬上處理DSR的情況。

相關文章