搜索
bottom↓
回复: 2

第三天 UC/OS-II的学习

[复制链接]

出0入0汤圆

发表于 2012-3-1 21:03:48 | 显示全部楼层 |阅读模式
第三天
1-2 回答了任务时如何被调度的。
1.        任务调度:(scheduler)
任务级的调度是由函数OSSched()完成的,中断级的调度是由OSIntExt()完成的。
1.1任务调度所化的时间是常数。与应用程序建立的任务数无关。(可参考OSSched()函数的代码,代码如3.1.1所示。)
void OSSched (void)
{
    INT8U y;
    OS_ENTER_CRITICAL();//进入临界区
    if ((OSLockNesting | OSIntNesting) == 0)//调用了任务调度函数 | 中断嵌套层数
{   
        y  =  OSUnMapTbl[OSRdyGrp];   
        OSPrioHighRdy  =  (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
        if (OSPrioHighRdy != OSPrioCur)
{         
            OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
            OSCtxSwCtr++;//跟踪任务切换次数。                       
            OS_TASK_SW();//进行任务切换。                        
               }
    }
    OS_EXIT_CRITICAL();
}
1.2        任务切换分两步完成。 将被挂起的微处理器寄存器推入堆栈,然后将较高优先级的任务的寄存器值从栈中恢复到寄存器。运行OS_TASK_SW()  在移植到51中用的是宏定义#define  OS_TASK_SW()         OSCtxSw()  在51中 OSCtxSw()是用的是汇编写的。
1.3        OSCtxSw()人为模仿一次中断,下面是51单片机的汇编程序
;                        --------------------------------------------------
;                        --------------------- OSCtxSw() ------------------
;                        --------------------------------------------------

        RSEG ?PR?OSCtxSw?OS_CPU_A
OSCtxSw:

;-----------------
; push registers
;-----------------
        PUSH        ACC
        PUSH        B
        PUSH        DPH
        PUSH        DPL
        PUSH        PSW
        PUSH        00
        PUSH        01
        PUSH        02
        PUSH        03
        PUSH        04
        PUSH        05
        PUSH        06
        PUSH        07

OSCPUAUniformCtxSw:
;assume register is pushed to hardware stack, in the format as discripted at the beginning of this file
;Before jump OSCPUAUniformCtxSw, OSCtxSw or OSIntCtxSw must first push registers to hardware stack as this format.

;----------------------
;Get OSTCBCurRdy->OSTCBStkPtr to DPTR
;-----------------------
;high byte is at low address

;OSTCBCurRdy to dptr
        MOV        DPH,#HIGH(OSTCBCur)
        MOV        DPL,#LOW (OSTCBCur)
        MOVX        A,@DPTR
        MOV        R0,A
        INC        DPTR
        MOVX        A,@DPTR
        MOV        DPH,R0
        MOV        DPL,A

;OSTCBStkPtr to dptr
        MOVX        A,@DPTR
        MOV        R0,A
        INC        DPTR
        MOVX        A,@DPTR
        MOV        DPH,R0
        MOV        DPL,A


;--------------------
;save stack
;--------------------

;store ?C_IBP
        MOV        A,?C_IBP
        MOVX        @DPTR,A

;store simulated stack
        JZ        OSCPUASmltSaveOver        ;simulated stack size == 0, that is A == 0x100
        MOV        R0,A
OSCPUASmltSave:
        INC        DPTR
        MOV        A,@R0
        MOVX        @DPTR,A
        INC        R0
        CJNE        R0,#0,OSCPUASmltSave
OSCPUASmltSaveOver:

;store sp size
        INC        DPTR
        MOV        A,SP
        CLR        C
        SUBB        A,#StkBottom - 1       
        MOVX        @DPTR,A

;store hardware stack and registers
;stack top is at high address
        MOV        R1,A                ;caluate copy rotation times
        MOV        R0,#StkBottom - 1        ;start of stack defined by keilc system
OSCPUASaveStk:
        INC        R0
        INC        DPTR
        MOV        A,@R0
        MOVX        @DPTR,A
        DJNZ        R1,OSCPUASaveStk

;-------------------
;call OSTaskSwHook
;-------------------

        LCALL _?OSTaskSwHook

;-------------------
; OSTCBCur = OSTCBHighRdy
;-------------------
       
        MOV        DPH,#HIGH (OSTCBHighRdy)
        MOV        DPL,#LOW  (OSTCBHighRdy)
        MOVX        A,@DPTR
        MOV        R7,A                ;store to R7/R6
        INC        DPTR
        MOVX        A,@DPTR
        MOV        R6,A

        MOV        DPH,#HIGH (OSTCBCur)
        MOV        DPL,#LOW  (OSTCBCur)
        MOV        A,R7
        MOVX        @DPTR,A
        MOV        A,R6
        INC        DPTR
        MOVX        @DPTR,A

;-----------------
; OSPrioCur = OSPrioHighRdy
;-----------------
       
        MOV        DPH,#HIGH (OSPrioHighRdy)
        MOV        DPL,#LOW  (OSPrioHighRdy)
        MOVX        A,@DPTR

        MOV        DPH,#HIGH (OSPrioCur)
        MOV        DPL,#LOW  (OSPrioCur)
        MOVX        @DPTR,A

;-----------------
; Restore Ctx
;-----------------
        LJMP        OSCPUARstStk
1.4         为缩短切换时间,OSSched()可以用汇编写。 OSCtxSw()中除了需要OSTCBHighRdy指向即将被挂起的任务,还需要让当前任务控制块OSTCBCur指向即将被挂起的任务。
2.        给调度器上锁 OSSchedlock() 和给调度器解锁 OSSchedUnlock()
2.1 OSSchedlock()用于禁止任务调度,知道任务完成后调用给调度器开锁函数OSschedUnlock()。
2.2 这两个函数要成对出现。
2.3 OSSchedLock()这个函数就是OSLockNesting++ ;代码3.1.1中的if语句,可以明白是如何上锁的。。。。
2.4 调用了OSSchedlock()函数的任务保持对CPU的控制权。但此时中断程序可以进行。
2.5 调用了OSSchedlock()之后,用户的应用程序,不能调用OSMboxPend()、OSQPend()
等函数了。
3.        空闲任务 idle task
永远设为最低优先级 OS_LOWEST_PRIO 空闲任务就是让OSIdleCtr++; 中断要关闭。


燕山大学  电气工程学院  09级检测技术与仪器

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2012-3-1 21:53:01 | 显示全部楼层
楼主学的真快。

出0入0汤圆

 楼主| 发表于 2012-3-1 22:08:19 | 显示全部楼层
回复【1楼】airfex  
-----------------------------------------------------------------------
不是我学的快,我学的慢啊,在寒假有半个月的时间都在看邵贝贝老师的书,现在是一边复习,一边记笔记。还没自己独立移植一下呢。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 01:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表