位置:51电子网 » 技术资料 » 其它综合

μC/OS-Il在TMS320VC33上的可靠应用

发布时间:2007/8/28 0:00:00 访问次数:426

作者:华中光电技术研究所 李 鲲


目前,μC/0S-II已经被成功移植到多种微处理器 上,其中也包括TMS320VC33。在μC/0S-II的网站上可以免费下载相关处理器的移植代码,这些代码可以作为 μC/OS-II应用中一个非常好的起点。笔者在应用这些 移植代码时遇到了一些问题,因此如何使移植更加可靠、 高效,仍然是一个值得深入探讨的话题。网上 TMS320VC33的移植代码已经完成了基本的移植工作, 本文不对移植的详细过程进行赘述,而只就移植及应用过程中的一些关键步骤和涉及到代码可靠性的问题进行讨论。


1 宏OS_ENTER_CRITlCAL和OS_EXIT_ CRITICAL


在μC/OS_ II中,0S_ENTER_CRITICAL和OS_ EXIT_CRITIcAL这两个宏分别实现关中断和开中断的功能。TMS320VC33的全局中断控制在ST寄存器的 GIE位(第13位),GIE=1时全局允许中断,GIE=O时全局禁止中断。这两个宏最简单直接的实现是使用与或指令修改GIE位,即“andn 2000H,st”和“0r 2000H,st”,网 上的移植代码就是采用了这种方式。但这不是一个非常可靠的方法,原因是TMS320VC33的流水线执行结构。为了提高代码的执行效率,TMS320VC33采取了四级流水线执行结构,指令的执行分为取指令、指令解码、读操作数和指令执行四个阶段,每个阶段都是并行执行的。在理想情况下(即不存在流水线冲突和等待周期),每个机器周期内都有四条不同的指令分别位于取指、解码、读和执行阶段。这时每条指令都以单机器周期执行,DSP达到其最大标称的指令吞吐量。当产生中断请求并且允许中断时,DSP不会立即执行中断服务程序,而是要先禁止中断、获取中断向量、保存返回地址,然后再跳转至中断服务程序。而以上各步都是与流水线操作同步的,在流水线结构中,DSP对中断响应步骤如表1所列。



表1中,proga+l是单周期取指指令。如果prog a+l 是多周期取指指令(例如取指时含有等待状态),中断响应会延迟到prog a+l执行以后。由表1可知,DSP对中断 的响应是在取指边界而不是指令的执行边界。假设prog a一2是关中断指令“andn 2000H,st”,那么prog a一1、 prog a甚至prog a+l仍然是可中断的,必须等到prog a +l执行完毕后才能完全禁止中断。同样在开中断时,紧邻开中断指令的后三条指令是不响应中断的。现在考虑下面的情况:系统通过OS_ENTER_CRITICAL宏禁止中断时,同时发生了中断请求,并且紧邻的三条指令是访问全局变量的指令。此时,由于流水线结构的执行特点, DSP还是会响应中断,如果相应的中断服务程序也访问了同样的全局变量,这样就可能破坏数据的一致性,造成系统的崩溃。为了防止这种情况,必须在改变系统中断状态时能够消除流水线操作带来的影响。为可靠实现OS_ ENTER_CRlTICAL和OS_EXIT_CRITICAL宏,在修改 ST寄存器之前加一条指令“RPTS O”。因为在RPTS指 令执行过程中会自动禁止中断,并且停止流水线操作,只有RPTS指令的下一条指令执行完毕后,DSP才会重新打开流水线。这样就保证了改变DSP中断状态时不会响应中断,也不会执行其他指令。上述宏的可靠实现为:



需要说明的是,利用trap指令的实现方式也是可靠的,但trap和rets/reti会两次清除流水线,因而会对性能稍微有点影响。OS_ENTER_CRITICAL宏的另外两种实现方法首先要保存DSP的中断状态,然后再改变中断状态。相应的,OS_EXIT_CRlTICAL宏可直接从前面保存的状态进行恢复。由于流水线操作的影响,要正确保存ST寄存器的状态,直接的存储或压栈指令是不行的,需要一些附加的保护性代码,本文就不再深入讨论了。


2 OSRdyGrp和OSRdyTbl


在笔者的应用系统中,除了定时器1中断外,还使用 了外部中断2、DMA中断和串口接收中断,把这些中断全 部打开后,会出现一个非常奇怪的现象。系统刚开始运行 时一切正常,一段时间后,与idle task不在同一个优先级 组的所有任务再也不执行了。但从程序上看,这些任务应 该处于就绪状态,除非就绪任务的优先级与idle task处于 同一个组,否则系统永远都在执行idle task。通过检查 OSRdyTbl发现,这些不被调度的任务的确处于就绪状 态,但在OSRdyGrp中却没有设置相应的标志.如果在 OSRdyTbl表中任务是就绪的,与该任务优先级组相对应 的OSRdyGrp中的标志却是0,那么任务调度时这些就绪 的任务是不会被调度的。在μC/OS-II中,OSRdyGrp与 OSRdyTbl的值都是同时修改的,并且还采用了临界区保 护,为什么还会出现OSRdyGrp与OSRdyTbl状态不一致 的现象呢?通过对汇编代码的仔细分析,发现问题出现在 函数OSTimeTick中,编译器产生了高效但不可靠的代 码。笔者使用的开发平台是Code Composer V4.1,代码 生成工具版本为5.11。此版本的代码生成工具产生的 OST

作者:华中光电技术研究所 李 鲲


