admin管理员组文章数量:1535117
学习UC/OS-II的过程中,之前也疑惑过#define OS_CRITICAL_METHOD == 3是干嘛用的,今天正好看到了相关部分,将其摘录过来,以便查阅,或者帮助到需要的人。
OS_ENTER_CRITICAL()(进入临界区代码)和OS_EXIT_CRITICAL()(退出临界区代码)可以用不同的方法实现,具体用哪种方法,取决于用户打算移植到的处理器的性能以及所用的C编译器。用定义(#define)常数OS_CRITICAL_METHOD可以选择具体使用哪种方法。该常数是在用户应用程序(即产品)的移植文件OS_CPU.H中定义的。
OS_CRITICAL_METHOD == 1
第一种办法是以最简单的方式来实现这2个宏调用的:用处理器指令关中断,完成OS_ENTER_CRITICAL(),用开中断完成OS_EXIT_CRITICAL()。然而,这种办法有点小问题,如果调用UC/OS-II的功能函数时,中断是关掉的,则从UC/OS-II的函数返回时,中断就打开了。若调用UC/OS-II的函数之前已将中断关掉,那么用户往往希望从UC/OS-II的函数返回时,中断仍然是关掉的。在此情况下,这种实现方法就不妥当;但是对一些特定的处理器或编译器,使用这种方法是唯一的选择。
OS_CRITICAL_METHOD == 2
实现OS_ENTER_CRITICAL()的第二种办法是在堆栈中保存中断的开/关状态,然后再关中断。在实现OS_EXIT_CRITICAL()时,只需简单地从堆栈中弹出原来中断的开/关状态即可。利用这种机制,不论用户在调用UC/OS-II的函数之前中断是开着的还是关着的,函数的进入和返回状态都得到了保护。换句话说,如果调用前中断是打开的,则调用后仍是打开的;如果调用前中断是关掉的,则调用后仍是关掉的。关中断后调用UC/OS-II的函数要特别小心,因为关中断延长了应用程序的中断延迟时间。这两个宏调用的示意性代码如下:
#define OS_ENTER_CRITICAL() \
asm("PUSH PSW") \
asm("DI")
#define OS_EXIT_CRITICAL() \
asm("POP PSW")
PUSH PSW指令将处理器状态字推入堆栈(也称做条件码寄存器或处理器标志)。DI指令表示关中断。POP PSW指令将中断标志从堆栈中弹出,恢复原来的状态。这里使用的指令只是为了解释之便,可能并非处理器的真实指令。
OS_CRITICAL_METHOD == 3
一些编译器提供了扩展功能,用户可以得到当前处理器状态字的值,并保存在C函数的局部变量之中,这个变量可以用于恢复PSW。保护和恢复处理器状态字的示意性程序如下:
void Some_uCOS_II_Service(arguments)
{
OS_CPU_SR cpu_sr;
cpu_sr = get_processor_psw();
disable_interrupts();
/*临界段代码*/
set_processor_psw(cpu_sr);
}
OS_CPU_SR是在UC/OS-II中依赖于处理器的相关文件OS_CPU.H定义的。当应用程序选择这种进入临界代码段的方式时,OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()将会多定义一个局部变量cpu_sr。换句话说,如果使用这种方式保护自己的临界段代码,则在应用程序的相关函数中多定义一个局部变量cpu_sr。
调用函数get_processor_psw()得到PSW的值,调用函数disable_interrupts()关中断,调用函数set_processor_psw()重新开中断。这些函数的具体名称不一定如此,依赖于具体的编译器。
本文标签: OSCRITICALMETHOD
版权声明:本文标题:OS_CRITICAL_METHOD == 3浅析 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dongtai/1726270689a1063792.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论