天天看点

ucos ii 任务调度原理

操作系统任务调度的原理(个人总结):

创建两个任务A、B

任务A的优先级>任务B的优先级(计算机根据任务的优先级大小让谁先执行)

A运行->任务A运行完->调用void OSTimeDly (INT32U ticks);函数,交出CPU的使用权,作用是让任务A运行态转换成等待状态,引发一次任务调度,任务调度函数void  OS_Sched (void);作用是查找处于就绪状态优先级最高的任务B->进行任务切换OS_TASK_SW();切换到任务B工作->任务B运行完成->B由运行态转换成等待状态->计算机查找处于就绪状态优先级最高的任务->没有任务待运行->计算机进入到空闲任务(计算机是不能停下来的),前提条件是没有任务再运行了->这时任务A产生定时时间到,即任务A控制块里的ptcb->OSTCBDly减到0(计算机会产生一个硬件定时器中断,进入中断服务函数void  OSTimeTick (void);该中断服务函数的作用是每个中断来临,把任务A和任务B控制块里面的ptcb->OSTCBDly--;操作,其中ptcb->OSTCBDly最初的值是void  OSTimeDly (INT32U ticks)函数传进去的tick的值)->任务A由等待状态转换成就绪状态->再次任务调度void  OS_Sched (void);查找优先级最高的就绪状态的任务A->进行任务切换OS_TASK_SW();->再次让任务A运行起来。循环往复。以上就是操作系统任务调度的原理。

第二章

操作系统是一种管理软件,程序控制块就是对各个任务管理的结构体。

这个结构体是通过链表链接,为了提高查找速度,再加上一个数组,数组的各个元素存储了链表成员的指针。

Typedef struct tcb{

      Char*code_name;

      Intp;

      Intv_number;

      Void(*fun)(void);//函数指针,指向各个任务

}

ucos ii 任务调度原理
ucos ii 任务调度原理

第三章 uc/OS-ii中的任务

任务之间的切换状态状态图。

1、任务分类:系统任务包括(空闲任务+统计任务)和用户任务

2、任务的优先级:最多可以创建64个任务,0-63,数字越小,任务优先级越高

3、任务的堆栈、以及任务堆栈的初始化

4、任务控制块链表及其任务控制块的初始化

5、任务就绪表和任务调度,计算机每时每刻让优先级最高的就绪任务处于运行状态

6、任务的创建OSTaskCreate();函数

7、任务的挂起OSTaskSuspend(INTU8prio);函数,如果参数是OS_PRIO_SELF,挂起任务本身,则删除任务在任务就绪表中的就绪标志。恢复任务用OSTaskResume()函数。

8、任务的删除。MyTask优先级0,YouTask优先级2,MyTask作为提出删除方,要删除任务YouTask,MyTask调用OSTaskDelReq(2)函数(优先级作为参数),YouTask任务调用OSTaskDelReq(OS_PRIO_SELF)删除自己。

9、uc/osii初始化 OSInit()函数和任务启动函数OSStart()函数。

第四章 uc/OS-ii的中断和时钟

1、中断的原理:uc/osii是一种可被剥夺性的内核,发生中断,系统进入中断服务函数,中断服务函数运行结束以后,会再次发生一次任务调度去运行优先级最高的就绪任务。void  OSIntExit (void);中断服务函数,任务级的切换函数是OSCtxSw(),中断级的任务切换函数OSIntCtxSw(),

2、临界段的概念

3、系统时钟,系统会产生周期性的硬件中断,中断调用中断服务程序OSTickISR中断调用中断服务函数OSTimeTick();函数,该函数是时钟节拍函数,作用是让每个控制块里的tcb->OSTCBDly--,简单说了解每任务的延时状态,其中到了延时时限的非挂起的任务处于就绪状态。

4、任务延时,任务延时的目的是让其他任务优先级别较低的任务获得CPU使用权的机会,函数OSTimeTick()作用是取消当前任务的就绪状态,引发一次任务调度。OSTimeTickResume()函数的作用是取消延时,进入就绪状态,如果任务比正在运行的任务优先级高,立即引发一次任务调度。

