首页 UCOS学习总结

UCOS学习总结

举报
开通vip

UCOS学习总结UCOS学习总结 UCOS的主要内容 一:内核管理 1:ucos的文件结构 应用软件 Ucos(与处理器无关 的代码) UCOS-11配置(与应OS_CORE.C 用相关)OS_FLAG.C OS_MBOX.C OS_MEM.C OS_MUTEX.C OS_Q.C OS_SEM.COS_CFG.H OS_TASK.CINCLUDE.H OS_TIME.C UCOS_11.C UCOS_11.H硬件 UCOS移植(与处理器相关代码)2:临界段,OS_ENTER_CRITICAL()和OS_EXIT_CRIT...

UCOS学习总结
UCOS学习总结 UCOS的主要内容 一:内核管理 1:ucos的文件结构 应用软件 Ucos(与处理器无关 的代码) UCOS-11配置(与应OS_CORE.C 用相关)OS_FLAG.C OS_MBOX.C OS_MEM.C OS_MUTEX.C OS_Q.C OS_SEM.COS_CFG.H OS_TASK.CINCLUDE.H OS_TIME.C UCOS_11.C UCOS_11.H硬件 UCOS移植(与处理器相关代码)2:临界段,OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。 OS_CPU.H,OS_CPU_A.ASM,OS_CPU_C.C它们可以用不同的 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 去实现,用定义(#define)常数OS_CRITICAL_METHOD(1,2,3)来选择用哪种方法来实现。 当OS_CRITICAL_METHOD=1时,表示用处理器指令关中断,完成OS_ENTER_CRITIACL,用开中断完成OS_EXIT_CRITICAL.利用这种方法有点小问题,即是调用UCOS功能函数之前,中断是关掉的,从UCOS返回后,中断就打开了。 当OS_CRITICAL_METHOD=2时,这种方法是在堆栈中保存中断的开关状态,然后再关中断。在实现OS_EXIT_CRITICAL时,只需简单的从堆栈中弹出原来中断的开关状态。利用这种方法,不论用户在调用函数之前中断是开着的还是关着的,函数的进入和返回状态都得到了保护。 当OS_CRITICAL_METHOD=3时,一些编译器提供了扩展功能,用户可以得到当前处理器的状态字,并保存在C函数的局部变量中,这个变量可以用于恢复PSW。 3:任务的状态 睡眠态:通过调用下述两个函数(OSTaskCreat()或OSTaskCreatExt())之一来实现的。 就绪态:任务一旦建立这个任务就进入了就绪态,准备运行。可以通过调用OSTaskDel()返回到睡眠态。 运行态:调用OSStart()可以启动多任务。 等待状态:正在运行的任务可以通过调用以下两个函数(OSTimeDly()或OSTimeDlyHMSM())之一,将自身延迟一段时间。正在运行的任务可能需要等待某一事件的发生,可以调用函数(OSFlagPend(),OSSempend(),OSMutexPend(),OSMboxPend(),OSQPend())之一来实现。 中断服务态:正在运行的任务可以被中断。 4:任务控制块(OS_TCB),,, 作用:当任务的CPU使用权被剥夺时,UCOS利用它来保存任务的状态。 5:就绪表 每个就绪的任务都放在就绪表中,就绪表中有两个变量,OSRdyGRP和OSRdyTbl【】。 OSRdyGrp中每一位表示8组任务中每一组是否有进入就绪态的任务。当有任务进入就绪态时,就绪表OSRdyTbl[]中相应元素的相应位也置为1。 6:任务调度OS_SCHED() Ucos总是进行进入就绪态任务中优先级最高的任务,确定哪个任务优先级最高,这一工作就是有调度器完成的。 7:任务切换OS_TASK_SW() 需恢复该任务在CPU使用权被剥夺时保存下来的全部寄存器的值,之后,运行被切换的任务。 8:给调度器上锁和开锁 给调度器上锁函数OSSchedlock()用于禁止任务调度,直到任务完成后,调用调度器开锁函数OSSchedUnlock()为止。这两函数必须成对使用。 9:空闲任务OS_TaskIdle() 这个任务没有其他任务进入就绪态时,投入运行,空闲任务永远处于就绪态。空闲任务始终设为最低优先级。OSTaskIdle()可以调用OSTaskIdleHook()让CPU进入STOP指令,从而进入低功耗模式。当应用系统有电池供电时,这种方式特别有用。 10:统计任务OSTaskStat() 有一个统计运行时间的任务,叫做OSTaskStat()。告诉用户使用了多少CPU时间,用百分比表示。如果应用程序打算使用统计任务,在调用系统启动函数OSStart()之前,用户初始化代码中必须先建立一个任务,在这个任务中调用统计任务初始化函数OSStatInit(),然后再建立应用程序中的其他任务。 11:ucos的中断 a:中断请求,但还不能被CPU识别。 b:ucos或应用程序关中断。 c:转到相应的中断向量 d:保存CPU寄存器 e: 通知 关于发布提成方案的通知关于xx通知关于成立公司筹建组的通知关于红头文件的使用公开通知关于计发全勤奖的通知 内核:OsIntEnter()。 f:ISR给任务发信号。 g:通知内核退出中断服务:OSIntExit() h:恢复CPU寄存器 i:中断返回 j:通知内核退出中断OSIntExit(), k:恢复CPU寄存器,中断返回。 12:时钟节拍OSTimTick() 注意点:必须在多任务系统启动后,也就是调用OSStart()之后,再开启时钟节拍器。 13:ucos的初始化 14:ucos的启动 二:任务管理 1:建立任务OSTaskCreat()/OSTaskCreatExt() 如果想让UCOS管理用户的任务,必须先建立任务。可以通过将任务的地址和其他参数传递到以下两个函数之一来建立任务。当调用OSTaskCreat()时,需要四个参数: OSTaskCreate(void(*task)(void*pd),void*pdata,OS_STK*ptos,INTU prio) Task:是指向任务代码的指针,pdata:是任务开始执行是,传递给任务的参数的指针,ptos:是分配给任务的堆栈的栈顶指针,prio是分配给任务的优先级。 OSTaskCreateExt()函数来建立任务会更加灵活,但是会增加一些额外的开销。 2:任务堆栈OS_STK() 每个任务都有自己的堆栈,堆栈必须申明为OS_STK类型,并且由连续的内存空间组成。可以静态分配堆栈空间,也可以动态分配堆栈空间。 3:堆栈检验OSTaskStkChk() 有时确定任务实际需要的堆栈空间的大小是很有必要的,因为这样就可以避免为任务分配过多的堆栈空间,从而减少应用程序代码所需的RAM空间。 4:删除任务OSTaskDel() 有时需要删除任务,删除任务,是说任务返回并处于休眠态,并不是说任务的代码被删除了,只是任务的代码不再被UCOS调用。 5:请求删除任务OSTaskDelReq() 有时,任务会占用一些内存缓冲或信号量一类的资源。这时,假如另一个任务试图删除该任务,这些被占用的资源就会因为没有被释放而丢失。在这种情况下,需想办法拥有这些资源的任务在使用完资源后先释放资源,再删除自己 6:改变任务的优先级OSTaskChangePrio() 在建立任务是,会分配给任务一个优先级。在程序运行期间,可以通过调用该函数改变任务的优先级。也就是说,UCOS允许动态的改变任务的优先级。 7:挂起任务OSTaskSuspend() 任务挂起是一个附加功能,也就是说,如果任务在被挂起的同时也在等待延迟时间到,那么,需要对任务做取消挂起的操作,并且等待延迟时间到,任务才能转让就绪状态。任务可以挂起自己或者其他任务。 8:恢复任务OSTaskResume() 别挂起的任务只有通过该函数才能被恢复。 9:获得任务的信息OSTaskQuery() 通过调用该函数,来获得自身或其他应用任务的信息 三:时间管理 1:任务延迟函数OSTimeDly() Ucos提供一个可以被任务调用而将任务延时一段特定时间的功能函数,即OSTimeDly().任务调用OSTimeDly()后,一旦 规定 关于下班后关闭电源的规定党章中关于入党时间的规定公务员考核规定下载规定办法文件下载宁波关于闷顶的规定 的时间期满或者有其他的任务通过调用OSTimeDlyResume()取消了延时,他就会进入就绪状态。只有当该任务在所有就绪态任务中具有最高的优先级,它才会立即运行。 2:按时,分,秒延时函数OSRimeDLyHMSM() 与OSTimeDly()一样,调用OSRimeDlyHMSM()函数也会是UCOS进行一次任务调度,并且执行下一个优先级最高的就绪任务。当OSTimeDlyHMSM()后,一旦规定的时间期满,或者有OSTimeDlyResume(),它就会马上处于就绪态。同样,只有当该任务在所有就绪态任务中具有最高的优先级,他才开始运行。 3:恢复延时的任务OSTimeDlyResume() 延时的任务可以不等待延时的期满,而是通过其他任务取消延时而使自己处于就绪态,可以通过该函数来实现,实际上,OSTimeDlyResume()也可以唤醒正在等待的事件。 4:系统时间OSTimeGet()和OSTimeSet() 四:事件控制块(ECB) 任何任务或中断服务子程序可以通过事件控制块ECB向另外的任务发信号,这里信号看成是事件。 事件控制块ECB的数据结构 Typedef struct { INT8U OSEventType; ;定义了事件的具体类型 INT8U OSEventGrp; ; INT16U OSEventCnt; ;当事件控制块用于信号量时,该变量用于信号量的计数器。 Void *OSEventPtr; ;只有所定义的事件是消息邮箱或者消息队列时才使用。 INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; }OS_EVENT; 1:初始化一个事件控制块,OS_EventWaitLListInit() 当建立一个信号量,邮箱或者消息队列时,通过调用该函数,对事件控制块中的等待任务列表进行初始化。 2:使一个任务进入就绪态,OS_EventTaskRdy() 该函数从等待任务队列中使最高优先级任务脱离等待状态,并把该任务置于就绪态。 3:使一个任务进入等待某事件发生状态OS_EventTaskWait() 当某个任务需等待一个事件的发生时,信号量,互斥型信号量,邮箱及消息队列会通过相应的PEND函数调用该函数,使当前任务从就绪任务表中脱离就绪态,并放到相应事件的事件控制块的等待任务表中。 4:由于等待超时而降任务置为就绪态OS_EventTo() 如果在预先指定的等待时限内任务等待的事件没有发生,那么该函数就会因为等待超时而将任务的状态量置为就绪态。在这种情况下,信号量,互斥型信号量及消息队列会通过PEND调用该函数,以完成这项工作。 五:信号量管理 信号量有两部分组成:一部分是16位无符号整型信号量的计数值,另一部分是有等待该信号量的任务组成的等待任务表。 1:建立一个信号量,OSSemCreate() 使用一个信号量之前,首先须建立该信号量,可以调用该函数来建立信号量,并对信号量赋予初始计数值。该初始值为0,65535.如果该信号量是用来表示一个或者多个事件发生,那么该信号量的初始值通常赋为0;如果该信号量用于对共享资源的访问,那么该信号量的初始值应赋为1;如果该信号量用来表示允许任务访问n个相同的资源,那么该信号量的初始值应赋为n,并把该信号量作为一个可记数的信号量使用。 2:删除一个信号量,OSSemDel() 如果要删除一个信号量,在OS_CFG.H中,OS_SEM_DEL_EN须置为1,该函数才能被使用。 3:等待一个信号量OSSemPend() 4:发出一个信号量OSSempend() 5:无等待的请求一个信号量OSSemAccept() 当一个任务请求一个信号量时,如果该信号量暂时无效,也可以让该任务简单的返回,而不是进入睡眠等待状态。这种操作由该函数完成。 6:查询一个信号量的当前状态,OSSemQuerey() 可以通过该函数,来插叙一个信号量的当前状态。 7:互斥型信号量管理 六:互斥信号量管理 任务可以使用互斥型信号量实现对共享资源的独占式处理,互斥型信号量mutex。 1:建立一个互斥型信号量,OSMutexCreate() 在使用mutex之前,必须建立它,建立mutex是通过该函数来实现的,当mutex的初始值为1时,表示资源是可以利用的。 2:删除一个互斥型信号量,OSMutexDel() 只有当OS_CFG.H文件中OS_MUTEX_DEL_EN的值为1时,该函数才有效。 3:等待一个互斥信号量,OSMutexPend() 4:释放一个互斥型信号量,OSMutexPost() 5:无等待的获取互斥型信号量(任务不挂起),OSMutexAccept() 如果要得到mutex,而当前mutex无效,那么不让任务进入休眠态也是可以的,这时可以通过调用该函数来实现。 6:获取互斥型信号量的当前状态,OSMutexQuery() 用来获取互斥型信号量的事件控制块的当前状况。 七:事件标志组管理 事件标志组由两部分组成:一是用来保存当前事件中各事件状态的一些标志位;二是等待这些标志位置位或清除的任务列表。 事件标志组数据结构 Typedef struct { INT8U OSFlagType; ;用来检验指针的类型是否是事件标志组的指针。 Void *OSFlagwaitList; ;包含一个等待事件标志组的任务列表。 OS_FLAGS OSFlagFlags; ;包含一系列表明当前事件标志状态的位。 }OS_FLAG_GRP; 1:建立一个事件标志组,OSFlagCreate() 2:删除一个事件标志组,OSFlagCreate() 3:等待事件标志组的事件标志位,OSFlagPend() 4:置位或清0事件标志组中的事件标志,OSFlagPost() 5:无等待的获得时间标志组中的事件标志,OSFlagAccept() 八:消息邮箱管理 消息邮箱是一种通信机制,可以使一个任务或者中断服务子程序向另一个任务发送一个指针型变量。 1:建立一个邮箱,OSMboxCreate() 使用邮箱之前,必须建立邮箱,该操作可以通过调用该函数来实现,并且须定时指针的初始值。一般情况下,这个初始值为NULL;但也可以初始化一个邮箱,使其在最开始就包含一条消息。 2:删除一个邮箱,OSMboxDel() 3:等待邮箱中的消息,OSMboxPend() 4:向邮箱发送一则消息,OSMboxPost() 5:向邮箱发送一则消息,OSMboxPostOpt()(该函数比OSMboxPost()函数功能更强大。) 6:无等待的从邮箱中得到一则消息,OSMboxAccept() 7:查询一个邮箱的状态,OSMboxQuery() 8:用邮箱作为二值信号量 9:用邮箱实现延时,而不是用OSTimeDly() 九:消息队列管理 消息队列是UCOS的另一种通信机制。它允许一个任务或者中断服务子程序向另一个任务发送以指针方式定义的变量或其他任务。 1:建立一个消息队列,OSQCreate() 该函数建立一个队列,并赋值给它2个参数:指向消息数组的指针和数组的大小。该指针数组必须声明为void OS_EVENT *OSQCreate(void **start,int16u size) 2:删除一个消息队列,OSQDel() ~~~:在删除一个消息队列之前,应该首先删除所有可能用到这个消息队列的任务。 3:等待消息队列中的消息,OSQPend() 4:向消息队列发送一则消息,OSQPost(), 5:向消息队列发送一则消息,OSQPostFront() 该函数和上述基本一样,只是在插入新的消息到消息队列时,使用OSQOut,而不是OSQIn,作为指向下一个插入消息的单元指针。 6:向消息队列发送一则消息,OSQPostOpt() 该函数最新,包含上述两函数的功能。 7:无等待的从消息队列中获得消息,OSQAccept() 8:清空消息队列,OSQFlush() OSQFlush()允许清空一个消息队列中的所有消息,以重新开始使用。 9:获取当前消息队列的状态,OSQQuery() 十:内存管理 内存控制块的数据结构 Typedef struct { void *osmemaddr ;指向内存分区起始地址的指针。 Void *osmemfreelist; ;指向下一个空余内存控制块或者下一个空余内存块的指针, Int32u osmemblksize; ;内存分区中内存块的大小,是建立内存分区时定义的。 Int32u osmemnblks; ;内存分区中总的内存块数量,也是建立该内存分区时定义的。 Int32u osmemnfree; ;内存分区块中当前获得的空余块数量。 }os_mem; 1;建立一个内存分区,OSMemCreate() 2:分配一个内存块,OSMemGet() 应用程序通过调用该函数,从已经建立的内存分区中 申请 关于撤销行政处分的申请关于工程延期监理费的申请报告关于减免管理费的申请关于减租申请书的范文关于解除警告处分的申请 一个内存块。该函数唯一的参数是指向特定内存分区的指针。 3:释放一个内存块,OSMemPut() 当应用程序不再使用一个内存块时,必须及时的把它释放,并放回到相应的内存分区中,这个操作就是通过调用该函数实现的。 4:查询一个内存分区的状态,OSQMemQuery()。 对一些概念的理解 实时系统概念 1 前后台系统 不复杂的小系统通常选择前后台系统,应用程序是一个无限循环。在循环中调用相应的函数完成相应的操作,这部分可以看成后台行为。中断服务程序处理异步事件,可以看成前台行为。 2 代码的临界段 需要在前后关开中断的代码,不能被打断的代码 3 资源 输入输出设备,各种变量,结构,数组 4 共享资源 可以被多个任务使用的资源 5多任务 通过CPU在许多任务之间转换和调度 6任务 每个任务都是一个无限循环,都可能处于五种状态之一:休眠,就绪,运行,挂起,被中断。UCOS中提供各种函数使任务能从一个状态变为另一个状态 每个任务都有自己的CPU寄存器和栈空间以及TCB任务控制块 7任务切换 任务切换过程是将正在运行任务的CPU寄存器全部内容保存到任务自己的栈区中,再将下一个要运行的任务的当前状况从该任务的栈中重新装入CPU的寄存器,并开始下一个任务的运行 8内核 负责管理各个任务,为每个任务分配CPU时间,并负责任务间的通信 9调度 决定该轮到哪个任务运行。主要是通过优先级来决定。总是让处于就绪态的优先级最高的任务先运行。 10不可剥夺型内核 每个任务主动放弃CPU的使用权,放弃的方法可以使用多种函数定时或者定事件的放弃。异步事件还是由中断服务来处理。中断处理结束之后还是回到被中断的那个任务直到该任务主动放弃CPU的使用权。在任务级,不可剥夺型内核允许使用不可重入函数函数不必担心被重复调用,因为每个时刻都只有一个任务在运行。当然,该函数不能具有放弃CPU使用权的功能。 11可剥夺型内核 当系统响应时间很重要,就需要使用可剥夺型内核。最高优先级任务一旦就绪,总能得到CPU的使用权。当运行的任务使一个更高优先级的任务进入就绪态,当前任务的CPU使用权就被剥夺或挂起,更高优先级的任务获得CPU的使用权。如果是中断服务子程序造成的,中断完成后被中断的任务被挂起,执行更高优先级的任务。 在可剥夺型内核中,要谨慎使用不可重入函数。因为低优先级的和高优先级的任务有可能都调用该函数。 总是让就绪态的高优先级的任务先运行,中断服务程序可以抢占CPU 12可重入函数 可重入函数或者只使用局部变量,要么就是使用全局变量并且对全局变量予以保护。 13时间片轮番调度法 UCOS中各个任务的优先级都是不同的。。不支持时间片轮番调度 14任务优先级 从0开始,越小的优先级越高 15静态优先级 在执行过程中优先级是不变的 16动态优先级 优先级在运行过程中可以变化 17优先级反转 避免优先级反转的方法是使占有共享资源的任务的优先级升到最高。 18任务优先级分配 19互斥条件 满足互斥条件的一般方法: 关中断 使用测试并置位指令,获得共享资源时置位,只有为零才有权获得共享资源 禁止作任务切换:用给任务切换上锁然后开锁的方法 利用信号量:信号量的操作:初始化create 挂起pend 发送post UCOS中是等待信号量任务中优先级最高的 20死锁 死锁也称为抱死指两个任务无限期地互相等待对方控制着的资源。 21同步 可以单向同步也可以双向同步 22事件标志 当某个任务要与多个事件同步时,须使用事件标志。 23任务间通信 任务间或中断服务与任务间的通信。有两种途径:通过全程变量或者发消息给另一个任务 24消息邮箱 把一则消息放到邮箱,通过内核也可以接收这则消息。 25消息队列 用于给任务发消息。 26中断 27中断延迟 28中断响应 29中断恢复时间 对于可剥夺型内核,中断的恢复要复杂一些。在中断服务子程序的末尾,要调用一个由实时内核提供的函数。这个函数用于判断中断是否脱离了所有嵌套。如果脱离了嵌套就判断是 否中断让一个更高优先级的任务进入就绪。 30中断延迟、响应及恢复 31中断处理时间 32非屏蔽中断 33时钟节拍 34对存储器的需求 使用多任务内核时内核本身需要额外的代码空间ROM。因为每个任务都是独立运行的,必须给每个任务提供单独的栈空间RAM。 内核结构 1临界段,OS_ENTER_CRITICAL和OS_EXIT_CRITICAL 开关中断的实现方法分三种: 1)直接用处理器指令 2)在堆栈中保存中断的开关状态,然后再关中断。 3)通过编译器提供的c函数来保存处理器状态字的值。 2任务 3任务状态 睡眠态:在ROM或RAM中,交给UCOS要调用下面两个函数之一:OSTaskCreate或者OSTaskCreateExt,调用之后告诉了UCOS任务的起始地址,优先级,要使用多少栈空间。 就绪态:建立了任务之后,就进入就绪态。如果是由任务建立的新任务且优先级更高,那么新建的任务将立即得到CPU使用权。通过OSTaskDel将一个任务返回到睡眠态。 运行态:调用OSStart可以启动多任务,该函数运行用户初始化代码中已建的优先级最高的任务。 等待态:正在运行的任务通过两个函数将自己延迟即进入等待状态。OSTimeDly或者OSTimeDlyHMSM。这两个函数将会立即执行强制任务切换,让下一个优先级最高且进入就绪态的任务运行。当延时时间到后,系统服务函数OSTimeTick将会让等待的任务进入就绪态。在运行中的任务如果调用OSFlagPend、OSSemPend、OSMutexPend、OSMboxPend或者OSQPend时时间并没有发生,那么该任务就进入等待态,此时最高优先级的就绪态任务进入运行态。当等待事件发生或者等待超时,该任务就从等待态进入就绪态。 中断服务态:正在运行的任务可以被中断。被中断了的任务进入中断服务态。响应中断时该任务被挂起,中断服务子程序可能 报告 软件系统测试报告下载sgs报告如何下载关于路面塌陷情况报告535n,sgs报告怎么下载竣工报告下载 多个事件发生,从而使得更高优先级的任务进入就绪态,当中断返回时会重新判断优先级,让最高优先级的任务运行,如果由更高优先级的任务那么先执行,直到被挂起的任务的优先级最高才会返回到被中断挂起的任务。 4任务控制块TCB 当任务建立的时候一个任务控制块TCB就被赋值,任务控制块能确保任务从被中断的那一点丝毫不差的继续运行。OS_TCB全部驻留在RAM中。OS_TCB中包括:指向当前任务堆栈栈顶的指OSTCBStkPtr、指向用户定义的任务控制块扩展OSTCBExtPtr(该扩展数据结构包含任务名字、跟踪某个任务的执行事件、跟踪切换到某个任务的次数)、指向任务堆栈栈底的指针OSTCBStkBottom(如果堆栈指针递减则指向任务使用的栈空间的最低地址)、存有栈中可容纳的指针元数目OSTCBStkSize(是指针元数目,乘以地址宽度即为实际栈容量)、选择项OSTCBOpt(传给OSTaskCreateExt)、用于存储任务的识别码OSTCBId、用于任务控制块双向链表的前后链接OSTCBNext/OSTCBPrev、指向事件控制块的指针OSTCBEventPtr、指向传递给任务的消息的指针OSTCBMsg、指向事件标志节点的指针OSTCBFlagNode、使任务进入就绪态的事件标志OSTCBFlagsRdy、延时或者挂起一段事件时用来计时的变量OSTCBDly、任务的状态字OSTCBStat(OS_STAT_READY,就绪态)、任务的优先级OSTCBPrio、用于加速任务进入就绪态的过程或进入等待事件发生状态的过程OSTCBX/OSTCBY/OSTCBBitX/OSTCBBitY、一个表示该任务是否须删除的布尔量OSTCBDelReq。所有的任务控制块OS_TCB都是放在任务控制块列表数组OSTCBTbl【】中。所有任务控制块OS_TCB都被链接成单向空任务链表。任务一旦建立,空任务控制块指针OSTCBFreeList指向的任务控制块便赋给了该任务。任务建立时,任务建立函数调用任务控制块初始化函数OS_TCBInit。在初始化OS_TCB的时候调用了用户自定义的函数OSTCBInitHook和OSTaskCreateHook函数。两个函数都是扩展作用的。当新建的任务块要插入表中时先要关中断,新任务的控制块总是插在OSTCBList表的开头。 5就绪表 每个就绪的任务都放在就绪表中,就绪表中有2个变量OSRdyGrp和OSRdyTbl【】。OSRdyGrp中任务按优先级分组,8个任务一组,8位表示8组任务中每组是否有进入就绪态的任务。进入就绪态后,就绪表OSRdyTbl【】中相应元素的相应位置1。因此,使任务进入就绪态的程序为: OSRdyGrp |= OSMapTbl[prio>>3]; OSRdyTbl[prio>>3] |= OSMapTbl[prio & 0x07]; OSMapTbl[]是屏蔽字,将0,7的下标转换成各自位置1的8位值 通过优先级判定表OSUnMapTbl查找任务的优先级,即OSUnMapTbl[OSRdyGrp]×8,OSUnMapTbl[OSRdyTbl[OSUnMapTbl[OSRdyGrp]]]。得到优先级后,查任务控制块优先级 表OSTCBPrioTbl【】得到指向相应任务的任务控制块OS_TCB。 6任务调度 任务级的调度是由OSSched完成,中断级的调度是由函数OSIntExt完成的。任务调度函数将找出优先级最高的进入就绪态的任务,检查该任务是否是当前正在运行的任务,如果不是才进行任务调度。为了实现任务的切换将该任务的控制块从任务控制块优先级表中取出并赋给OSTCBHighRdy,将统计切换次数的变量加1来跟踪任务切换次数。最后就可以使用宏调用OS_TASK_SW完成实际上的任务切换 任务切换:将被挂起任务的寄存器推入堆栈再将准备运行的任务的寄存器从栈中恢复到寄存器。因此UCOS运行就绪态任务要做的就是恢复所有的CPU寄存器并运行中断返回指令。这里是一段重点,为了实现任务切换,运行OS_TASK_SW人为模仿了一次中断。在ARM中由软中断指令来实现上述操作。必须给汇编语言函数OSCtxSw提供中断向量。OSCtxSw除了需要OS_TCBHighRdy指向即将被挂起的任务,还需让当前任务控制块OSTCBCur指向即将被挂起的任务。OSCtxSw挂起了正在执行的任务而让CPU执行更重要的任务。 7任务级的任务切换OSCtxSw OSCtxSw是宏调用通常含有软中断指令,切换是靠中断级代码完成的。UCOS将与实际处理器相关的软件中断机制封装起来易于移植。 8 给调度器上锁和开锁 上锁函数OSSchedlock,调用该函数可以禁止任务调度,保持该任务对CPU的使用权,不过中断还是可以识别,中断服务也能得到,因为中断是开着的,中断和调度是两个意思。其中变量OSLockNesting跟踪OSSchedLock函数被调用的次数所以允许嵌套函数。如果OSLockNesting,0调度重新得到允许。 9空闲任务 UCOS-II中总要建立一个空闲任务,主要是计数,然后有一个用户定义的函数OSTaskIdleHook。 10统计任务 除了空闲任务还有一个统计运行时间的任务OSTaskStat,它告诉用户应用程序使用了多少CPU时间,用百分比表示。 11UCOS-II中的中断 中断服务子程序的编写:保存全部CPU寄存器;调用OSIntEnter或者OSIntNesting直接加1;如果是中断的第一层,立即将堆栈指针保存到这个任务;如果需要重新允许中断,必须清中断源,重新开中断;用户设定;调用脱离中断函数OSIntExit,标志着中断服务子程序的结束。 OSIntExit是使中断离开的函数,当中断嵌套层数计数器和锁定嵌套计数器都为0才重新开始调度,然后选择一个优先级最高的任务。最后应该调用中断切换函数OSIntCtxSw而不应该调用任务切换函数OS_TASK_SW。因为在中断之前已经把CPU寄存器存入到中断了的任务堆栈中不需要再用。这部分也牵涉到后面的移植部分。 12时钟节拍 在调用OSStart之后应做的第一件事情就是初始化定时器中断。时钟节拍服务是通过在中断服务子程序中调用OSTimeTick实现的。 时钟节拍中断服务子程序: OSTickISR(void) { 保存CPU寄存器的值 调用OSIntEnter或是将OSIntNesting加1 如果OSIntNesting等于1则将当前堆栈指针存入当前任务控制块的堆栈中 调用OSTimeTick 清发出中断设备的中断 重新允许中断 调用OSIntExit 恢复处理器寄存器的值 执行中断返回指令 } 其中OSTimeTick通过OSTimeTickHook函数进行扩展。除此之外最大的任务就是给每个用户任务控制块OS_TCB中的时间延时项OSTCBDly减1。
本文档为【UCOS学习总结】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_594886
暂无简介~
格式:doc
大小:44KB
软件:Word
页数:0
分类:生活休闲
上传时间:2017-09-25
浏览量:22