基于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的情况。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值