您当前的位置:五五电子网电子知识单片机-工控设备嵌入式系统-技术利用MC68K的C编译器的μC/OS-II向MC68K移植的实现 正文
利用MC68K的C编译器的μC/OS-II向MC68K移植的实现

利用MC68K的C编译器的μC/OS-II向MC68K移植的实现

点击数:7166 次   录入时间:03-04 11:57:07   整理:http://www.55dianzi.com   嵌入式系统-技术

    在中断处理程序中,当执行到OSIntExit()时,堆栈的情况和刚刚进入中断还是相同的,是能够随时恢复被打断的任务的情况。那么,只需要忽略 OSIntExit()函数造成的堆栈变化。首先,是OSIntExit()函数本身的返回地址,长度为2个字;调用OS_ENTER_CRITICAL ()压入堆栈的状态寄存器,长度为1个字;最后,是OSIntCtxSw()函数的返回地址,长度为2个字。那么在OSIntCtxSw()进行任务切换时,首先要把这5个字的堆栈的内容清除,才能保证被中断任务的正确恢复。该语句如下:

    ADDA #10,A7;

    在完成了这些调整后,由于开关中断可能导致的内核调度死锁的可能已经不存在了。但是在这种情况下,另一个更加隐蔽的问题会出现,这个问题又是和使用的C编码器相关的。

    问题出现在使用OSSemPend()函数时,一旦调用这个函数,CPU就会出现地址错误而进入异常处理,内核被终止。这个问题相当奇怪,因为, OSSemPend()函数完全是一个C语言写成的子函数,函数本身不应出现地址错误。通过阅读编译器编译出来的目标码发现了问题。EmPend()函数,发现这个函数没有任何局部变量。在进入OSSemPend()函数时,编译器不需要产生LINK指令来提供局部变量空间。所有的参数都是使用带偏移量的地址寄存器间接寻址方式直接从堆栈中取得,而且使用的地址寄存器就是A7寄存器。问题可能就在这里,OS_ENTER_CRITICAL()和 OS_EXIT_CRITICAL()对堆栈的操作都会调整A7寄存器,这就会导致下面的语句在利用A7作寄存器间接寻址时发生错乱,出现地址错误。

    这需要详细研究编译器的特性。我们使用的HIWARE的编译器实际上已经考虑到了这一点,当调用 OS_ENTER_CRITICAL()或 OS_EXIT_CRITICAL()函数更加了A7寄存器后,使用A7的地址寄存器间接寻址也会做出相应的调整,保证仍然能够得到函数调用时传递的变量。每出现一个OS_ENTER_CRITICAL(),接下来的A7寄存器间接寻址的偏移量就会加2;每出现一个OS_EXIT_CRITICAL (),接下来的A7寄存器间接寻址的偏移量就会减2。但是问题却依然存在,对OSSemPend()的调用会导致地址错误,这应该是一个更深层次的错误。

    这个问题的解决方法是:定义一个局部变量,迫使编译器生成LINK指令,构造内部参数寻址指针A6,这样调用OS_ENTER_CRITICAL()或OS_EXIT_CRITICAL()时,更动的只是A7,而对参数寻址用的是A6,不受影响。

    如果强迫编译器在调用函数时都加上LINK和UNLINK指令也可以解决这个问题,但是又会面临最先提到的编译器的优化选项问题。可以看出,编译器的特性对移植μC/OS-II是非常重要的,并且往往这些特性是相互制约的。

    在移植和运行μC/OS-II的过程中,也许还会有新的问题出现,遇到问题时只要仔细分析,分析堆栈的使用、中断的影响,分析编译生成的代码,就可以实现μC/OS-II的稳定可靠运行.



上一页  [1] [2] [3] 


本文关键字:编译器  嵌入式系统-技术单片机-工控设备 - 嵌入式系统-技术