打印

由Small—RTOS想起关于单片机的中断嵌套管理

[复制链接]
3041|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
songhere|  楼主 | 2012-7-15 14:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
           首先必须了解一个Keil 的一个源控制指令  #pragma disable
在一个函数执行期间禁止所有的中断。DISABLE指令必须在函数前面以#pragma 参数的形式出现,并且只能用在一个函数中,因此它是由编译器内部设置的。  其实的方法是在函数执行前关总中断,执行完成后再开总中断。

Small RTOS51下关于中断嵌套管理有三种情况:
1.允许嵌套管理
2.允许嵌套管理(期中有软非屏蔽中中断)
3.不允许嵌套管理

KEIL C51将中断放在语言扩展部分
一个中断
Void  int_uu(void )  interrupt 1
{
  (这里隐藏了保存寄存器的指令,汇编会体现出来)
  //用户代码   
(隐藏中断返回指令)
}

时钟节拍中断,不在中断嵌套管理之列,因为它不会调用 OS_INT_ENTER();,不进行嵌套计算。出中断时调用OS_Int_Exit () .   除非是做高级中断,否则中断函数之前必需加
#pragma disable ,以防止执行期间被另外一个中断打断,其在执行中不允许中断。
写法:
#pragma disable
Void OSTickISR voidinterrupt  OS_TIME_ISR
{
  。。。
  。。。
}


允许中断嵌套管理 中断的写法
#pragma disable                                //关总中断处理
Void UserISR(void) interrupt UserISR
{
  (隐藏保存寄存器)
OS_INT_ENTER();                         //开中断,主要这么做的原因是防止保
。。。            /    /                   //存寄存时被中断
     。。。           /    /  嵌套中断
     。。。           \    \
     。。。            \    \
     OSIntExit();
}

软非屏蔽中断: 由于操作系统中存在着大量的临界区代码,当一个中断响应的及时性已经不能忍受,必须通过设置将其设为软非屏蔽中断。

怎么设置:
将这个中断设置为最高级中断(不需要加#pragma disable ,因为不会被中断)
OS_ENTER_CRITICAL  OS_Enter_Sum++IE=IE&(~0X30)  //关中断不会影响该中断,同样OS_EXIT_CRITICAL 也进行类似的设置。
同时还要设置堆栈空间 Sp2space  和 宏SET_EA 等。

注意到软非屏蔽中断不应调用OS_INT_ENTER() OSIntExit() 等系统函数。由于其使用了堆栈空间 Sp2space 所以其不会破坏系统全局变量,几乎任意时刻都可以响应中断(除了其他中断保存寄存器期间)。  中断不调用任何临界区代码,也不访问任何临界区使用的共享资源,中断是可以执行的。



不使用中断嵌套管理:
  每一个中断都使用#pragma disable ,就不会有中断嵌套。

  每一个中断不使用#pragma disable ,则可能存在Bug的原因:一个低优先级的中断执行到“保存寄存器”时,未全部保存,被一个高优先级中断打断,恢复现场可能存在错误。所以类似像郭天祥教程那种编程方法下,多个中断是有可能存在BUG的,只是概率和小罢了。                                         

相关帖子

沙发
DownCloud| | 2012-7-15 14:14 | 只看该作者
保存的寄存器未全部恢复?发生更高级中断会有bug?更高级中断也有保存和恢复啊!退出高级中断后数据还是一样的!

使用特权

评论回复
板凳
DownCloud| | 2012-7-15 14:16 | 只看该作者
土土的理解应该是两个中断使用同个全局变量时才需要屏蔽中断。

使用特权

评论回复
地板
ayb_ice| | 2012-7-16 08:32 | 只看该作者
“并且只能用在一个函数中”

谁说的这话

使用特权

评论回复
5
liang7143| | 2012-7-16 09:12 | 只看该作者
“并且只能用在一个函数中”

谁说的这话
ayb_ice 发表于 2012-7-16 08:32


应该是只能作用于一个函数
每个要禁止中断的函数必须在函数前面重新加#pragma disable

使用特权

评论回复
6
liang7143| | 2012-7-16 09:15 | 只看该作者
对于使用#pragma disable
我更习惯于 直接关中断

gEAVal = EA;
EA = 0;
……
EA = gEAVal ;

使用特权

评论回复
7
ayb_ice| | 2012-7-16 09:34 | 只看该作者
对于使用#pragma disable
我更习惯于 直接关中断
gEAVal = EA;
EA = 0;
……
EA = gEAVal ;

liang7143 发表于 2012-7-16 09:15


你这种操作主演是有风险的

#pragma disable这种是利用JBC指令操作的,是原子操作,是零风险的,是有本质区别的

使用特权

评论回复
8
songhere|  楼主 | 2012-8-6 17:21 | 只看该作者
  MCS-51单片机的中断优先级分为两级:高优先级和低优先级。
  对每个中断源,可以通过编程设置为高优先级中断或低优先级中断。具体由IP寄存器控制,0为低优先级,1为高优先级。
IP(interrupt  priority中断优先寄存器) 可位寻址  
位        bit7        bit6        bit5        bit4        bit3        bit2        bit1        bit0
位名称        *        *        PT2        PS        PT1        PX1        PT0        PX0

  如果有多个中断源有中断请求信号,CPU先响应高优先级中断。当CPU同时收到几个同一优先级的中断请求时,CPU则通过内部硬件轮询决定优先次序,也称为辅助优先级。

所以只要不设置IP(interrupt  priority中断优先寄存器),则大家都是低优先级,就不会出现风险了。。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

52

帖子

1

粉丝