专栏中心

EEPW首页 > 专栏 > 浅析μC/OS-II v2.85内核调度函数

浅析μC/OS-II v2.85内核调度函数

发布人:transformer 时间:2008-03-17 来源:工程师 发布文章

浅析μC/OS-II v2.85内核调度函数
//----------------------------------------------------------------------
//1.μC/OS-II v2.85调度函数
void OS_Sched (void)
{
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR cpu_sr = 0;
#endif
    OS_ENTER_CRITICAL();
    if (OSIntNesting == 0) {
        if (OSLockNesting == 0) {
            OS_SchedNew();//计算当前优先级最高的就绪进程对应的OSPrioHighRdy--task管理结构体指针
            if (OSPrioHighRdy != OSPrioCur) {
            //确实是一个全新的最值得占有cpu的task就绪了
                OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
#if OS_TASK_PROFILE_EN > 0
                OSTCBHighRdy->OSTCBCtxSwCtr++;
#endif
                OSCtxSwCtr++;
//假设当前执行的进程为A,那个更高优先级的进程为B,那么[gliethttp]
//当前进程A让出cpu,让更有能力持有cpu的进程B持有cpu,此时当前进程A的执行代码将终止于此,
//A的返回地址---函数OS_EXIT_CRITICAL();被OS_TASK_SW()函数推入堆栈,
//下一次因为A的优先级最高切换回来的时候,进程A继续执行的代码是OS_EXIT_CRITICAL();打开中断,
//所以OS_TASK_SW()代码执行的过程中,最后切换到新进程,新进程还没执行语句之前,ISR中断始终关闭,直到
                OS_TASK_SW();
//直到切换到的新进程恢复到这里,继续向下执行
            }
        }
    }
//新进程将调用OS_EXIT_CRITICAL()重新打开cpu的ISR中断系统,这时cpu的ISR中断才算是打开[gliethttp]
    OS_EXIT_CRITICAL();
}
//----------------------------------------------------------------------
//2.OS_SchedNew()--巧妙的采用μC/OS-II v2.7之前的8位图方式,计算就绪task的优先级
static void OS_SchedNew (void)
{
#if OS_LOWEST_PRIO <= 63//如果定义的任务个数小于63个,那么还使用计算速度很快的μC/OS-II v2.7之前方式
    INT8U y;
//OSRdyGrp位8bit,每一个bit代表优先级计算中行、列矩阵的某一组,
//如bit0为1,那么矩阵数组的第0组有就绪进程
// bit1为1,那么矩阵数组的第1组有就绪进程
// ...
// bit7为1,那么矩阵数组的第7组有就绪进程
    y = OSUnMapTbl[OSRdyGrp];//通过优先级码表,获得最有持有cpu权限的task对应的矩形组号y
//OSRdyTbl[y]也为8bit数据,每一个bit代码一个进程的低8位值,使用位图码表,返回该y组内的进程中,
//进程号最小的那个进程号低8位,这样合成出新的进程号OSPrioHighRdy
//[使用位图码表的方式使得计算优先级的耗时为常数,不受进程数量的影响,但位图码表要占用255个字节空间gliethttp]
    OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
#else
//以下为超过63,小于256个进程的优先级计算方法,计算效率不如上面的64个进程
    INT8U y;
    INT16U *ptbl;
//OSRdyGrp为16位
    if ((OSRdyGrp & 0xFF) != 0) {
//y值越小,它的优先级越高,所以如果低8位有了需要调度的程序,那么没有必要再去考虑高8位情况
//优先级0~127中有就绪的进程
//如果OS_LOWEST_PRIO = 60,那么OS_TaskIdle()进程将在这里
        y = OSUnMapTbl[OSRdyGrp & 0xFF];
    } else {
//优先级0~127中有没有就绪的进程
//那么128~255中一定有就绪进程
//如果OS_LOWEST_PRIO = 132,那么OS_TaskIdle()进程将在这里
        y = OSUnMapTbl[(OSRdyGrp >> 8) & 0xFF] + 8;//矩形组号y>=8
    }
    ptbl = &OSRdyTbl[y];//取出x方向的16bit数据
    if ((*ptbl & 0xFF) != 0) {
//x值越小,它的优先级越高,所以如果低8位有了需要调度的程序,那么没有必要再去考虑高8位情况
//合成OSPrioHighRdy
        OSPrioHighRdy = (INT8U)((y << 4) + OSUnMapTbl[(*ptbl & 0xFF)]);
    } else {
//x方向低8位对应的进程可能因为OSSemPend()、OSTimeDly()之类的原因,悬停在某个地方,
//现在让x方向的高8位中优先级最高的进程成为最值得占用cpu的task
        OSPrioHighRdy = (INT8U)((y << 4) + OSUnMapTbl[(*ptbl >> 8) & 0xFF] + 8);
    }
#endif
}
//----------------------------------------------------------------------
//3.AT91RM9200处理器的OS_TASK_SW()定义如下[ADS1.2汇编代码gliethttp]
OSCtxSw
                             ;// SAVE CURRENT TASK'S CONTEXT
        STMFD {LR}           ;//Push return address
        STMFD {LR}
        STMFD {R0-R12}       ;// Push registers
        MRS R4, CPSR         ;// Push current CPSR
        ;//TST LR, #1 ;// See if called from Thumb mode
        ;//ORRNE R4, R4, #0x20 ;// If yes, Set the T-bit
        STMFD {R4}
        LDR R4, =OSTCBCur    ;// OSTCBCur->OSTCBStkPtr = SP;
        LDR R5, [R4]
        STR SP, [R5] 
        LDR R4, =OSPrioCur   ;// OSPrioCur = OSPrioHighRdy
        LDR R5, =OSPrioHighRdy
        LDRB R6, [R5]
        STRB R6, [R4]
        LDR R4, =OSTCBCur    ;// OSTCBCur = OSTCBHighRdy;
        LDR R6, =OSTCBHighRdy
        LDR R6, [R6]
        STR R6, [R4]
        LDR SP, [R6]         ;// SP = OSTCBHighRdy->OSTCBStkPtr;
                             ;// RESTORE NEW TASK'S CONTEXT
        LDMFD {R4}           ;// Pop new task's CPSR
        MSR SPSR_cxsf, R4
        LDMFD {R0-R12,LR,PC}^
