如果运行任务的时候中断没有关,在中断发生的时候会停止任务的运行。转去运行中断任务。中断程序尽可能的短,越短越好。
在ucosii中中断时允许嵌套的,每中断嵌套深入一层,则全局变量OSIntNesting就会加1。当系统没有中断发生,运行任务的时候,OSIntNesting = 0(之前的任务管理中,有不少源码就用到了这个全局变量来判断程序是否运行在中断环境中)。要是某个中断在运行的时候,不希望被其他中断打断,只需要进入中断之后关掉总中断(OS_ENTER_CRITICAL( ) )就可以了。
OSIntEnter和OSIntExit函数
OSIntEnter函数就是实现在进入一个中断后OSIntNesting加1 (os_core.c)
void OSIntEnter (void)
{
if (OSRunning == OS_TRUE) {
{
if (OSRunning == OS_TRUE) {
if (OSIntNesting < 255u) {
OSIntNesting++; /* Increment ISR nesting level*/
}
}
}
}
在进入中断的时候,调用OSIntEnter函数实现嵌套全局变量加1。
在退出中断的时候,调用与OSIntEnter匹配的OSIntExit来完成最后的处理。这两个函数,在中断程序中是成对的出现的。我们在编写自己的中断函数的时候需要注意一下。
OSIntExit 是在中断退出的时候执行,核心代码如下所示:
if (OSRunning == OS_TRUE) {
OS_ENTER_CRITICAL();
OS_ENTER_CRITICAL();
if (OSIntNesting > 0u) { /* Prevent OSIntNesting from wrapping */
OSIntNesting--; //在进入中断的时候,OSIntNesting加一,因此中断退出的时候减一。
}
if (OSIntNesting == 0u) { //OSIntNesting为0说明这个中断是目前的最后一个中断。在这个中断退出的时候,就会运行任务。
if (OSLockNesting == 0u) { //调度器没有加锁
OS_SchedNew(); //计算就绪任务中的最高优先级
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; //取得优先级最高任务的控制块指针
if (OSPrioHighRdy != OSPrioCur) { //当前就绪任务最高优先级等于正在任务优先级相同而话,就不需要进行调度。只有在不相等的情况下才需要调度
#if OS_TASK_PROFILE_EN > 0u
OSTCBHighRdy->OSTCBCtxSwCtr++; /* Inc. # of context switches to this task */
#endif
OSTCBHighRdy->OSTCBCtxSwCtr++; /* Inc. # of context switches to this task */
#endif
OSCtxSwCtr++; /* Keep track of the number of ctx switches */
OSIntCtxSw();
//OSIntCtxSw跟OSCtxSw的功能完全一样,都是将PendSv悬起,当没有其他中断运行的时候,会执行PendSv中断程序,将最就绪任务中最高优先级的任务切换上来。(详情可见任务管理(4)中的相关部分))
}
}
}
}
OS_EXIT_CRITICAL();
在UCOSII下的中断函数一般如下格式:
{
OSIntEnter;
中断函数功能主体;
OSIntExit ;
}
要是某个中断在运行的时候,不希望被其他中断打断,则其格式可以如下:
{
OS_ENTER_CRITICAL( );
OSIntEnter;
中断函数功能主体;
OS_EXIT_CRITICAL( );
OSIntExit ;
}
在stm32中中断函数原型都在启动文件中startup.s中定义,可以自己修改函数名称。就如在移植里所说的那样。