μc/os-II原理简介(笔记)

来源:互联网 发布:软件行业发展前景概述 编辑:程序博客网 时间:2024/05/21 18:45
第一章


1、实时操作系统必须是多任务系统,任务的切换时间应与系统中的任务数无关,并且中断延迟的时间应该可预知并尽可能短。


第二章


3.1.1


1、从任务的存储结构上看,μc/os-II的任务由:任务程序代码、任务堆栈和任务控制块组成。
2、μc/os-II是所有的任务都是线程,没有给任务分配私有空间。


3.1.2


1、任务的5种状态:睡眠状态、就绪状态、运行状态、等待状态、中断服务状态


3.1.3


1、临界段,进入临界宏段,退出临界宏段
2、用户任务就是一个C语言函数,main()负责任务的创建并把他们交给系统,由操作系统来管理和调度


3.1.4


1、空闲任务 ,叫OSTaskIdle()的系统任务,做加1操作,规定:用户应用程序必须使用这个空闲任务,且不能通过程序删除
2、统计任务,叫OSTaskStat()的系统任务,计算CPU单位时间内被使用的时间。根据需要调用。


3.1.5


1、任务的优先权及优先级别


3.2


1、每个任务都应该配有自己的堆栈。


3.2.1


1、为提高可移植性,用选择开关写出向下和向上增长的任务堆栈
2、把任务初始化数据放到任务堆栈的工作叫做任务堆栈的初始化。


3.3


1、任务控制块:记录任务的堆栈指针、任务的当前状态、任务的优先级别等一些与任务管理有关的属性的表
122页


3.3.1


1、任务控制块结构


3.3.2


1、在任务控制管理上,μC/OS-II有两条链表:一条空任务块链表(其中所有任务控制块还未分配给任务)和一条任务块链表(其中所有的任务控制块已分分配给任务)


3.3.3


1、初始化任务控制块函数OTCBInit()
主要任务:1.为被创建任务从空任务控制块链表获取一个任务控制块
 2.用任务的属性对任务控制块各个成员进行复制
          3.把这个任务控制块链入到任务控制块链表


3.4


3.4.1


1、任务就绪表结构:它是一个位图,系统中的每个任务都在这个位图中占据一个二进制位。值为1表示任务处于就绪状态
2、每个数组元素描述了8个任务的就绪状态,这八个任务看成一个任务组
3、优先级化为二进制,取低六位,其中高三位指明OSRdyTBl,即第几个数组,低三位指明该数组元素的具体数据位。


3.4.2


对任务就绪表的操作
1、登记:在就绪表中将该任务的对应位置置1
2、注销:某个任务需要脱离就绪状态时,系统在就绪表中将该任务的对应位置置0
3、最高优先级就绪任务查找:调度器能从任务就绪表中查找最高优先级任务的能力


3.4.3


1、调度器的主要工作:1.查找具有最高优先级别的就绪任务2.实现任务的切换
2、两种调度器:1.任务级的调度器(由OSSched()实现) 2.中断级的调度器(由函数OSIntExt()实现)
3、任务切换两个步骤:1.获得待运行的TCB指针  2.进行断点数据的切换
4、OSSchedLock()和OSScheedUnclock()给调度器上锁和解锁。变量OSLockNesting了解调度器上锁的嵌套次数,上锁加1,解锁-1
5、调度器在任务切换前获得两个指针OSTCBHignRdy(指向待运行任务控制块)  OSTCBCur(指向当前任务控制块)
6、任务的切换时断点数据的切换,断点数据的切换也就是CPU堆栈指针的切换
7、任务切换宏OS_TASK_SW()7项工作
①把被中止的断点指针保存到任务堆栈中
②把CPU通用寄存器的内容保存到任务堆栈中
③把被中止的任务的任务堆栈指针当前值保存到该任务的控制块的OSTCBStkPtr中
④获得待运行任务的任务控制块
⑤使CPU通过任务控制块获得待运行任务的任务堆栈指针
⑥把待运行任务堆栈中通用寄存器的任务恢复到CPU的通用寄存器中
⑦使CPU获得待运行任务的断点指针


3.5


3.5.1


1、任务创建函数OSTaskCeeate(),OSTaskCreateExt()


3.6


1、任务的挂起:停止这个任务的运行
2、OSTakSuspend()挂起自身或者除空闲任务之外的其他任务
3、用OSTakSuspend()挂起的任务,只能在其他任务中通过调用恢复函数OSTaskResume()使其恢复为就绪函数




3.7.1


1、任务优先级别的修改函数OSTaskChangePrio()


3.7.2


1、任务的删除:把该任务置于睡眠状态
2、任务删除函数OTaskDel()删除自身或者除了空闲任务之外的其他任务
3、删除一个占用资源的任务时,提出删除任务请求的任务只负责提出删除任务请求而删除工作则由被删除任务自己来完成




3.7.3


1、OSTaskQuery()获取选定任务的信息


3.8.1 