第五章 任务的同步与通信

信号量,互斥量、消息邮箱、消息队列4个概念,解决的问题是多任务对共享资源的访问引发的问题,包括(1)互斥问题不能同时访问,(2)同步问题先后访问,(3)任务之间的通信,消息邮箱、消息队列

1、       事件控制块

typedef struct os_event {

INT8U    OSEventType; 

void    *OSEventPtr;

INT16U   OSEventCnt;

      OS_PRIO  OSEventGrp;

       OS_PRIO  OSEventTbl[OS_EVENT_TBL_SIZE];

      INT8U   *OSEventName;

} OS_EVENT;

OSEventType事件类型,包括OS_EVEVT_TYPE_MUTEX, OS_EVEVT_TYPE_MBOX, OS_EVEVT_TYPE_Q,OS_EVEVT_TYPE_SEM,4种类型。OSEventCnt信号量计数器。OSEventGrp各任务组中是否有任务。OSEventTbl[OS_EVENT_TBL_SIZE]查看任务组中的等待任务列表。

事件控制块函数OS_EventWaitListWait()作用是OSEventGrp和任务等待表中OSEventTbl[OS_EVENT_TBL_SIZE]全部清0,在

OS×××CREATE()函数中调用,×××表示4中类型。

      OS_EventTaskWait()函数的作用是把一个任务处于等待状态,OS×××Pend()函数中调用。

      OS_EventTaskRdy()函数的作用是把一个任务处于就绪状态,OS×××Post()函数中调用。

2、信号量Sem。OSSemCreate(1);创建信号量初值为1。OSSemPend()请求信号量,OSEventCnt>1信号量有效,可以执行下面的代码,OSEventCnt并减1操作。OSSemPost()对OSEventCnt加1操作。信号量同样可以解决同步和互斥的问题。

3、互斥信号量Mutex。会出现优先级反转的问题,出现的原因是:当高优先级别的任务A和低优先级的任务C使用同一个信号量,低优先级的任务C先获得信号量,A打断C的运行,C没有释放信号量,A只好等待。系统中还存在中等优先级的任务B时,任务B没有使用同一个信号量,B会打断任务C的运行,同时C没有释放信号量,B运行完之后,C运行,C释放信号量,A运行。造成中等优先级的B先于A运行,优先级反转。解决方法:信号量任务的优先级别在使用共享资源的时候暂时提升到所有任务最高优先级别的高一级别上。

4、互斥信号量的创建OSMutexCreate(),请求OSMutexPend(),发送OSMutexPost()。

5、消息邮箱的创建OSMboxCreate(),请求OSMboxPend(),发送OSMboxPost()。消息邮箱的作用是,任务之间传递信息。

6、消息队列的创建OSQCreate()创建,请求OSQPend(),OSQPost()。

消息队列的作用是,任务之间通信。OSQPost()或者OSQPostFront()都是想消息队列发送消息,OSQPost()先进先出OSQPostFront()后进先出的方式组织消息队列。

第6章 信号量集

例子:创建3个任务,MyTask、YouTask、HerTask,要求用一个信号量集来控制MyTask的运行,即任务YouTask发送一个信号,任务herTask发送一个信号,当这两个任务都发送了信号之后,MyTask 任务才运行。

定义全局变量

INTU8 err;

OS_FLAG_GRP *Sem_F;

在StartTask()中创建三个任务MyTask、YouTask、HerTask,优先级分别为3,4,5。

MyTask请求信号量集OSFlagPend(Sem_F,(OS_FLAGS)3,OS_FLAG_WAIT_ALL,0,&err),其中数字3表示请求第0位和第1位信号。

YouTask发送信号量集OSFlagPost(Sem_F,(OS_FLAGS)2,OS_FLAG_SET,0,&err),其中数字2表示给第1位发送信号。

HerTask发送信号量集OSFlagPost(Sem_F,(OS_FLAGS)1,OS_FLAG_SET,0,&err),其中数字1表示给第0位发送信号。

总结:只有任务YouTask和任务HerTask都发送完信号,任务Myask才会运行。