UC/OS-II基础知识之中断

UC/OS-II基础知识之中断

1.中断
任务在运行过程中,应内部或者外部异步事件的请求终止当前任务而去处理异步时间所要求的任务的过程叫做中断,应中断请求而运行的程序叫做中断服务子程序,中断服务子程序的入口地址叫做中断向量。UC/OS-II系统响应中断的过程是:系统接收到中断请求时,如果这时CPU处于中断允许状态,即中断时开放的,系统就会终止正在运行的当前任务,而按照中断向量的指向转而去运行服务子程序。需要特别注意的是对于可剥夺形的UC/OS-II内核来说,中断子程序运行结束之后,系统将会根据情况进行一次任务调度去运行优先级别最高的就绪任务,并不一定接着运行被中断的任务。同时中断是可以嵌套的,即高优先级别的中断源的中断请求可以中断低优先级别的中断服务程序的运行。为了记录中断嵌套的层数,UC/OS-II定义了一个全局变量OSIntNesting,UC/OS-II的中断响应过程入下图所示

在编写中断服务程序时,需要用到两个重要的函数OSIntEnter()和OSIntExt()
函数OSIntEnter()的作用就是把全局变量OSIntNesting加1,从而用它来记录中断嵌套的层数。函数原型如下

void  OSIntEnter (void)
{
    if (OSRunning == OS_TRUE) {
        if (OSIntNesting < 255u) {
            OSIntNesting++;                      /* Increment ISR nesting level                        */
        }
    }
}

OSIntEnter()的调用通常发生在中断服务程序保护了被中断任务的断点之后运行用户中断服务代码之前。
另一个函数是OSIntExt(),在改函数中会将变量OSIntNesting减1,OSIntExt()的源码如下

void  OSIntExit (void)
{
#if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
    OS_CPU_SR  cpu_sr = 0;
#endif
    if (OSRunning == OS_TRUE) {
        OS_ENTER_CRITICAL();
        if (OSIntNesting > 0) {                            /* Prevent OSIntNesting from wrapping       */
            OSIntNesting--;
        }
        if (OSIntNesting == 0) {                           /* Reschedule only if all ISRs complete ... */
            if (OSLockNesting == 0) {                      /* ... and not locked.                      */
                OS_SchedNew();
                if (OSPrioHighRdy != OSPrioCur) {          /* No Ctx Sw if current task is highest rdy */
                    OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy];
#if OS_TASK_PROFILE_EN > 0
                    OSTCBHighRdy->OSTCBCtxSwCtr++;         /* Inc. # of context switches to this task  */
#endif
                    OSCtxSwCtr++;                          /* Keep track of the number of ctx switches */
                    OSIntCtxSw();                          /* Perform interrupt level ctx switch       */
                }
            }
        }
        OS_EXIT_CRITICAL();
    }
}

该函数的流程图入下所示
中断服务子程序的流程图入下图所示

2.中断级任务切换
与任务级切换类似。完成中断级任务切换需要调用通过调用OSIntCtxSw()来完成。其代码如下所示

void OSIntCtxSw()
{
    DWORD n = 0;
    if(!(SS_SP->Exit)) {
        n = SuspendThread(SS_SP->Handle);
    }
    OSTaskSwHook();
    OSTrace( OBJ_SW, PT_SW_INT, OSTCBHighRdy, 0, OSPrioCur,OSPrioHighRdy,0 );
    OSTCBCur = OSTCBHighRdy;
    OSPrioCur = OSPrioHighRdy;
    SS_SP = (OS_EMU_STK*) OSTCBHighRdy->OSTCBStkPtr;
    ResumeThread(SS_SP->Handle);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值