您的位置:首页 > 其它

uCos-iii 学习笔记开篇

2016-03-16 08:39 330 查看
uCos-iii 学习笔记开篇


一、基本概念

        uCos-iii是一个可裁剪,可固化,可剥夺的多任务内核,没有任务数目的限制,其源代码开放,支持时间片轮转调度,系统API使用简单,易作为通用操作系统来进行学习,本章主要对前后台系统及实时内核的结构及调度进行总结。

1.1、前后台系统

        简单的小系统通常设计成前后台结构,这个系统包括一个主循环和若干个中断服务程序,应用程序是一个主循环,循环中调用相关的函数完成相应的操作(后台),中断服务程序用于处理系统的异步事件(前台),前台也称作中断级,后台是任务级。前后台系统的缺点在于任务级响应延时,一些时间要求较高的操作通常会放在中断中进行处理,这会导致中断的执行时间变长,中断程序即使快速的生成了特定的数据,后台程序也需要运行到特定的代码处才能进行处理。



图1-1 前后台系统

1.2、实时内核

        实时系统通常把系统划分为多个任务,每个任务仅负责实现某一功能,每个任务都是一段简单的程序,通常是一个死循环,CPU在任一时刻只能执行一个任务,但每个任务都认为自己在独自使用整个CPU。实时内核的作用是尽最大效率的利用CPU资源,决定什么时候停止任务,什么时候进行任务切换。



图1-2可剥夺型多任务内核

二、任务调度

        用习惯了前后台系统刚刚使用实时操作系统时总是感觉不适应,不适应的原因很简单,对操作系统的工作方式不是很清楚,不清楚内核到底帮我们做了哪些工作,借助ucos-iii操作系统把通用操作系统的任务调度流程进行总结,明白了操作系统的调度方式,也就基本掌握了操作系统的使用,剩下的就是一些系统API的调用。

        任务通常是一个循环,当任务挂起或有高优先级任务需要执行时会进行任务切换,任务切换首先调用OS_TASK_SW宏,这里只进行地址赋值,接着通过CPU_INT_EN宏跳转到OS_CPU_PendSVHandler汇编代码处执行上下文的切换操作,首先将当前的CPU寄存器做入栈操作,然后将堆栈指针指向高优先级任务的入口地址,再进行出栈操作,将栈中保存的CPU寄存器值还原到CPU寄存器中,这样高优先级任务就得到正确执行,执行结束后根据需要进行相关调度,详细流程参见代码注释及流程图。

2.1、代码片段

OS_CPU_PendSVHandler

    CPSID   I                   ;关闭中断

    MRS     R0,PSP             ;保存任务堆栈地址到R0寄存器PSP
->R0

    STMFD   R0!, {R4-R11}       ; 保存R4-R11到R0指向的存储单元中,地址自动+1

 

    MOV32   R5,OSTCBCurPtr     ; 保存当前任务控制块地址 OSTCBCurPtr->R5
;

    LDR     R6,[R5]            ;
R5 -> R6

    STR     R0,[R6]            ;
R6 -> R0(当前所指向的堆栈地址)

    ;到此为止完成上文保存

   

    MOV     R4,LR              ;防止调用函数期间返回地址变更,保存返回地址 LR
-> R4

    BL      OSTaskSwHook        ;
OSTaskSwHook();

 

    ; 将当前优先级切换为高优先级 OSPrioCur
= OSPrioHighRdy;

    MOV32   R0,OSPrioCur       ;
&OSPrioCur -> R0;

    MOV32   R1,OSPrioHighRdy   ;
&OSPrioHighRdy -> R1;

    LDRB    R2,[R1]            ;
OSPrioHighRdy -> R2;

    STRB    R2,[R0]            ;
OSPrioHighRdy -> OSPrioCur;

 

    ; 将当前任务控制块指针切换为高优先级任务控制块指针 OSTCBCurPtr
= OSTCBHighRdyPtr;

    MOV32   R1,OSTCBHighRdyPtr;
&OSTCBHighRdyPtr -> R1;

    LDR     R2,[R1]            ;
OSTCBHighRdyPtr -> R2;

    STR     R2,[R5]            ;
OSTCBHighRdyPtr -> OSTCBCurPtr

 

    ORR     LR,R4, #0x04       ; 确保返回地址R4
-> LR;使用PSP

    LDR     R0,[R2]            ;
OSTCBHighRdyPtr -> R0;

    LDMFD   R0!, {R4-R11}       ;
R4-R11出栈

    MSR     PSP,R0             ;OSTCBHighRdyPtr
-> PSP

    CPSIE   I                   ; 开中断

    BX      LR                  ; 返回

 

    END

 

 

 
          在实际调试时一直不明白BX LR是如何跳转到指定的任务入口的,原来是在BX
LR语句执行时会执行其他CPU寄存器的出栈操作,该操作和入栈时一样,是由硬件自动完成的,出栈的顺序为R0~R3
R12 R14(LR) PC xPSR.然后跳转到PC处执行代码。



图2-1切换过程分析

2.2、调度过程



图2-2任务调度流程

1、Task1正在执行(此处不会在任务堆栈中执行,这里只是示意)。

2、产生任务调度,可能是自身挂起让出CPU使用权,也可能是有高优先级任务抢占执行。

3、入栈操作来保存当前运行环境。

4、将SP指针指向高优先级任务Task2.

5、出栈操作来还原之前保存的运行环境。

6、执行高优先级任务(此处不会在任务堆栈中执行,这里只是示意)。

7、发生任务调度,具体流程同上。

三、总结

        实时系统会帮助用户最大程度的利用CPU资源,多任务切换会造多CPU的假象,任务切换依赖于独立的任务堆栈空间,任务堆栈空间主要用于上下文切换和一些任务相关的临时变量,在使用实时系统时要注意任务堆栈空间的分配,还要注意一些系统API的使用场景及方式,后面会对uCOS-III的系统API使用进行总结,主要包括多任务创建、行为同步、数据通信、临界区保护、定时器等操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: