Chinaunix首页 | 论坛 | 博客
  • 博客访问: 276977
  • 博文数量: 95
  • 博客积分: 2047
  • 博客等级: 大尉
  • 技术积分: 1022
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-14 16:18
文章分类

全部博文(95)

文章存档

2013年(1)

2011年(94)

我的朋友

分类: 嵌入式

2011-08-30 22:57:29

SEP4020的中断共有32位,用一个寄存器来保存中断产生信号,当产生中断时,对应寄存器那一位将置位。

获取中断控制函数的方式是建立一个32位的数组,将所有中断处理函数保存在数组中,如下:
INT_VECTOR vector[] =
{
       /* interrupt number,   handler */
  {  INTSRC_NULL,             NULL },
  {  INTSRC_EXINT0,          EntIntKey },
  {  INTSRC_EXINT1,          EntIntKey },
  {  INTSRC_EXINT2,          EntIntKey },
  {  INTSRC_EXINT3,          EntIntKey },
  {  INTSRC_EXINT4,          EntIntKey },
  {  INTSRC_EXINT5,          NULL },
  {  INTSRC_EXINT6,          NULL },
  {  INTSRC_EXINT7,          NULL },
  {  INTSRC_EXINT8,          NULL },
  {  INTSRC_EXINT9,          NULL },
  {  INTSRC_EXINT10,        NULL },
  {  INTSRC_SDIO,             NULL },
  {  INTSRC_SMC1,            NULL },
  {  INTSRC_SMC0,            NULL },
  {  INTSRC_USB,               NULL },
  {  INTSRC_NULL,             NULL },
  {  INTSRC_SSI,                NULL },
  {  INTSRC_I2S,                NULL },
  {  INTSRC_LCDC,             NULL },
  {  INTSRC_PWM,             NULL },
  {  INTSRC_UART3,           NULL },
  {  INTSRC_UART2,           NULL },
  {  INTSRC_UART1,           NULL },
  {  INTSRC_UART0,           NULL},
  {  INTSRC_TIMER3,          NULL },
  {  INTSRC_TIMER2,          NULL },
  {  INTSRC_TIMER1,         NULL },
  {  INTSRC_MAC,              NULL },
  {  INTSRC_EMI,               NULL },
  {  INTSRC_DMAC,            NULL },
  {  INTSRC_RTC,               NULL },
};

判断中断的方式是通过不断移位,获取被置位的中断源:
void int_vector_handler(void)
{
    U32 intnum;
    U8 i = 0;
        intnum = *(RP)(INTC_IFSR);  //读取IRQ 中断最终状态寄存器获得中断号
        while (intnum != 1)
    {
        intnum = intnum >> 1;
        i++;
    }
        (*vector[i].handler)(); //通过调用相应的处理函数
    
    return ;
}

姑且不讨论这种方法是否符合SEP4020的中断优先级,采用移位方法判断中断源,best需要O(1),worst需要O(32),效率太低,让我们讨论下有何改进方法。

改进算法1:
采用二分法,32bit需要5次可以找到我们想要的位置

           XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
              |        |
1)         XXXXXXXXXXXXXXXX  XXXXXXXXXXXXXXXX
          |   |        |   |
2)      XXXXXXXX XXXXXXXX     XXXXXXXX XXXXXXXX
        | |  | |      | |  | |
3)     XXXX XXXX XXXX XXXX     XXXX XXXX XXXX XXXX
      || || || ||   || || || ||
4)    XX XX XX XX XX XX XX XX   XX XX XX XX XX XX XX XX 
  | | | |  | | | |  | | | |  | | | |  | | | |  | | | |  | | | |  | | | |  
5)X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X 

Time=O(5)

改进算法2:
若查表,可以获得最快的速度,但是32bit组成的表足有2^32=4G之大。
若将32bit分成两个16bit的表,可将表缩小为2^16=65536,还是比较大。
若将32bit分成四个8bit的表,可将表缩小为2^8=256,同时这四张表可以复用!

Pseudocode

tablenum <- (intnum & 0xFFFFFF00)
if tablenum  is not zero
i<- table[tablenum]
goto end;

tablenum <- (intnum & 0xFFFF00FF)>>8)
if tablenum  is not zero
i<- table[tablenum]+8
goto end;

tablenum <- (intnum & 0xFF00FFFF)>>16)
if tablenum  is not zero
i<- table[tablenum]+16
goto end;

tablenum <- (intnum & 0x00FFFFFF)>>24)
if tablenum  is not zero
i<- table[tablenum]+24
goto end;


Best case  : O(1)
Worest case: O(4)
阅读(1042) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~