vxbus每种驱动都要定义一套方法,这些方法可以提供某种类型的服务。比如中断控制器驱动应该定义:
intconnet 中断绑定
intDisconnet中断角绑定
intEnable 中断使能
intDisable 中断关闭
。。。。。
这些方法是把中断控制器的功能进行抽像出来的基本方法,每种控制器都应该提供。那么在vxbus驱动中,这些方法是如何进行声明与定义的呢。先看下面一幅图:
我们发现method是一种ID+handler的结构数组,所有的方法都放进自定义的方法数组中。
在说明这些宏的使用时,我们先看一下宏定义中#与##的用法。
#运算符将一个宏的参数转换为字符串字面量。
比如:
#define PRINT_INT(x) printf(#x " = %d\n", x)
调用
PRINT_INT(i/j);
相当于:
printf("i/j" " = %d\n", i/j);##运算符可以将两个记号(例如标识符)“粘”在一起,成为一个记号。
比如:
#define MK_ID(n) i##n
调用:
int MK_ID(1), MK_ID(2), MK_ID(3);
相当于:
int i1, i2, i3;
那么vxbus中关于方法的声明与定义也是通过几个宏实现的:
#define DEVMETHOD(NAME, FUNC) { (VXB_METHOD_ID)&NAME##_desc, (FUNCPTR) FUNC }//定义方法数据元素
#define DEVMETHOD_END { 0, NULL }//定义方法数据结束
#define METHOD_DECL(NAME) IMPORT char NAME##_desc[];//声明为外部变量
#define DEVMETHOD_DEF(METHOD, STRING) char METHOD##_desc[]=STRING; //定义一个方法的描述字符串
#define DEVMETHOD_CALL(METHOD) ((VXB_METHOD_ID)(&METHOD##_desc[0]))//调用方法
每种驱动的要声明的方法是在target\src\hwif\methods下定义的。比如:
vxbus要定义方法数组时,使用下面的宏先声明要定义的外部函数,比如我们上面说的中断控制器那四个函数:
METHOD_DECL(vxbIntCtlrConnect)
METHOD_DECL(vxbIntCtlrDisconnect)
METHOD_DECL(vxbIntCtlrEnable)
METHOD_DECL(vxbIntCtlrDisable)
声明之后我们使用method结构体将中断控制器驱动提供抽像函数与具体实现对应起来:
LOCAL device_method_t alteraIntCtlr_methods[] =
{
DEVMETHOD(vxbIntCtlrConnect, vxbAlteraIntCtlrConnect),
DEVMETHOD(vxbIntCtlrDisconnect, vxbAlteraIntCtlrDisconnect),
DEVMETHOD(vxbIntCtlrEnable, vxbAlteraIntCtlrEnable),
DEVMETHOD(vxbIntCtlrDisable, vxbAlteraIntCtlrDisable),
#ifdef ALTERA_INTCTLR_DEBUG_ON
DEVMETHOD(busDevShow, vxbAlteraIntCtlrShow),
#endif /* ALTERA_INTCTLR_DEBUG_ON */
{ 0, 0}
};
调用DEVMETHOD_CALL(vxbIntCtlrEnable)将会返回vxbIntCtlrEnable_desc的首地址,这个地址是唯一的,可以做为ID,来识别method。