跳至主要内容

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 (intConnectCode));

return ((FUNCPTR)pCode);
}

封装代码与体系结构相关,下面是MIPS的代码,从注释中容易得知其作用,实现利用了指令的二进制编码形式,是一个较为巧妙的思想。
LOCAL UINT intConnectCode [] = /* intConnect stub */
{
/*
* 0x0: 3c08xxxx lui t0,xxxx * msh routine address
* 0x4: 3c04yyyy lui a0,yyyy * msh parameter load
* 0x8: 3508zzzz ori t0,t0,zzzz * lsh routine address
* 0xc: 01000008 jr t0 * jump to routine
* 0x10: 3484pppp ori a0,a0,pppp * lsh load in BD slot
*/
0x3c080000, /* msh routine address runtime load */
0x3c040000, /* msh parameter load runtime load */
0x35080000, /* lsh routine address runtime load */
0x01000008, /* jump to routine */
0x34840000, /* lsh load in BD slot runtime load */
};

然而MIPS异常0代表中断,又如何支持多个中断?这是由于vxworks提供了一个excIntStub中断处理函数作为异常0处理函数,然后根据中断位来分发中断。
这里涉及到两个表:sysHashOrder, IntPrioTable。sysHashOrder表是一个哈希表实现,在多个中断Pending情况下,两个表联合确定最高优先级的中断及该中断的信息。

vxworks提供了两个默认的哈希表,ffsMsbTbl和ffsLsbTbl,它们分别代表高位高先级和高位低先级,对于XLR,我们使用ffsMsbTbl,请看定义:
UINT8 ffsMsbTbl [256] =
{
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
};
MIPS一共有8个中断位。当多个中断来临时,假定最高位为N,那么2^N范围内的中断都取第N个中断为下一个处理的中断,按这种方式便可以将该表定义出来。
数组的值是对IntPrioTable的索引,在XLR中,定义如下:
PRIO_TABLE intPrioTable[8] =
{
{CAUSE_SW1,(ULONG) IV_XLR(IV_SW0), 0x0100, 0}, /* sw trap 0 */
{CAUSE_SW2,(ULONG) IV_XLR(IV_SW1), 0x0200, 0}, /* sw trap 1 */
{CAUSE_IP3,(ULONG) IV_XLR(IV_HW0), 0x0400, 0}, /* Uart0 */
{CAUSE_IP4,(ULONG) IV_XLR(IV_HW1), 0x0800, 0}, /* Hardware int 1 */
{CAUSE_IP5,(ULONG) IV_XLR(IV_HW2), 0x1000, 0}, /* PCIX */
{CAUSE_IP6,(ULONG) IV_XLR(IV_HW3), 0x2000, 0}, /* Demultiplex */
{CAUSE_IP7,(ULONG) IV_XLR(IV_HW4), 0x4000, 0}, /* Hardware int 4 */
{CAUSE_IP8,(ULONG) IV_XLR(IV_HW5), 0x8000, 0} /* Compare(Timer 0) */
};
IntPrioTable表提供了异常向量,中断向量,掩码等信息,有了中断向量,vxworks便可以通过excBsrTbl表找到中断回调并调用。

评论

此博客中的热门博文

反转剧

这两天明显感到天气转冷,呱呱的家里也已经下起了大雪,南京则是阴冷潮湿,让人没有了出行的欲望。没想到躲在被子里看反转剧也成了度过寒冬的一剂良药。在PPLive越来越让人失望的时候,PPStream横空出世,虽然广告仍是少不了的主题,但从视频质量和播放连续性上来说都超过PPLive,实为居家必备之良品(由此可见,新事物一定会战胜旧事物......)。韩国的反转剧最近似乎比较流行,称之为反转剧就在于其结果总是让人出乎意料,不合常理,其间又不乏各种搞怪搞笑的镜头,各种当红帅哥美女也一定让DDMM们爱不释手,20~30分钟一集的剧情一改韩剧拖沓的风貌,想看就看,容易切入。 反转剧,今天你看了吗?

