ucos II 下用户自定义中断函数的添加

    在ucos下,不仅仅依赖于一个定时器中断作为系统脉搏,很多时候需要添加用户自定义的中断,这里以外部中断为例,拿的是友善的2440的板子做的测试。由于事先对ucos比较陌生,因此整整花费了三天时间才明白其中的调用机制,写下来以作备忘也供大家参考:

    1.首先初始化自己的中断,比如使能中断,设置中断优先级等,以一个很简单的例子,通过一个按键出发外部中断0,在外部中断0的处理函数中post一个消息给测试进程,该进程收到消息以后随便打印一行文字。首先初始化寄存器,使能中断,大概代码入下:

     

void CPU_Init()
{
//0000 0000 1010 0010 1010 1010 1010 1010 1010
/ b.c文件中已经将CON
// rGPGCON = 0xff95ffba;
// rGPGUP = 0xffff; // The pull up function is disabled GPG[15:0]
//外部中断8开,按键应该使能(测试);
testcount=0;
rGPGCON=(rGPGCON & ~3)| 2; //使能GPGCON0为外部中断的形式
rEXTINT1=(rEXTINT1 & ~7)| 2; //将中断设置为下降沿中断

rEINTPEND =(1<<8); //中断8 append寄存器位打开
rSRCPND =(1<<5); //清空中断未决寄存器的EINT8——23标志位
rINTPND =(1<<5); //中断标志寄存器清空

// HandleEINT8_23=(uint32)KeyBoard_INT;
pISR_EINT8_23=(U32)HandleEINT8_23; //填入中断向量


rEINTMASK =rEINTMASK & ~(1<<8); //禁止对外部中断8的屏蔽
rINTMSK =rINTMSK &~(1<<5); //禁止对EINT8_23的屏蔽
Uart_SendString("InterInit Finished!");
}

2. 这里说明一下ocos下中断的实现机制(个人理解)。在2440的版本中,Os_cpu_a.s中可以看到2440init.s的中断向量号:

;Don''t use the label 'IntVectorTable',
;The value of IntVectorTable is different with the address you think it may be.
;IntVectorTable
;@0x33FF_FF20
HandleEINT0 # 4
HandleEINT1 # 4
HandleEINT2 # 4
HandleEINT3 # 4
HandleEINT4_7 # 4
HandleEINT8_23 # 4
HandleCAM # 4 ; Added for 2440.
HandleBATFLT # 4
HandleTICK # 4
HandleWDT # 4
HandleTIMER0 # 4
HandleTIMER1 # 4
HandleTIMER2 # 4
HandleTIMER3 # 4
HandleTIMER4 # 4
HandleUART2 # 4
;@0x33FF_FF60
HandleLCD # 4
HandleDMA0 # 4
HandleDMA1 # 4
HandleDMA2 # 4
HandleDMA3 # 4
HandleMMC # 4
HandleSPI0 # 4
HandleUART1 # 4
HandleNFCON # 4 ; Added for 2440.
HandleUSBD # 4
HandleUSBH # 4
HandleIIC # 4
HandleUART0 # 4
HandleSPI1 # 4
HandleRTC # 4
HandleADC # 4
;@0x33FF_FFA0
END

这一部分就是各个中断函数的中断向量表,当一个中断到来时,会根据中断在向量表的offset跳转到特定的中断处理函数。

然后开始写自己的中断处理函数,注意函数名和给出的句柄名字要一样(不过通过指针赋值我想也是可以的)。

void HandleEINT8_23(void) 
{
//EnterCritical(&r);
OS_CPU_SR cpu_sr;
OS_ENTER_CRITICAL();
OSIntNesting++;
OS_EXIT_CRITICAL();

if(rINTPND==BIT_EINT8_23) {
ClearPending(BIT_EINT8_23);
if(rEINTPEND&(1<<8)) {
rEINTPEND |= 1<< 8;
OSMboxPost(Keyboard_Box,(void *)&msg); //将按键的消息发送到对应邮箱中
}
}

OSIntExit();
// ExitCritical(&r);

// OS_ENTER_CRITICAL(); /* Update the 32-bit tick counter */

// OS_EXIT_CRITICAL();

// char msg='A';
// Uart_SendString("Enter Task3\n");ing("In the Inter!");
// rEINTPEND =(1<<8);
// rSRCPND=(1<<5);
// rINTPND=(1<<5);
//
}

中断处理程序的流程是有讲究的,必须将intnesting++,最后调用OSINTExit(),这个是从

http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3513293&bbs_page_no=1&search_mode=4&search_text=mcu520&bbs_id=9999

看到的。

3.接下来的测试无非就是新建一个Task,然后等待mail到来,这是ucos的内容,这里不再赘述。


posted @ 2012-03-12 20:13  Orig  阅读(1115)  评论(0编辑  收藏  举报