1、应用程序首先应该调用OSInit()函数对全局变量和数据结构进行初始化,以建立运行环境
2、应用程序是通过调用函数OSStart()开始进行多任务管理的,但在调用函数OSStart()之前必须至少创建了一个任务。






4.1


1、应中断请求而运行的程序叫做中断服务子程序(ISR),中断服务子程序的入口地址叫做中断向量


2、对于可剥夺型的μC/OS-II内核来说,中断服务子程序运行结束后,系统将会根据情况进行一次任务调度去运行优先级别最高的就绪任务,而不一定是继续运行被中断的任务。


4.1.1


μC/OS-II中,通常用一个任务来进行异步事件的处理,而在中断服务程序中只是通过向任务发消息的方法去激活这个任务


4.1.2


1、OSIntCtxSw()叫做中断级任务切换函数
2、被中断任务的断点保护工作已经在中断服务程序中完成了。




4.1.3


1、μC/OS-II中不希望被中断的代码段叫做临界段
2、μC/OS-II中不要在临界段中调用μC/OS-II提供的功能函数,一面系统崩溃   


4.2


1、最小的时钟单位就是两次中断之间的相间隔的时间,这个最小时钟单位叫做时钟节拍
2、时钟中断服务程序中调用的OSTiemTick()叫做时钟节拍服务函数
3、函数OSTimeTick()的任务就是在每个时钟节拍了解每个任务的延时状态,使其中已经到了延时实现的非挂起任务进入就绪状态。
4、OSTimeTick()是系统调用的函数,为了方便程序员能在系统调用的函数中插入一些自己的工作,μC/OS-II提供了时钟节拍服务函数的钩子函数OSTimeTickHook()


4.3


1、除了空闲任务之外的所有任务必须在任务中合适的位置调用系统提供的函数OSTimeDly(),使当前任务的运行延时(暂停)一段时间并进行一次任务调度,以让出CPU的使用权
2、调用了函数OSTimeDly()或OSTimeDlyHMSM()的任务,当规定的延时时间期满,或有其他任务通过调用函数OSTimeDlyResume()取消了延时时,它立即回进入就绪状态


4.3.2


1、延时的任务可通过在其他任务中调用函数OSTimeDlyResume()取消延时而进入就绪状态。如果任务比正在运行的任务优先级别高,则立即引发一次任务调度


4.3.3


1、OSTime记录系统发生的时钟节拍数
2、应用程序中调用函数OSTimeGet()可获取OSTime的值


5.1.1


1、任务之间的制约关系:1.直接制约关系:源于任务之间的合作
      2.间接制约关系:源于对资源的共享
2、μC/OS-II使用信号量、邮箱(消息邮箱)和消息队列这些中间环节来实现任务之间的通信。这些中间环节统一称作"事件"


5.1.2
1、μC/OS-II把任务发送事件、请求事件以及其他对事件的操作都定义成为全局函数,以供应用程序的所有任务来调用
2、用来传递消息缓冲区的指针的数据结构叫做消息邮箱。定义一个数组,让数组的每个元素都存放一个消息缓冲区指针,那么任务就可以通过传递这个指针数组指针的方法来传递多个消息。
3、可以传递多个消息的数据结构叫做消息队列


5.2.1


1、功能完善的事件对等待任务具有两方面的管理功能:一是要对等待事件的所有任务进行记录并排序,二是应该允许等待任务有一个等待时限,即当等待任务认为等不及时可以退出对事件的请求


5.2.2


1、EventWaitLostInit()可以对事件控制块进行初始化。该函数的作用就是把变量OSEventGrp及任务等待表中的每一位都清0,即令事件的任务等代表中不含有任何等待任务。
2、把一个任务置于等待状态要用函数OS_EventTaskWait()
3、OS_EventTaskRdy()  使具备可以运行条件的正在等待的任务进入就绪状态。函数作用是把调用这个函数的任务在任务等待表中的位置清0(解除等待状态)后,再把任务在任务就绪表中对应的位置1,然后引发一次任务调度
4、一个正在等待事件的任务已经超过了等待的时间,却仍因为没有获取事件等原因而未具备而已运行的条件,却又要使它进入就绪状态,这时要调用OS_EventTo()


5.3.1


当事件控制块成员OSEventType的值被设置为OS_EVENT_TYPE_SEM时,这个事件控制块描述的就是一个信号量


5.3.2


1、使用信号之前,应用程序必须调用函数OSSemCreate()来创建一个信号量。函数的返回值为已创建的信号量的指针。
2、当任务需要访问一个共享资源时,先要请求管理该资源的信号量,这样就可以根据信号量当前是否有效(即信号量的计数器OSEventCnt的值是否大于0)来决定改任务是否可以继续运行
3、任务获得信号量,并在访问共享资源结束以后,必须释放信号量。释放信号量叫做发送信号量,调用OSSemPost()
4、应用程序不需要某个信号量,那么可调用函数OSSemDel()来删除该信号量,
5、只能在任务中删除信号量,而不能在中断服务函数中删除。
6、任务可以调用函数OSSemQuery()随时查询信号量的当前状态。


5.4