如何突破自己的界限(ZZ)

大家都听说过温水煮青蛙的故事,也知道生于忧患死于安乐的道理,但是我们在生活中总会自然而然的根据自己的好恶养成一些习惯,在习惯的环境中,会感 觉很舒适,同时,这些习惯会开始渐渐在我们周围建起一座壁垒,哪怕这些习惯本身并没有什么错误,它们会慢慢局限我们的想法和决定,让我们失去很多应该获得 的机会,难以突破自己。 为什么我们常常会觉得工作和生活越来越沉闷,归根结底,是因为我们选择了这样的生活。 我们回避犯错误回避冒险。 不会犯错误的人永远不会创造出新的价值。 如果你想打破这种沉闷,让生活重新充满活力,下面有一些方法: 了解自己各种积习的真相。这些习惯往往曾经为你带来过成功,下一次你仍然会那么做。想要有所突破,必须放弃这些习惯,尝试新的思路模式和行动方法。除此之外别无他法,这些积习已经在阻碍你发现新鲜事物,让你停滞不前。 用不同的方法做事,看看效果。世界每一天都在发生变化,哪怕曾经让你无比成功的习惯,也不可能适应各种情况。 尝试用不同的方法做事,不要害怕失败,不要成为习惯的傀儡。 破除给自己强加的条条框框, 重新审视自己 ,给自己时间。积习难改,首先我们可能没有意识到这些习惯的存在,其次,在调整自我的过程中,这些习惯会不断的反扑,看看有多少人戒烟成功就知道了。 做你自己。很多时候我们不是在做自己,而是在做别人眼中的自己。大多数人都会有取悦别人的想法,希望达到别人的期望,哪怕是让自己变成自己都不愿 意成为的人。 你首先应该做好自己。 每个人都是不同的, 你应该把自己放在第一位,因为没有人会比你自己更在乎你。 把别人放在第二位是说给别人足够的尊重就可 以,不是让你完全忽略他们。 总是活在别人的阴影里是一种负担。 跳出这个圈子,给自己一个成为自己的机会。 放慢脚步,随遇而安。很多人都希望自己是一个充满智慧、优秀、受人爱戴的人。有时你的确是,有时却不一定。现实太复杂了,我们需要不断从别人那里 获取信息和支持来完成任何事情。我们所拥有的东西和知识都来自于别人。有时候,通过这些外界的帮助,我们可以做的更好。但有时却无法很好的利用。所以,要 了解自己是一个思想和感觉的复杂结合体,这些思想和感觉有时候很有用,有时候不。不需要给自己戴一个面具,也 不需要伪装自己什么都行,更没有必要因为发现自己的弱点而感到恐惧。 如果你能真诚的面对自己,会获得一种解脱。可能你不如自己想像得那么伟大,但也不

天将降大任于斯人也,必先折其体肤,洗其脑袋

元宵节就这么被一个半导体扼杀了。一趟大巴把我们拉到了汤山,我在那看到了keywords:温泉、洗浴、桑拿...可是没看到司机踩刹车... 当晚便开始训练,站在操场上,看着万家烟火,寒风凛冽,想着可怜的呱呱在家一个人吃汤圆,老泪纵横。Goodbye me lover, goodbye my friend. ——James Blunt语 当天正是降温的时候,第二天,天空居然飘起了小雪点,毛衣没带,冻得发抖。下午心动过速一小时,顶着,心里在想,如果倒下了,呱呱会怎样。接下来两天气温有些回升,训练也没有那么累了,Thank God。只是冬天的太阳狠,真狠,真是狠,真他妈狠,Yeah!脸皮痛,回到南京遂开始脱皮。一觉睡到大天亮,开始为期十二天的洗脑。生活颇为FB,行动却尤为不便,拜超级BT的领导所赐。好在呱呱也将有长达半月的培训,总算不会担心她会饿死,大饼的故事? 杀!!! ——顺带记念30年的第一次军训