完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
嵌入式实时操作系统内核主要工作就是对任务进行管理和调度,为我们提供丰富的、高度封装的多任务管理函数对任务进行管理。
比如任务的创建,挂起,删除和调度等。因此弄清μC/OS-III操作系统中,什么是任务,任务结构,任务管理方法,就显得尤为重要。 根据嵌入式系统任务的执行特点,任务通常是一个无限循环结构。因为应用中有很多需要重复的工作(例如,读取输入值、更新显示、控制操作等)。 此外,μC/OS-III系统最为重要的特性是一个多任务系统。但什么是多任务系统呢? 简单说就是由一个处理器并发(注意不是同时)地运行多个程序的计算机管理系统。 那,什么又是并发呢?并发的意思是说,由同一个处理器轮换地运行多个程序。或者说是由多个程序轮班地占用处理器这个资源。且在占用这个资源期间,并不一定能够把程序运行完毕。 虽然uC/OS-III支持多任务且对任务数量没有限制, 但任务数仅取决于处理器内存的大小(RAM)。多任务调度是任务间占用CPU的过程 。 |
|
|
|
μC/OS-III 的启动和初始化
①系统初始化,其实就是和使用外设一样,在启动μC/OS-III前,我们必须现在main函数里将μC/OS-III进行初始化。调用API函数CPU_Init()初始化μC/OS-III。 ②创建任务,随后我们都在main函数中创建一个开始任务用于创建其他的任务函数、事件或者信号等。创建任务是调用API函数OSTaskCreate(),将任务的信息填入其中即可。并将这一段创建任务的函数置于临界区中避免打断。 ③启动系统,我们自己创建完第一个任务后,便可以调用API函数OSStart();开启μC/OS-III。 在 uC/OS-III 中,可以创建无数多个任务,让这些任务并发运行,就好像有多个主函数在运行一样。 在 uC/OS-III 初始化的时候,至少会创建空闲任务 OS_IdleTask()和时基任务OS_TickTask() 这 两 个 任 务 , 另 外 还 有 三 个 可 选 择 的 内 部 任 务 , 软 件 定 时 器 任 务OS_TmrTaks() 、中断延迟提交任务 OS_IntQTask()和统计任务 OS_StatTask()。 |
|
|
|
任务状态
uC/OS-III支持的是单核的CPU,不支持多核,这样在某一时刻只有一个任务会获得CPU的使用权进入运行态。其他任务就会进入其他状态,uC/OS-III中的任务有多个状态, 任务状态之间的具体切换情况如下图所示。 |
|
|
|
任务控制块
任务控制块,本质上其实就是由一个struct结构体,用来保存任务的信息(知道这一点就可以了)。在使用API函数OSTaskCreate()时,就会给创建的任务分配一个任务控制块。 |
|
|
|
任务堆栈
堆栈是一个很重要的概念,堆栈的使用是在任务切换或者调用其他的函数的时候,保护现场和断点。方便在返回后继续执行(注意:uC/OS-III中在调用其他任务返回后会检验一次任务的最高优先级,优先执行优先级高的),因此每一个任务都有自己的堆栈。 CPU_STK在cpu.h中有定义,就是CPU_INT32,固一个CPU_STK变量为4字节。所以上述代码的堆栈大小为64*4=256字节。 良好的编程习惯是一般如上图所示用宏定义,方便后续的修改和移植。 我们调用API函数OSTaskCreate()创建任务时,如上图红色字体所示可以把堆栈的信息传递给任务。 同时会初始化任务的堆栈,提前将CPU的寄存器保存在任务堆栈中,完成这些操作的是OSTaskInit()函数,用户不用调用这个函数,这个函数被OSTaskCreate()函数在创建任务的时候电泳。 堆栈深度通常是堆栈大小的十分之一,主要是用来检测堆栈是否为空。 |
|
|
|
任务就绪表
在μC/OS-III中,所有已经就绪等待运行的任务放置于任务就绪列表中。就绪表包括两部分:一个就绪优先级表OSPrioTbl[ ],用于表明哪个优先级下有任务就绪;一个就绪任务列表OSRdyList[ ],其中包含指向各个就绪任务的指针。 ①优先级位映射表 优先级位映射表的结构如下图所示,该表的位宽有CPU_DATA决定,可以是8位,16位或者32位。一般根据所使用的处理器来决定 os_prio.c文件包含了置位、清零和查找就绪优先级位映射表等相关操作的代码。这些函数是内部函数。下表列出了优先级操作函数。 当要查找包含就绪任务的最高优先级时,程序会逐项扫描就绪优先级位映射表,知道遇到第一个非零位为止。该操作通过调用OS_PrioGetHighest()函数实现的。其代码如下: ②就绪任务列表 数组OSRdyList[ ]用来记录每一个优先级下的所有就绪的任务,如下图所示 可以看出就绪任务列表是一各包含OS_CFG_PRIO_MAX项的数(OSRdyList),数组元素分别为Enteries,TailPtr,HeadPtr。 Enteries用于记录对应优先级下就绪任务的数量。如果对应的优先级下没有任务就绪,那么该值为0. TailPtr和HeadPtr用来创建一个双向链表。 就绪表的操作函数如下: 这些函数在文件os_core.c中,仅在μC/OS-III内部使用,用户程序不能调用这些行数。 |
|
|
|
任务的调度和切换
uC/OS-III是一个可抢占的, 基于优先级的内核。“可剥夺型”(preemptive)意味着当一个事件发生,并且使得一个更高优先级的任务就绪时,μC/OS-III就会立即将CPU的控制权剥夺,转交给更高优先级的任务使用。 而任务调度和切换就是让就绪表中优先级最高的任务获得CPU的使用权,任务的调度是通过任务调度器(scheduler)来实现的,任务调度器又叫调度程序(dispatcher)。是μC/OS-III的一部分,负责确定下一个要执行的任务。 任务调度是通过这两个函数完成调度功能: OSSched()和OSIntExit()。 OSSched()在任务级被调用, OSIntExit()在中断级被调用。这两 个函数都在os_core.c中有定义。 以下是任务级调度伪代码 以下是中断级级调度伪代码 时间片轮转调度 当多个任务有相同的优先级时, uC/OS-III允许每个任务运行规定的时间片。 当任务没有用完分配给它的时间片时, 它可以自愿地放弃CPU。uC/OS-III允许任务在运行时开启或者关闭循环轮转调度。 下图是多个任务运行在同一优先级下的执行时间图。为了便于描述,时间片定位4个时钟节拍。 OS_SchedRoundRobin()的伪代码如下所示: |
|
|
|
只有小组成员才能发言,加入小组>>
934 浏览 1 评论
1090 浏览 1 评论
12506 浏览 0 评论
5922 浏览 3 评论
17716 浏览 6 评论
1022浏览 1评论
1013浏览 1评论
935浏览 1评论
4700浏览 1评论
1091浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-21 09:57 , Processed in 0.963510 second(s), Total 90, Slave 72 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号