任务的调度与切换(uC/OS-II)

一、任务的状态

任务的5种状态:休眠态、就绪态、运行态、挂起态(等待某一事件发生)和被中断态。

1、休眠态

任务驻留在内存中,但并不被多任务内核所调度。

2、就绪态

任务已经准备好,可以运行,但由于该任务的优先级比正在运行的任务的优先级低,暂时不能运行。

3、运行态

任务掌握了CPU的使用权,正在运行中。

4、挂起态

也叫等待事件态,指任务在等待某一事件的发生。例如:等待某外设的I/O操作,等待某共享资源由暂不能使用变成能使用状态,等待定时脉冲的到来,以结束目前的等待。

5、被中断态

发生中断时,CPU提供相应的中断服务,原来正在运行的任务暂不能运行。

二、任务的调度

任务级的调度是由函数OS_Sched()完成的。uC/OS-II任务调度的执行时间是常数,与应用程序建立了多少个任务没有关系。

 1 void  OS_Sched (void)
 2 {
 3 #if OS_CRITICAL_METHOD == 3                            /* Allocate storage for CPU status register     */
 4     OS_CPU_SR  cpu_sr;
 5 #endif
 6     INT8U      y;
 7
 8
 9     OS_ENTER_CRITICAL();
10     if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Sched. only if all ISRs done & not locked    */
11         y             = OSUnMapTbl[OSRdyGrp];          /* Get pointer to HPT ready to run              */
12         OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
13         if (OSPrioHighRdy != OSPrioCur) {              /* No Ctx Sw if current task is highest rdy     */
14             OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
15             OSCtxSwCtr++;                              /* Increment context switch counter             */
16             OS_TASK_SW();                              /* Perform a context switch                     */
17         }
18     }
19     OS_EXIT_CRITICAL();
20 }

(1)OS_Sched()检验这个优先级最高的任务是否是当前正在运行的任务,以避免不必要的任务调度。

(2)统计计数器OSCtxSwCtr的使用目的是让用户知道每秒做了多少次任务切换。

(3)调用OS_TASK_SW()宏,完成实际上的任务切换。

三、任务级的任务切换

任务切换代码须恢复该任务在CPU使用权被剥夺时保存下来的全部寄存器的值,以便让这个任务能继续运行。任务切换由2步完成:将被挂起任务的处理器寄存器推入堆栈,然后将较高优先级任务的寄存器值从栈中恢复到寄存器。OS_TASK_SW()挂起了正在执行的任务,而让CPU执行更重要的任务。

任务切换过程增加了应用程序的额外负荷,CPU的内部寄存器越多,额外负荷越重。任务切换所需时间取决于CPU有多少寄存器要入栈。

OS_TASK_SW()是宏调用,通常含有微处理器的软中断指令,因为uC/OS-II假定任务切换是靠软中断完成的。OS_TASK_SW()通常是汇编语言写的,因为C编译器不能从C语言中直接处理CPU寄存器。

时间: 2024-08-14 14:58:00

任务的调度与切换(uC/OS-II)的相关文章

uC/OS II 任务切换原理

今天学习了uC/OS II的任务切换,知道要实现任务的切换,要将原先任务的寄存器压入任务堆栈,再将新任务中任务堆栈的寄存器内容弹出到CPU的寄存器,其中的CS.IP寄存器没有出栈和入栈指令,所以只能引发一次中断,自动将CS.IP寄存器压入堆栈,再利用中断返回,将新任务的任务断点指针弹出到CPU的CS.IP寄存器中,实现任务切换.虽然明白个大概,但是其中的细节却有点模糊,为什么调用IRET中断返回指令后,弹入CPU的CS.IP寄存器的断点指针是新任务的断点指针,而不是当前任务的,UCOS II是如

uC/OS II 函数说明 之–OSTaskCreate()与OSTaskCreateExt()

1. OSTaskCreate()    OSTaskCreate()建立一个新任务,能够在多任务环境启动之前,或者执行任务中建立任务.注意,ISR中禁止建立任务,一个任务必须为无限循环结构.        源码例如以下: #if OS_TASK_CREATE_EN > 0                    /* 条件编译,是否同意任务的创建               */INT8U  OSTaskCreate (void (*task)(void *pd), /* 函数指针,void *

