分类:
2009-11-05 11:11:20
今天看到keil的一个例子,里面涉及到利用typedef和指向函数的指针结合的例子,使得程序结构体系非常明了,觉得很好,特地记下来。
首先在头文件定义了这个指针,并用typedef将其声明为一个类型:
typedef void (*HandlerAddr)(void);
这里面定义了一个HandlerAddr的指针变量,该指针变量指向一个参数和返回值都为void类型的函数。这种类型的函数正好对应中断服务函数。中断服务函数不能有参数,也没有返回值。
然后用typedef将其声明为一个类型。然后在别的文件中可以利用这种类型进行重新定义。
然后在.c文件定义一些变量。
HandlerAddr IntVectTable[3][32]; /* 0 is MIC, 1 is SIC1, 2 is SIC2 */
这里定义了一个3*32的数组,该数组的第0行代表MIC中断控制器,第一行代表SIC1中断控制器,第二行代表SIC2中断控制器。每一个数据元素表征一个中断函数的入口地址。
在使用时,以IRQ_Exception为例:
void __irq IRQ_Exception( void )
{
HandlerAddr IRQHandler;
int i;
/* The first while loop is to take care of MIC1 interrupts. */
while ( (MIC_SR != 0) && (!(MIC_SR & 0x01)) && (!(MIC_SR & 0x02)) )
{
for ( i = 31; i >= 0; i-- )
{
if ( MIC_SR & (1< {
if ( IntVectTable[0][i] != NULL )
{
IRQHandler = IntVectTable[0][i];
if ( MIC_ATR & (1< {
MIC_RSR |= (1< }
(*IRQHandler)();
}
else
{
if ( MIC_ATR & (1< {
MIC_RSR |= (1< }
}
}
}
}
..........
return;
}
以一句IRQHandler = IntVectTable[0][i];获得某个中断函数的地址,然后直接通过 (*IRQHandler)();调用该函数。
说明:指向函数的指针一般用在两类地方,一种是如本例,实现函数回调。另一种为用在结构体中,在c语言中实现某些面向对象的例子。