目前,μC/0S-II已经被成功移植到多种微处理器 上,其中也包括TMS320VC33。在μC/0S-II的网站上可以免费下载相关处理器的移植代码,这些代码可以作为 μC/OS-II应用中一个非常好的起点。笔者在应用这些 移植代码时遇到了一些问题,因此如何使移植更加可靠、 高效,仍然是一个值得深入探讨的话题。网上 TMS320VC33的移植代码已经完成了基本的移植工作, 本文不对移植的详细过程进行赘述,而只就移植及应用过程中的一些关键步骤和涉及到代码可靠性的问题进行讨论。


1 宏OS_ENTER_CRITlCAL和OS_EXIT_ CRITICAL


在μC/OS_ II中,0S_ENTER_CRITICAL和OS_ EXIT_CRITIcAL这两个宏分别实现关中断和开中断的功能。TMS320VC33的全局中断控制在ST寄存器的 GIE位(第13位),GIE=1时全局允许中断,GIE=O时全局禁止中断。这两个宏最简单直接的实现是使用与或指令修改GIE位,即“andn 2000H,st”和“0r 2000H,st”,网 上的移植代码就是采用了这种方式。但这不是一个非常可靠的方法,原因是TMS320VC33的流水线执行结构。为了提高代码的执行效率,TMS320VC33采取了四级流水线执行结构,指令的执行分为取指令、指令解码、读操作数和指令执行四个阶段,每个阶段都是并行执行的。在理想情况下(即不存在流水线冲突和等待周期),每个机器周期内都有四条不同的指令分别位于取指、解码、读和执行阶段。这时每条指令都以单机器周期执行,DSP达到其最大标称的指令吞吐量。当产生中断请求并且允许中断时,DSP不会立即执行中断服务程序,而是要先禁止中断、获取中断向量、保存返回地址,然后再跳转至中断服务程序。而以上各步都是与流水线操作同步的,在流水线结构中,DSP对中断响应步骤如表1所列。



表1中,proga+l是单周期取指指令。如果prog a+l 是多周期取指指令(例如取指时含有等待状态),中断响应会延迟到prog a+l执行以后。由表1可知,DSP对中断 的响应是在取指边界而不是指令的执行边界。假设prog a一2是关中断指令“andn 2000H,st”,那么prog a一1、 prog a甚至prog a+l仍然是可中断的,必须等到prog a +l执行完毕后才能完全禁止中断。同样在开中断时,紧邻开中断指令的后三条指令是不响应中断的。现在考虑下面的情况:系统通过OS_ENTER_CRITICAL宏禁止中断时,同时发生了中断请求,并且紧邻的三条指令是访问全局变量的指令。此时,由于流水线结构的执行特点, DSP还是会响应中断,如果相应的中断服务程序也访问了同样的全局变量,这样就可能破坏数据的一致性,造成系统的崩溃。为了防止这种情况,必须在改变系统中断状态时能够消除流水线操作带来的影响。为可靠实现OS_ ENTER_CRlTICAL和OS_EXIT_CRITICAL宏,在修改 ST寄存器之前加一条指令“RPTS O”。因为在RPTS指 令执行过程中会自动禁止中断,并且停止流水线操作,只有RPTS指令的下一条指令执行完毕后,DSP才会重新打开流水线。这样就保证了改变DSP中断状态时不会响应中断,也不会执行其他指令。上述宏的可靠实现为:



需要说明的是,利用trap指令的实现方式也是可靠的,但trap和rets/reti会两次清除流水线,因而会对性能稍微有点影响。OS_ENTER_CRITICAL宏的另外两种实现方法首先要保存DSP的中断状态,然后再改变中断状态。相应的,OS_EXIT_CRlTICAL宏可直接从前面保存的状态进行恢复。由于流水线操作的影响,要正确保存ST寄存器的状态,直接的存储或压栈指令是不行的,需要一些附加的保护性代码,本文就不再深入讨论了。


2 OSRdyGrp和OSRdyTbl


在笔者的应用系统中,除了定时器1中断外,还使用 了外部中断2、DMA中断和串口接收中断,把这些中断全 部打开后,会出现一个非常奇怪的现象。系统刚开始运行 时一切正常,一段时间后,与idle task不在同一个优先级 组的所有任务再也不执行了。但从程序上看,这些任务应 该处于就绪状态,除非就绪任务的优先级与idle task处于 同一个组,否则系统永远都在执行idle task。通过检查 OSRdyTbl发现,这些不被调度的任务的确处于就绪状 态,但在OSRdyGrp中却没有设置相应的标志.如果在 OSRdyTbl表中任务是就绪的,与该任务优先级组相对应 的OSRdyGrp中的标志却是0,那么任务调度时这些就绪 的任务是不会被调度的。在μC/OS-II中,OSRdyGrp与 OSRdyTbl的值都是同时修改的,并且还采用了临界区保 护,为什么还会出现OSRdyGrp与OSRdyTbl状态不一致 的现象呢?通过对汇编代码的仔细分析,发现问题出现在 函数OSTimeTick中,编译器产生了高效但不可靠的代 码。笔者使用的开发平台是Code Composer V4.1,代码 生成工具版本为5.11。此版本的代码生成工具产生的 OST

相关IC型号

Warning: Undefined variable $stockkeys in G:\website_51dzw\www.51dzw.com\code\tech\view.php on line 152

热门点击

 

推荐技术资料

罗盘误差及补偿
    造成罗盘误差的主要因素有传感器误差、其他磁材料干扰等。... [详细]
版权所有:51dzw.COM
深圳服务热线:13692101218  13751165337
粤ICP备09112631号-6(miitbeian.gov.cn)
公网安备44030402000607
深圳市碧威特网络技术有限公司
付款方式