主题 : 关于函数OS_Sched(void)的奇怪问题 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 36351
精华: 0
发帖: 1
金钱: 5 两
威望: 1 点
贡献值: 0 点
综合积分: 2 分
注册时间: 2011-01-14
最后登录: 2011-06-24
楼主  发表于: 2011-01-14 22:03

 关于函数OS_Sched(void)的奇怪问题

任务级别的任务调度函数sched()的源代码如下所示

/*
*********************************************************************************************************
*                                              SCHEDULER
*
* Description: This function is called by other uC/OS-II services to determine whether a new, high
*              priority task has been made ready to run.  This function is invoked by TASK level code
*              and is not used to reschedule tasks from ISRs (see OSIntExit() for ISR rescheduling).
*
* Arguments  : none
*
* Returns    : none
*
* Notes      : 1) This function is INTERNAL to uC/OS-II and your application should not call it.
*              2) Rescheduling is prevented when the scheduler is locked (see OS_SchedLock())
*********************************************************************************************************
*/

void  OS_Sched (void)
{
#if OS_CRITICAL_METHOD == 3                            /* Allocate storage for CPU status register     */
    OS_CPU_SR  cpu_sr;
#endif    
    INT8U      y;


    OS_ENTER_CRITICAL();
    if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Sched. only if all ISRs done & not locked    */
        y             = OSUnMapTbl[OSRdyGrp];          /* Get pointer to HPT ready to run              */
        OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
        if (OSPrioHighRdy != OSPrioCur) {              /* No Ctx Sw if current task is highest rdy     */
            OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
            OSCtxSwCtr++;                              /* Increment context switch counter             */
            OS_TASK_SW();                              /* Perform a context switch                     */
        }
    }
    OS_EXIT_CRITICAL();
}

里面执行了OS_TASK_SW(),使得当前的代码停止执行而去执行另一个任务。那么 语句 OS_EXIT_CRITICAL() 岂不永远也不会执行么?这样一来难道不是只有OS_ENTER_CRITICAL();而没有OS_EXIT_CRITICAL();了吗???
learning UCOS II
级别: 新手上路
UID: 41787
精华: 0
发帖: 4
金钱: 20 两
威望: 4 点
贡献值: 0 点
综合积分: 8 分
注册时间: 2011-04-01
最后登录: 2011-06-16
1楼  发表于: 2011-06-13 13:26
OS_TASK_SW()含有软中断指令 调用后会强制保存PSW和PC当前值;这个任务上下文也就是各寄存器的值就会在这个位置开始保存 保存到相应的任务堆栈里面 然后切换到其他任务 等其他任务执行 等轮到这个任务执行时 PSW、PC和各寄存器的值会得到恢复而继续执行。
级别: 新手上路
UID: 50674
精华: 0
发帖: 2
金钱: 10 两
威望: 2 点
贡献值: 0 点
综合积分: 4 分
注册时间: 2011-06-24
最后登录: 2011-06-27
2楼  发表于: 2011-06-24 17:35
OS_ENTER_CRITICAL();
是关中断,关中断了就不会调度,其它任务也不会运行
只有当OS_EXIT_CRITICAL()调用之后,开中断,才会调试,其它的任务才会运行
精注于硬件设计,ucos,ucgui