1、互斥型信号是一个二值信号,它可以使任务以独占方式使用共享资源
2、优先级反转原因:一个优先级别较低的任务在获得了信号量使用共享资源期间,被具有较高优先级别的任务所打断而不能释放信号量,从而使正在等待这个信号量的更高级别的任务得不到信号量而被迫处于等待状态,在这个等待期间,就让优先级别低于它而高于占据信号量的任务的任务先运行了。
3、解决办法之一:使获得信号量的任务的优先级别在使用共享资源期间暂时提高到所有任务最高优先级别的高一个级别上,以使该任务不被其他任务所打断,从而能尽快地使用完共享资源并释放信号量,然后在释放信号量之后,再回复该任务原来的优先级别 


5.4.2


1、OSMutexCreate()创建互斥型信号量
2、当任务需要访问一个独占式共享资源时,就要调用函数OSMutexPend()来请求管理这个资源互斥型信号量
3、OSMutexPost()发送一个互斥型信号量
4、OSMetexQuery()获取互斥型信号量的当前状态
5、OSMetexDel()删除一个互斥型信号量


5.5.2


1、创建邮箱需要调用函数OSMboxCreate(),参数为消息的指针,返回值为消息邮箱的指针
2、OSMboxPost()向消息邮箱发送消息
3、OSMboxPostOpt(),该函数可以广播的方式向事件等待任务表中的所有任务发送消息
4、OSMboxQuery()查询邮箱的当前状态,并把相关信息存放在一个结OS_MBOX_DATA中
5、OSMboxDel()删除一个邮箱。


5.6.1


1、使用消息队列可在任务之间传递多条消息。消息队列由三部分组成:事件控制块、消息控制块、消息队列和消息


5.6.2


1、创建消息队列首先需要定义一个指针数组,然后把各个消息数据缓冲区的首地址存放入这个数组中,最后调用OSQCreate()来创建消息队列。
2、请求消息队列函数OSQPend()从消息队列中获取消息
3、OSQPost()或OSQPOSTFront()来向消息队列发送消息
4、OSQFlush()来清空消息队列
5、OSQDel()删除消息队列
6、0SQQuery()查询一个消息队列的状态


6.1.1


1、μC/OS-II信号量集由一个标志组合多个等待任务控制块组成
2、标志组主要组成部分是一个叫做信号列表的二进制数OSFlagFlags,其实就是一个位图。该位图每一位都对应一个信号量,位图的作用就是用来接收并保存其他任务所发来的信号量值,所以它也可看做是输入信号暂存器。
3、等待任务:已经向信号量集合发出请求操作的任务


6.1.3


1、给等待任务链表添加节点的函数为OS_FlagBlock()
2、从等待任务链表中删除一个节点的函数为OS_flagUnlink()


6.2.1


1、任务可以通过调用函数OSFlagCreate()来创建一个信号量集




6.2.2


1、OSFlagPend()请求一个信号量集
2、OSFlagPost()向信号量集发送信号
3、OSFlagQueary()查询一个信号量集的状态
4、OSFlagDel()删除一个信号量集


7.1


1、μC/OS-II对内存进行两级管理,即把一个连续的内存空间分为若干个分区,每个分区又分为若干个大小相等的内存块
2、操作系统以分区为单位来管理动态内存,而任务以内存块为单位来获取和释放动态内存
3、内存分区是系统对内存进行管理的基本单位


7.1.2


1、系统用内存控制块(OS_MEN)来记录和跟踪每一个内存分区的状态


7.1.3
1、函数首先对创建一个内存分区的基本条件做一系列判断,然后定义内存分区。如果一个条件不满足,就意味着函数调用失败。
2、条件判断主要注意两点:1.分区的内存块至少有两块,2.每个内存块空间至少能存放一个指针(因为要在内存块中建立一个用于把内存分区的内存块链接为已个链表的指针)
7.2.2
1、应用程序需要一个内存块时,应用程序可以通过函数OSMenGet()向某内存分区请求获得一个内存块
2、需要注意:应用程序调用OSMenGet(),应该事先知道该分区中内存块的大小,并且在使用时不能超过该内存块大小,否则会引起灾难性后果


7.2.3
1、当应用程序不再使用一个内存块时,必须及时地将其释放。


7.2.4
1、OSMenQueary()来查询一个分区目前的状态信息


8.1.1


1、可重入函数:能被多个任务所调用,并且不会产生任务之间的相互干扰的函数




8.2


1、为了提高可移植性,μC/OS-II的绝大部分代码都用C语言编写。在一般情况下,这部分代码不需要修改就可以使用,而需要修改的主要是以下4个文件
①汇编文件OS_CPU_A.ASM
②处理器相关的C文件OS_CPU_.H和OS_CPU_C.C
③系统配置文件OS_CFG.H


8.2.4


1、原则上对μC/OS-II进行移植时,并不需要修改与处理器无关的代码,但因为在默认情况下KEIL编译器生成的代码不可冲入,如果要生成可冲入代码,则必须在函数后面显示地使用关键词reentrant.















0 0
原创粉丝点击