跳至主要内容

博文

目前显示的是 十月, 2008的博文

VxWorks对中断的处理

我们平时使用intConnect调用挂接中断向量实际是将中断处理函数连接到vxworks内部的一个中断向量表,以MIPS为例,这个表为excBsrTbl,前几项与MIPS处理器的定义相同,但在后面保留了许多向量作为扩展使用。 intConnect为用户提供的回调函数与指针分配一小块内存(通过intHandlerCreate),并调用intVecSet将它设置到excBsrTbl中去。 intHandlerCreate用4条指令包装了用户函数,为原本不支持参数的中断处理函数提供了参数传递的功能。 FUNCPTR intHandlerCreate ( FUNCPTR routine, /* routine to be called */ int parameter /* parameter to be passed to routine */ ) { FAST UINT * pCode; /* pointer to newly synthesized code */ pCode = (UINT *) malloc (sizeof (intConnectCode)); if (pCode != NULL) { /* copy intConnectCode into new code area */ bcopy ((char *)intConnectCode, (char *)pCode, sizeof (intConnectCode)); /* set the addresses & instructions */ pCode [0] |= HI_WORD (routine); pCode [1] |= HI_WORD (parameter); pCode [2] |= LO_WORD (routine); pCode [4] |= LO_WORD (parameter); } /* * Flush the cache so we don't get instruction * cache hits to wrong vector */ CACHE_TEXT_UPDATE ((void *) pCode, sizeof (intCo

container_of

Linux常用container_of宏从成员变量提取整个结构体的首地针,这个宏的定义如下: #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) typeof是gcc的一个扩展,用于确定一个变量的类型,有点像C++的RTTI,常用于表达式内的语句,在定义宏时,如果需要临时变量,可以这样做: #define max(a,b) \ ({ typeof (a) _a = (a); \ typeof (b) _b = (b); \ _a > _b ? _a : _b; }) 它可以保证我们定义的变量_a/_b与宏传入的变量a/b类型匹配,而不会产生编译器告警。 因此container_of的第一行就是定义一个与member类型匹配的变量__mptr,赋值后,__mptr为宏参数中的待转换指针,因为只是类型转换,不涉及数据读写,((type*)0)是没有任何副作用的。 第二行用__mptr减去member变量在type中的偏移,这样便可实际访问到ptr相同偏移,也即type的实际首地址了。offsetof有两种定义: #ifdef __compiler_offsetof #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER) #else #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #endif __compiler_offsetof即__builtin_offsetof,__builtin_offsetof可能是gcc內建的支持(见gcc源码c-parser.c), 从后一种实现方式可以明显看到这一技巧,假定一个从0地址开始的结构体,取其成员member的地址正是结构体内的偏移。