所谓临界段代码,
Critical Sections of Code
, 就是这段代码在执行时, 不希望也不允许有中断发生.所有使用了系统变量, 也就是全局变量, 的代码段, 基本上都是属于这一类, 除非使用信号量的方式对全局变量加以了保护.
---------------------------------
处理方法:
封装了两个宏,
OS_ENTER_CRITICAL()
, OS_EXIT_CRITICAL()
, 分别用于进入临界段, 退出临界段.封装方式:
OS_CRITICAL_METHOD
宏定义, 用来指示采用何种封装方式.#1
直接定义为关中断, 开中断.
/* pseudo code*/ #if OS_CRITICAL_METHOD == 1 #define OS_ENTER_CRITICAL() __asm_tag__ (CLI;) #define OS_EXIT_CRITICAL() __asm_tag__ (STI;) #endif
上面是伪代码, 使用的两条汇编指令
CLI STI
是 IA-32 以及 IA-64 架构中的关中断 Clear Interrupt, 开中断 Set Interrupt 指令. 具体可以参考 Intel 64 and IA-32 Architectures -- Software Developer's Manual
的第一卷 5.1.11.pros:
# 简便, 迅速. 对于处理器速度很慢的系统尤其适用.
# 有些系统仅仅能够使用此类方法.
cons:
如果系统本身就是关中断状态, 那么使用
OS_ENTER_CRITICAL() OS_EXIT_CRITICAL()
组合后, 系统中断将打开. 这时便有可能产生严重错误.#2
先保存当前状态, 再进入临界段代码, 退出时恢复.
保存方式可以使用堆栈, 如,
/* pseudo code*/ #if OS_CRITICAL_METHOD == 2 #define OS_ENTER_CRITICAL() __asm_tag__ (PUSHF; CLI;) #define OS_EXIT_CRITICAL() __asm_tag__ (POPF;) #endif
也可以根据编译器提供的方式, 如,
/* pseudo code*/ #if OS_CRITICAL_METHOD == 3 #define OS_ENTER_CRITICAL() \ cpu_sr = get_processor_psw(); \ disable_interrupt(); #define OS_EXIT_CRITICAL() \ set_processor_psw(cpu_sr); #endif
其中
cpu_sr
是和系统的程序状态字寄存器, Program Status Register, 大小一致的变量.如8051中的
PSW
是8位, 就应该定义, typedef unsigned char OS_CPU_SR; OS_CPU_SR cpu_sr;
. 如 IA-32 架构的 EFLAGS
是32位, 则应该是 typedef unsigned long int OS_CPU_SR;
.pros:
没有第一种实现方式的错误.
cons:
占用的时钟周期自然就增加了, 对于系统的速度有所拖累.
---------------------------------
总结:
这里所提到的两个宏定义, 都是在
OS_CPU.h
文件中, 用于移植所需.至于移植时, 采取何种办法, 根据各类架构和应用而定.
如果对于「是否屏蔽了中断」不敏感, 那么使用第一种方式足矣. 如果敏感, 务必使用第二种, 否则系统定然崩溃或者挂起.
而在第二种中, 推荐使用编译器提供的方式, 而非内联汇编的堆栈操作. 因为有时候编译器对内联汇编支持不好, 可能导致对堆栈指针
SP
的处理出错.---------------------------------
** 注意:
一旦进入临界段代码, 所有中断便随之关闭, 包括定时时钟中断 Clock Tick Interrupt. 如果在此时调用类似
OSTimeDly()
的延时功能函数, 便会导致系统挂起, 也就是死机, 因为时钟节拍中断无法得到服务. 谨慎起见, 调用任何功能函数前, 都要保证中断是开着的.而且, 如果临界段代码太长, 占用时钟周期太多, 会导致系统对中断的响应变慢, 中断延时增加, 这对于商业实时系统是不可忍受的. 因此务必良好规划和设计, 将临界段代码压缩至最小, 切记切记.
- EOF -
没有评论:
发表评论
不要使用过激的暴力或者色情词汇.
不要充当勇猛小飞侠 --- 飘过 飞过 扑扑翅膀飞走 被雷得外焦里嫩地飞走.
万万不可充当小乌龟 --- 爬过.
构建河蟹社会 责任你有 我有 大家有 -_-