加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

ucos进入临界区三种方法的探究

(2013-10-06 17:32:52)
标签:

ucos

嵌入式

中断

任务切换

it

所谓临界区,即某些大家都使用到的一些变量,例如全局变量,当我们的某个函数要修改全局变量时,如果有中断打断了该中断过程,就会造成全局变量的混乱,为了避免此时其他中断打断该修改过程,我们可以在修改前将中断关闭,修改完成之后再开中断。在os_cpu.h中有OS_CRITICAL_METHOD,它定义了进入临界区的方法。一般的移植过程而言,有三种进入临界区的方法:

   1>OS_CRITICAL_MOTHOD==1.

    #define OS_ENTER_CRITICAL() _asm sei;

    #define OS_EXIT_CRITICAL() _asm cli;

    这种方法是直接开关中断,并没有保存中断屏蔽寄存器的值(见PRIMASK FAULTMASK BASEPRI这三个寄存器),不管进入临界区之前中断是否是已经打开或者关闭,退出临界区后中断就被强制性的打开了。这在任务级代码中这样做没有太大的问题,因为在执行任务代码时中断基本都是打开的,但是在中断处理函数中情况就不是这样了。

   2>OS_CRITICAL_MOTHOD==2

   #define OS_ENTER_CRITICAL() _asm{PUSHF;CLI}

   #define OS_EXIT_CRITICAL() _asm POPF

   这种方法是关中断前将CPU状态寄存器的值存入堆栈中,然后在关中断。开中断时将CPU状态寄存器出栈,这样中断也恢复到了原来的状态。但是这样做的坏处就是会导致堆栈寄存器的内容的改变,从而导致对局部变量的访问产生了错位。从而产生严重的错误。

   3>OS_CRITICAL_MOTHOD==3

   #define OS_ENTER_CRITICAL (cpu_sr=OSCPUSaveSR())

   #define OS_EXIT_CRITICAL (OSCPURestoreSR(cpu_sr))

   方法三将CPU状态寄存器的值存至局部变量cpu_sr,而不是像方法二一样存到任务堆栈中,这样就避免用到了堆栈指针,防止了方法二错误的发生。开中断时将局部变量cpu_sr的值恢复到cpu状态寄存器中,这样就恢复到了中断前的状态。里面的OSCPUSaveSR()和OSCPURestoreSR()需要我们自己去实现,具体的实现是在os_cpu_a.asm中,这是我们移植时需要修改的一部分。

 

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有