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(),这个是从
看到的。
3.接下来的测试无非就是新建一个Task,然后等待mail到来,这是ucos的内容,这里不再赘述。