特别声明:本笔记是对uc/os-ii研究做一些重要的内核思路整理和心得记录,以日期为作为记录块,故没有思路和规范可言,为此贴于工程师笔记里面,一来方便自己温故知新,二来希望能给初学者带来一些方便和帮助。高手别见笑^_^,偶刚起步。另外,如有错误和不当之处,请指正和发表您的心得体会。谢谢!1. 任务是一个无返回的无穷循环。uc/os-ii总是运行进入就绪状态的最高优先级的任务。2. 任务是如何调度(切换)的?因为uc/os-ii总是运行进入就绪状态的最高优先级的任务。所以,确定哪个任务优先级最高,下面该哪个任务运行,这个工作就是由调度器(scheduler)来完成的。任务级的调度是由函数OSSched()完成的,而中断级的调度是由函数OSIntExt()完成。对于OSSched(),它内部调用的是OS_TASK_SW()完成实际的调度(人为模仿一次中断);OSIntExt()内部调用的是OSCtxSw()实现调度。参考:P92,P106任务切换其实很简单,由如下2步完成:(1)将被挂起任务的处理器寄存器推入自己的任务堆栈。(2)然后将进入就绪状态的最高优先级的任务的寄存器值从堆栈中恢复到寄存器中。参见P92(1)作为uc/os-ii的一条普通原则,调用uc/os-ii功能函数时,中断总应当是开着的。(2)任务永不返回,就算任务自我删除,也绝对不会返回。(任务删除并非代码删除,只是ucos-ii不会理会这任务。)(3)OSTimeTick()函数是ucos-ii内部函数,用户无需调用。(4)ucos-ii从中断返回之前,要判断被中断的任务是否还是就绪状态任务中优先级最高的任务。3. OSInit()初始化示意图 我做了一个很好的图示,竟然粘贴不出来,没办法...4. 任务的5种状态(参见P79 图)睡眠态(task dormat):任务驻留于程序空间(rom或ram)中,暂时没交给ucos-ii处理。就绪态(task ready):任务一旦建立,这个任务就进入了就绪态。运行态(task running):调用OSStart()可以启动多任务。OSStart()函数只能调用一次,一旦调用,系统将运行进入就绪态并且优先级最高的任务。等待状态(task waiting):正在运行的任务,通过延迟函数或pend(挂起)相关函数后,将进入等待状态。中断状态(ISR running):正在运行的任务是可以被中断的,除非该任务将中断关闭或者ucos-ii将中断关闭。5. 任务控制块(OS_TBC)任务一旦建立,任务控制块OS_TBC将被赋值。OS_TBC是一个数据结构,当任务的CPU使用权被剥夺后,ucos-ii将把当前的任务状态存放于OS-TBC数据结构中;当任务的CPU使用权得到恢复后,任务控制块能确保任务能从被中断点那一点丝毫不差地继续执行。每个任务都有自己的OS_TBC控制块,OS_TBC的数量由OS_MAX_TASK决定,任务数量少,当然OS_TBC占用RAM的空间就少。所有的任务控制块OS_TBC都是放在任务控制块列表数组OSTCBTbl[]中。在ucos-ii初始化时,所有任务控制块OS_TBC都被链表连接成单向空任务链表。注意:OS_TBC全部驻留于RAM中。6. 关于任务切换使用到的OS_TASK_SW()函数,其中调用软中断实现寄存器的保持和弹出。开始调用含软中断,ucos-ii强制处理器保存psw、pc的当前值,最后通过执行中断返回指令,pc和psw的值装回到cpu中。1.中断服务所做的事应尽量少做,应把大部分工作留给任务去做。2.OSIntExit()和OSSched()有点相似,但OSIntExit()使中断nestiing减1,而重新调度的条件是:中断nesting和锁定nesting计算器(OSLockNesting)均为0。3.OS_TASK_SW()和OSCtxSw()的区别:后者使用于中断服务程序中,中断返回已经对cpu做了保存工作。而前者需要采用模仿软中断返回指令实现cpu保存。4.时钟节拍(1)ucos-ii需要提供周期性的信号源,用于实现时间延迟和确认超时。节拍率应为10~100Hz,时钟节拍率越高,系统额外的负荷就越重。(2)系统多任务启动时候(调用OSStart())之后,第一件初始化事情就是初始化定时中断。(3)ucos-ii中的时钟节拍服务是通过在中断服务子程序(OSTickISR())中调用OSTimeTick()实现的。OSTimeTick()跟踪所以任务的定时器和超时时限。时钟节拍中断服从一般中断规则(含任务调度判断)。5.OSTCBList指向任务控制块链表的开始,而且它总是指向最新建立的任务。6.非常好的一个图示:OSInt()之后的变量和数据结构。请参阅P1127.启动多任务时,执行OSStart()函数,OSStart()先从任务就绪表中找出用户建立的优先级最高的任务的任务控制块,而后调用了OSStartHighRdy(),此函数实质上是将任务堆栈中的保存内容返回到cpu寄存器中,然后执行一条中断返回指令。【信号量专题】 1. 信号量的理解(1)uc/os-ii的信号量是由两个部分组成:一部分是16位的无符号整型信号量的计数值(0~65535);另一部分是等待该信号量的任务组成的等待任务表。(另外参考事件控制块ECB)(2)信号量可以是2值的变量(称为二值信号量),也可以是计数式的。根据信号量的值,内核跟踪那些等待信号量的任务。(3)建立信号量的工作必须在任务级代码中或者多任务启动之前完成。(4)任务要得到信号量的问题。想得到信号量的任务,必须执行等待操作(pend)。如果信号量有效(非0),则信号量减1,任务得以继续运行。如果信号量无效,则等待信号量的任务就被列入等待信号量的任务表中。多少内核允许定义等待超时,当等待时间超过了设定值,该信号量还是无效,则等待该信号量的任务进入就绪态,准备运行,并返回出错代码(等待超时错误)。(5)任务对信号量的释放问题。任务执行发信号(post)操作来释放信号量。如果没有任务等待信号量,那么信号量的值仅是简单的加1(则信号量大于0,有效);如果有任务等待该信号量,那么就会有另一个任务进入就绪态,信号量的值就不加1。之后,这个释放的信号量给那个等待中的任务,要看内核如何调度的。收到信号量的任务可能是如下两者之一:◆等待任务中,优先级最高的;(uc/os-ii仅支持这种方式)。◆最早开始等待信号量的任务(如果是按先进先出FIFO原则)。2. 信号量的有效与无效问题信号量有效:信号量的计算器非0(.OSEventCnt!=0)。信号量有效表示任务对资源可用。信号量无效:信号量的计算器为0。信号量无效表示任务对目前资源不可用,需要等待其他另一个任务(或者中断服务子程序)发出该信号量(OSSemPost)。3. 信号量的值(.OSEventCnt)大小表示什么?二值信号量,表示任务可以独占共享资源。计数式信号量,用于某资源可同时为N个任务所用。4. 信号量是如何实现任务之间的通信的?参见第1点的(4)(5)概述。5. 信号量有关的三个重要函数分析◆OSSemCreate() 创建一个信号量 (注:由任务或启动代码操作)创建工作必须在任务级代码中或者多任务启动之前完成。功能只要是先获取一个事件控制块ECB,写入一些参数。其中调用了OS_EeventWaitListInt()函数,对事件控制块的等待任务列表进行初始化。完成初始化工作后,返回一个该信号量的句柄(Handle)。◆OSSemPend() 等待一个信号量 (注:只能由任务操作)本函数应用于任务试图获得共享资源的使用权、任务需要与其他任务或中断同步及任务需要等待特定事件发生的场合。如果任务Task_A调用OSSemPend(),且信号量的值有效(非0),那么OSSemPend()递减信号量计数器(.OSEventCnt),并返回该值。换句话说,Task_A获取到共享资源的使用权了,之后就执行该资源。如果如果任务Task_A调用OSSemPend(),信号量无效(为0),那么OSSemPend()调用OS_EventTaskWait()函数,把Task_A放入等待列表中。(等待到什么时候呢?要看OSSemPost()(或者等待超时情况),由它释放信号量并检查任务执行权,见下资料)◆OSSemPost() 发出(释放)一个信号量 (注:由任务或中断操作)本函数其中调用OS_EventTaskRdy()函数,把优先级最高的任务Task_A(在这假如是Task_A,另外假设当前调用OSSemPost()的任务是Task_B)从等待任务列表中去除,并使它进入就绪态。然后调用OSSched()进行任务调度。如果Task_A是当前就绪态中优先级最高的任务,则内核执行Task_A;否则,OSSched()直接返回,Task_B继续执行。互斥型信号量1.互斥型信号量(mutex) 互斥型信号量具备uc/os-ii信号量的所有机制,但还具有其他一些特性。 任务可利用互斥型信号量来实现对共享资源的独占处理。 Mutex是二值信号量,1表示资源是可以使用的。2.关于优先级反转 下面概述优先级反转原理: 假设有三个任务,分别命名为A,B,C;A的优先级最高,C的优先级最低。任务A和任务B处于挂起状态(请注意这条件),等待某一事件的发生,任务C正在运行。当任务C等待到共享资源(命名为S1)并使用后,如果任务A等待得事件到来之后,由于A的优先级最高,所以就会剥夺任务C的CPU使用权。运行过程中,任务A也要使用资源S1,但S1的信号量还被任务C占用着,所有任务A只能进入挂起状态,等待任务C对S1的信号量的释放。此时任务C得以继续运行。 同理,任务B的事件到来后,会剥夺任务C的CPU使用权。任务B把事情搞定以后,把CPU使用权归还给任务B(呵呵,优先级低就是给人欺负啊,所以做人还真的要争口气!)。任务B又得以继续运行,任务B认真处理完毕资源S1后,终于可以释放S1的信号量。而处于等待该信号量的任务A马上得到信号量并开始处理共享资源S1。 综述上面情况,任务C和任务A的优先级发生了反转。 而互斥型信号量就是具有解决优先级反转问题的特性。3.uc/os-ii的互斥型信号量由三个部分组成:◆一个标志,指示mutex是否可以使用(0或1)◆一个优先级,准备一旦高优先级的任务需要这个mutex,赋予给占有mutex的任务。◆一个等待该mutex的任务列表。
用户1464311 2010-8-30 09:06