;//返回到新的task,新task将要执行的第一个语句是OS_EXIT_CRITICAL(),启动中断.

专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们

关键词:

相关推荐

在线工具的兴起及其对系统设计和供应链管理的影响

芯科科技Works With开发者大会深圳站成功举办 展示全球AIoT先进科技与协同创新

义隆IC 湿度检测IC电流反馈放大IC

内存狂缺货!大客户满足率仅剩7成、服务器DRAM涨价5成

英特尔18A工艺正在稳步推进,要到2027才能达到行业标准水平

EDA/PCB 2025-10-28

同步PWM降压控制器MAX8576–MAX8579

决战希腊:微软“创新杯”2009实况-——软件设计和嵌入式开发项目组决赛2

视频 2009-07-07

今年专用无线增长 20% 公共无线没有

决战希腊:微软“创新杯”2009实况-——软件设计和嵌入式开发项目组决赛1

视频 2009-07-07

关于 CAN BUS

helenyu 2005-07-09

决战希腊:微软“创新杯”2009实况-——软件设计和嵌入式开发项目组决赛3

视频 2009-07-08

五笔输入法在单片机系统中的应用

需求超过供应 英特尔预警Intel10 和Intel7节点CPU短缺

你知道哪些智能技术能够提高效能?

视频 2009-07-02

关于CAN BUS

helenyu 2005-07-09

學習式遙控器IC FD59C08

高通发布两款面向数据中心的人工智能芯片

亚马逊将从本周开始解雇多达 30,000 名员工

智能计算 2025-10-28

稳流ic 7135

决战希腊:微软“创新杯”2009实况-——软件设计和嵌入式开发项目组决赛4

视频 2009-07-08

英飞凌首席营销官加入Wolfspeed

树莓派项目:酒精时钟

更多 培训课堂
更多 焦点
更多 视频

技术专区