Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1050032
  • 博文数量: 178
  • 博客积分: 10222
  • 博客等级: 上将
  • 技术积分: 2215
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-03 11:27
个人简介

有所追求

文章分类

全部博文(178)

文章存档

2012年(1)

2011年(5)

2010年(3)

2009年(78)

2008年(91)

我的朋友

分类: BSD

2008-03-12 10:15:01

     

1、向量中断模式(也叫矢量中断模式)
      为了缩短中断模式在进入所需的服务前所需要的中断响应时间,S3C44B0提供了一种新的中断模式——矢量中断模式。当多重中断源请求中断时,硬件优先级逻辑会判断哪一个中断将会被执行,同时,硬件逻辑自动执行由0x18地址到各个中断源向量地址的跳转指令,然后再由中断源向量进入相应的中断处理程序。简单的说,每个中断源对应一个内存地址,只要在对应的地址上设置一条到中断服务程序的跳转指令,CPU自动跳转到响应的中断处理函数。和原来的软件实现方式相比,这种方式可显著缩短中断响应时间。
 
2、非向量中断模式
      在非向量中断模式下,有两种方式可以使PC指向相应的中断处理程序。

      第一种方法,可以通过对I_ISPR/F_ISPR寄存器的分析判断出中断的类型,然后再把PC指向相应的中断处理程序。其中HandlerXXX实际上是一段跳转程序,运行这段程序将把HandleXXX指向的内容值赋给PC。由于HandleXXX所对应的地址中,存放的是每个相应的ISR的起始地址,这样就完成了向特定ISR的调转。这些ISR地址存放在HandleXXX指向的表项中,该表一般定位在RAM高端,基地址为ISR_STARTADDRESS。
      第二种方法,对于IRQ处理程序可以通过对I_CMST寄存器的分析来判断中断源的类型,然后再把PC指向相应当中断处理程序。

      之所以被称为向量中断模式,是因为它不需要用程序判断中断源,通过硬件实现直接跳转到相应ISR。而非向量中断必须在中断服务程序中判断中断来源,进而跳转到不同的处理程序。

      在非向量中断模式下,中断响应流程如下:
      1、通常情况下,CPU内核收到来自中断控制器的IRQ中断请求,会在0x00000018处执行一条指令,在从0x00000018处取指令时,中断控制器会在数据总线上加载分支指令。这些分支指令使程序计数器能够对应到每一个中断源的向量地址。所以,一般会在从0x00处到0xA0处放置跳转指令,跳转到HandlerXXX处。
 
      2、HandlerXXX处一般放置汇编下面的一段中断处理宏(一般定义为HANDLER),入口是跳转地址,
      主要流程:
              栈空间递减保存跳转地址
              保存工作寄存器R0到栈
              载入中断入口地址所在位置到R0
              载入中断入口地址到R0
              保存中断入口地址到栈
              恢复工作寄存器并跳转到中断函数
      通过如下一系列宏跳转到HandleXXX:HandlerXXX        HANDLER        HandleXXX(HandlerXXX是汇编标号)
      HandleXXX一般是定义在存储器高端的中断入口向量定义表,存放中断处理函数的指针。
      内存中的HandleIRQ地址处存放总中断入口处理函数指针。这个函数的实现其中一个方法如下:

            static ISR_HANDLER_IRQ IsrHandler[NINT_NUMBERS];        //定义中断跳转表

            void IrqIsr(void)
            {
                int nInt;
                INT32U temp,i;
                ISR_HANDLER_IRQ pIsr;
        
                if((temp = rI_ISPR) == 0)              //读出中断挂起寄存器
                        return;
                for(i=0; i<26; i++)                    //转换成中断编号
                {
                        if(temp & 0x1 == 1)
                              break;
                        else
                              temp = temp >> 1;
                }
        
                nInt = i;
                if(nInt == 26)
                        return;
        
                pIsr = IsrHandler[nInt];
                if(pIsr)
                        (*pIsr)();                      //执行中断服务程序
                else
                        CLEAR_PENDING_BIT(nInt);        //清空中断标志位
            }

            //中断装载函数:
            int OSInstallIsr(int nInt,ISR_HANDLER_IRQ pIsr)
            {
                if(nInt > NINT_NUMBERS || nInt < 0 || !pIsr)
                        return 0;
        
                IsrHandler[nInt] = pIsr;
                        return 1;
            }
阅读(1481) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~