blievethink 发表于 2009-7-3 11:31:30

统一的中断处理函数设计问题

/* -----------------------------------------------------------------------
*                              EOSIrqHandle( void )
* 功能: 统一的中断处理句柄
* 参数: 无
* 返回值:无
* 说明: 无
* ----------------------------------------------------------------------- */
void    EOSIrqHandle( uint8 vect ) __attribute__((naked))
{
    IRQ_ENTRYentry;
    uint8   vect;
    OS_ARCH_VAR;

    ARCH_IRQ_DISABLE_ALL();                                       /* 关中断               */
    ARCH_SAVE_CONTEXT();                                          /* 保存上下文         */

    if( irq_cnt < 255 )                                             /* 中断计数增1         */
    {
      irq_cnt++;
      if( irq_cnt == 1 )
      {
            OSTCBCur->stk_top = ARCH_GET_SP();                      /* 保存堆栈指针          */
            ARCH_SET_SP( &irq_stk[ EOS_IRQ_STK_LEN - 1 ] );         /* 使用专用的堆栈区      */
      }
    }

//    vect = ARCH_GET_VECT();                                       /* 取发生的中断向量号    */
    entry = irq_tbl.irq;

    ARCH_IRQ_ENABLE_ALL();

    if( entry != ( IRQ_ENTRY)0 )                                 /* 调用相应的中断处理函数 */
      ( * entry )( );

    if( --irq_cnt == 0 )                                          /* 如果是在中断最外层,调度 */
    {
      OSScheduler();
    }
}

  如上面的代码所示,我想让ATMEGA32的所有中断由统一的处理函数EOSIrqHandle处理.
  我的问题主要在于如何让EOSIrqHandle能获取发生的中断的向量号.像S3c44box这样的芯片,可以都过查询某些寄存器来确定.
但atmega32可供查询的寄存器较多,我想如果通过检测这些寄存器的标志位来判定中断是否发生,显然效率太低.另一种方面是再为
每个中断写一个简单的ISR处理程序,在该ISR里,可直接将向量号通过参数传递给EOSIrqHandle,再调用EOSIrqHandle.但这样
做的话,EOSIrqHandle的结构需要重写,并且上下文保存,堆栈指针保存的C代码,必须放到小的ISR中去了.

  我只看过ucos的中断管理方法,比较烦琐.有没有人能提供一种更好点的中断管理方式?

ralfak 发表于 2009-7-6 22:50:47

有,你得自己改
除了时钟节拍中断需要每次都保护所有的现场
其余中断先让编译器保护现场
关中断
nesting+1
开中断
然后根据中断处理函数里面是否有高优先级任务触发来置一个标志位,例如missedScheduler
nesting-1
if(missedScheduler)
{ARCH_SAVE_CONTEXT();                                          /* 保存上下文         */
OSScheduler();
}
这样就可以了
页: [1]
查看完整版本: 统一的中断处理函数设计问题