关于uC/OS的简单学习(转)

1.微内核 与Linux的首要区别是,它是一个微内核,内核所实现的功能非常简单,主要包括: 一些通用函数,如TaskCreate(),OSMutexPend(),OSQPost()等. 中断处理函数,且处理函数非常简单,一般仅是向相应的Task发消息,唤醒该Task来处理中断任务. 一个高效的调度器,这是OS的灵魂,实现多任务间的调度(包括调度点.调度算法.任务切换等). 好像就这么点,呵呵.它不支持内存保护,即不像Linux那样分用户空间.内核空间.如一个Task运行时,可调用内核函数Task

【原创】uC/OS 中LES BX,DWORD PTR DS:_OSTCBCur的作用及原理

1 LES BX, DWORD PTR DS:_OSTCBCur ;取得任务堆栈指针ES:[BX] 2 MOV ES:[BX+2], SS ;将当前SS(栈的基地址)寄存器值存放至当前任务堆栈的2,3内存单元 3 MOV ES:[BX+0], SP ;将当前SP(栈顶的偏移量)存放至当前任务堆栈的0,1内存单元 首先讲讲LES指针的功能:LES的功能有点像C语言的*. LES REG,MEM 参与操作的寄存器不仅有REG,还有ES寄存器.在16位系统中,寄存器为16位,很显然,MEM所指向的内存

uC/OS 的任务调度解析 (转)

uC/OS 的任务调度解析 1.任务调度器启动之后(初始化,主要是TCB的初始化),就可以创建任务,开始任务调度了,实际上第一个任务准确的说不是进行任务切换,而是进行启动当前最高优先级任务.uC/OS使用的是OSStartHighRdy OSStartHighRdy LDR R0, =NVIC_SYSPRI14 ; Set the PendSV exception priority LDR R1, =NVIC_PENDSV_PRI STRB R1, [R0] MOVS R0, #0 ; Set

uc os相关的C语言知识点1-函数指针

开始读uc os的代码了,发现很多C语言的东西,之前没搞懂的,慢慢积累. 就象某一数据变量的内存地址可以存储在相应的指针变量中一样,函数的首地址也以存储在某个函数指针变量里的.这样,我就可以通过这个函数指针变量来调用所指向的函数了. 形式1:返回类型(*函数名)(参数表) ,例子如下: #include<stdio.h> void (*funp)(int); //定义一个函数指针,注意函数的返回类型和参数类型和指针的一致,才可以用. void print(int n); //函数申明 int

uc/os iii移植到STM32F4---IAR开发环境

也许是先入为主的原因,时钟用不惯Keil环境,大多数的教程都是拿keil写的,尝试将官方的uc/os iii 移植到IAR环境. 1.首先尝试从官网上下载的官方移植的代码,编译通过,但是执行会报堆栈溢出警告(为何keil没有报堆栈溢出??),网上有人说不用理会,但是实际使用时发生了错误(定义的常量数组值被改变,怀疑是堆栈溢出导致),发现使用的IAR版本不能完美支持使用的STM32芯片,换用高版本测试..(高版本正确,与低版本对芯片的支持有关) 2.开始时虽然会堆栈溢出,但是能够进入异常中断,进入

uc/os调度机制深度解析

一.准备工作: //OSMapTbl与OSUnMapTbl定义 /* ********************************************************************************************************* * MAPPING TABLE TO MAP BIT POSITION TO BIT MASK * * Note: Index into table is desired bit position, 0..7 * In

任务的调度和切换

一.任务的状态 任务的5种状态:休眠态.就绪态.运行态.挂起态(等待某一事件发生)和被中断态. 1.休眠态 任务驻留在内存中,但并不被多任务内核所调度. 2.就绪态 任务已经准备好,可以运行,但由于该任务的优先级比正在运行的任务的优先级低,暂时不能运行. 3.运行态 任务掌握了CPU的使用权,正在运行中. 4.挂起态 也叫等待事件态,指任务在等待某一事件的发生.例如:等待某外设的I/O操作,等待某共享资源由暂不能使用变成能使用状态,等待定时脉冲的到来,以结束目前的等待. 5.被中断态 发生中断时