基於Blackfin構架體系的DSR實現


        對於操作系統內核有些了解的朋友應該對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的情況。


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com