【UCOSIII】UCOSIII的任务管理
UCOSIII任务创建
UCOSIII是多任务系统,那么肯定要能创建任务,创建任务就是将任务控制块、任务堆栈、任务代码等联系在一起,并且初始化任务控制块的相应字段。在UCOSIII中我们通过函数OSTaskCreate()来创建任务,OSTaskCreate()函数原型如下(在os_task.c中有定义)。
OSTaskCreate()的函数定义为:
void OSTaskCreate (OS_TCB *p_tcb, //任务控制块CPU_CHAR *p_name, //任务名称OS_TASK_PTR p_task, //任务函数void *p_arg, //传递给任务函数的参数OS_PRIO prio, //任务优先级CPU_STK *p_stk_base, //任务堆栈基地址CPU_STK_SIZE stk_limit, //任务堆栈深度限位CPU_STK_SIZE stk_size, //任务堆栈大小 OS_MSG_QTY q_size, //任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息OS_TICK time_quanta, //当使能时间片轮转时的时间片长度,为0时为默认长度void *p_ext, //用户补充的存储区OS_OPT opt, //任务选项OS_ERR *p_err) //存放该函数错误时的返回值
{... //函数省略OSSched();
}
对于任务创建函数有几点解释的:
- 参数*p_arg:传递给任务的参数。这就要求我们在定义任务函数的时候,需要给它赋予任务参数;但是我们一般在创建任务的时候,很少会传递这个参数,一般为0。比如,任务start_task的任务说明:
void start_task(void *p_arg);
- 参数q_size:UCOSIII中每个任务都有一个可选的内部消息队列,我们要定义宏OS_CFG_TASK_Q_EN>0,这是才会使用这个内部消息队列;
- 参数opt:包含任务的特定选项,有如下选项可以设置:
选项 | 说明 |
OS_OPT_TASK_NONE | 表示没有任何选项 |
OS_OPT_TASK_STK_CHK | 指定是否允许检测该任务的堆栈 |
OS_OPT_TASK_STK_CLR | 指定是否清除该任务的堆栈 |
OS_OPT_TASK_SAVE_FP | 指定是否存储浮点寄存器 |
另外注意!不能在中断服务程序中调用OSTaskCreat()函数来创建任务。
UCOSIII任务删除
OSTaskDel()函数用来删除任务,当一个任务不需要运行的话,我们就可以将其删除掉,删除任务不是说删除任务代码,而是UCOSIII不再管理这个任务。
void OSTaskDel (OS_TCB *p_tcb,OS_ERR *p_err)
{... //函数省略OSSched(); /* Find new highest priority task */
}
对于任务删除函数有几点说明的:
- 调用OSTaskDel()删除一个任务后,这个任务的任务堆栈、OS_TCB所占用的内存并没有释放掉,因此我们可以利用他们用于其他的任务,当然我们也可以使用内存管理的方法给任务堆栈和OS_TCB分配内存,这样当我们删除掉某个任务后我们就可以使用内存释放函数将这个任务的任务堆栈和OS_TCB所占用的内存空间释放掉。
- 尽管UCOSIII允许在系统运行中删除任务,但是应该尽量避免这种操作,如果这个任务可能占有与其他任务共享的资源,在删除此任务之前这个被占有的资源没有被释放就有可能导致奇怪的结果。
UCOSIII任务挂起
有时候有些任务因为某些原因需要暂停运行,但是以后还要运行,因此我们就不能删除掉任务,这里我们可以使用OSTaskSuspend()函数挂起这个任务,以后再恢复运行,函数OSTaskSuspend()的原型如下:
void OSTaskSuspend (OS_TCB *p_tcb,OS_ERR *p_err)
{... //函数省略OS_TaskSuspend(p_tcb, p_err);
}
我们可以多次调用OSTaskSuspend ()函数来挂起一个任务,因此我们需要调用同样次数的OSTaskResume()函数才可以恢复被挂起的任务,这一点非常重要。
UCOSIII任务恢复
OSTaskResume()函数用来恢复被OSTaskSuspend()函数挂起的任务,OSTaskResume()函数是唯一能恢复被挂起任务的函数。函数OSTaskResume()的原型如下:
void OSTaskSuspend (OS_TCB *p_tcb,OS_ERR *p_err)
{... //函数省略OS_TaskSuspend(p_tcb, p_err);
}
如果被挂起的任务还在等待别的内核对象,比如事件标志组、信号量、互斥信号量、消息队列等,即使使用OSTaskResume()函数恢复了被挂起的任务,该任务也不一定能立即运行,该任务还是要等相应的内核对象,只有等到内核对象后才可以继续运行。
UCOSIII时钟片轮转调度
我们说过UCOSIII是支持多个任务拥有同一个优先级的,这些任务采用时间片轮转调度方法进行任务调度。在os_cfg.h文件中有个宏OS_CFG_SCHED_ROUND_ROBIN_EN,我们要想使用时间片轮转调度就需要将OS_CFG_SCHED_ROUND_ROBIN_EN定义为1,这样UCOSIII中有关时间片轮转调度的代码才会被编译,否则不能使用时间片轮转调度,这点特别重要!
OS_SchedRoundRobin()函数
时间片轮转调度器用于时间片轮转调度,为函数OS_SchedRoundRobin(),此函数由OSTimeTick或者OS_IntQTask()调用,函数在文件os_core.c中定义。
该函数在【UCOSIII】UCOSIII的任务调度和切换中已经讲解到,这里就不赘述了。
OSSchedRoundRobinCfg()函数
OSSchedRoundRobinCfg()函数用来使能或失能UCOSIII,如果我们要使用时间片轮转调度功能的话不仅要将宏OS_CFG_SCHED_ROUND_ROBIN_EN定 义 为1,还需要调用OSSchedRoundRobinCfg()函数来使能UCOSIII,OSSchedRoundRobinCfg()函数原型如下:
void OSSchedRoundRobinCfg (CPU_BOOLEAN en, //用于设置打开或关闭时间片轮转调度机制OS_TICK dflt_time_quanta, //设置默认的时间片长度,就是系统时钟节拍个数OS_ERR *p_err)
{CPU_SR_ALLOC();#ifdef OS_SAFETY_CRITICALif (p_err == (OS_ERR *)0) {OS_SAFETY_CRITICAL_EXCEPTION();return;}
#endifCPU_CRITICAL_ENTER();if (en != DEF_ENABLED) {OSSchedRoundRobinEn = DEF_DISABLED;} else {OSSchedRoundRobinEn = DEF_ENABLED;}if (dflt_time_quanta > (OS_TICK)0) {OSSchedRoundRobinDfltTimeQuanta = dflt_time_quanta;} else {OSSchedRoundRobinDfltTimeQuanta = (OS_TICK)(OSCfg_TickRate_Hz / (OS_RATE_HZ)10);}CPU_CRITICAL_EXIT();*p_err = OS_ERR_NONE;
}
对于OSSchedRoundRobinCfg()函数还有几点说明:
- 参数en:用于设置打开或关闭时间片轮转调度机制,如果为DEF_ENABLED表示打开时间片轮转调度,为DEF_DISABLED表示关闭时间片轮转调度;
- 参数dflt_time_quanta:设置默认的时间片长度,就是系统时钟节拍个数,比如我们设置系统时钟频率OSCfg_TickRate_Hz为200Hz,那么每个时钟节拍就是5ms。当我们设置dflt_time_quanta为n时,时间片长度就是(5*n)ms长,如果我们设置dflt_time_quanta为0的话,UCOSIII就会使用系统默认的时间片长度:OSCfg_TickRate_Hz / 10,比如如果OSCfg_TickRate_Hz为200,那么时间片长度为:200/10*5=100ms。
OSSchedRoundRobinYield()函数
当一个任务想放弃本次时间片,把CPU的使用权让给同优先级下的另外一个任务就可以使用OSSchedRoundRobinYield()函数,函数原型如下:
void OSSchedRoundRobinYield (OS_ERR *p_err)
{OS_RDY_LIST *p_rdy_list;OS_TCB *p_tcb;CPU_SR_ALLOC();#ifdef OS_SAFETY_CRITICALif (p_err == (OS_ERR *)0) {OS_SAFETY_CRITICAL_EXCEPTION();return;}
#endif#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0uif (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Can't call this function from an ISR */*p_err = OS_ERR_YIELD_ISR;return;}
#endifif (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* Can't yield if the scheduler is locked */*p_err = OS_ERR_SCHED_LOCKED;return;}if (OSSchedRoundRobinEn != DEF_TRUE) { /* Make sure round-robin has been enabled */*p_err = OS_ERR_ROUND_ROBIN_DISABLED;return;}CPU_CRITICAL_ENTER();p_rdy_list = &OSRdyList[OSPrioCur]; /* Can't yield if it's the only task at that priority */if (p_rdy_list->NbrEntries < (OS_OBJ_QTY)2) {CPU_CRITICAL_EXIT();*p_err = OS_ERR_ROUND_ROBIN_1;return;}OS_RdyListMoveHeadToTail(p_rdy_list); /* Move current OS_TCB to the end of the list */p_tcb = p_rdy_list->HeadPtr; /* Point to new OS_TCB at head of the list */if (p_tcb->TimeQuanta == (OS_TICK)0) { /* See if we need to use the default time slice */p_tcb->TimeQuantaCtr = OSSchedRoundRobinDfltTimeQuanta;} else {p_tcb->TimeQuantaCtr = p_tcb->TimeQuanta; /* Load time slice counter with new time */}CPU_CRITICAL_EXIT();OSSched(); /* Run new task */*p_err = OS_ERR_NONE;
}
该函数的返回错误码通常为:
错误码 | 说明 |
OS_ERR_NONE | 调用成功 |
OS_ERR_ROUND_ROBIN_1 | 当前优先级下没有其他就绪任务 |
OS_ERR_ROUND_ROBIN_DISABLED | 未使能时间片轮转调度功能 |
OS_ERR_YIELD_ISR | 在中断调用了本函数 |
【UCOSIII】UCOSIII的任务管理相关推荐
- ucosiii系统中的任务管理
前言: 多任务操作系统最重要的就是对任务进行管理,包括任务的创建,挂起,删除和调度等,因此对于ucosiii操作系统中任务管理的理解就显得尤为重要了. 分几个部分介绍: 1:任务状态 ...
- UCOSIII的任务管理
文章目录 序言 相关文件概览 os_task.c文件概览 os_core.c文件概览 部分API实际应用 任务创建和删除 任务挂起和恢复 API详解 OSTaskCreate OSTaskDel OS ...
- UCOSIII任务管理
对UCOSIII系统的任务管理包括了任务的创建.任务挂起.任务的删除以及任务的调度等. UCOSIII的启动和初始化 最先肯定是调用OSInit()初始化UCOSIII. 创建任务,一般我们在main ...
- 【UCOSIII操作系统】任务篇(1)创建任务
UCOSIII操作系统 UCOSIII操作系统--任务篇(1)创建任务 一.UCOSIII--任务 简介 二.创建任务流程 1.定义任务栈 2.定义任务控制块TCB 3.定义任务主体函数 4.创建任务 ...
- STM32F103移植uCOS-III
本文主要叙述使用STM32F103C8T6移植uCOSIII操作系统,构建3个任务,以1s和3s洲际对LED进行点亮-熄灭控制,以2s周期通过串口发送"hello uc/OS! 欢迎来到RT ...
- uCOSIII移植stm32c8t6
文章目录 一.用CubeMX建立工程 二.uCOSIII移植 一.下载uCOSIII源码 二.移植前准备工作 三.开始移植 三.实现功能 一.任务描述 二.代码 四.效果展示 总结 一.用CubeMX ...
- 【UCOSIII】一、任务创建、删除、挂起、恢复、任务管理
文章目录 0.开始之前需要知道的 1.任务创建 1.1.App.c 1.2.创建任务 1.2.1.官方main函数 1.2.2.自建main函数 1.4.任务删除 1.5.任务挂起.任务恢复 2.任务 ...
- UCOSIII 任务管理(中)
导读: 本文涉及三部分: 1. 第一部分:任务堆栈的创建和使用 2. 第二部分:任务控制块 3. 第三部分:优先级以及就绪表 希望能通过讲解对UCOSIII的任务管理有进一步的理解. 一.任务堆栈 u ...
- 2.uCOSIII任务管理
任务简介: 任务即由系统管理的程序实体,由三部分组成: 任务堆栈:本质是一个数组,不同的任务在创建前可以自己定义相关数组的大小: 任务控制块:本质上是一个结构体,用于保存任务当前的各种状态信息,其成员 ...
最新文章
- 方舟原始恐惧mod生物代码_主播在《方舟生存进化》成功打造幽灵城堡,可怕的怪物在这里横行...
- How run Powershell ISE on WIndows Server2008
- php 图片库 加星,PHP使用imagick_st类库把JPG生成GIF动画图片
- CRM呼叫中心采用轮询和SNS服务器两种方式的架构
- rrdtool zabbix mysql_MRTG、Cacti、Rrdtool、Nagios、Zabbix安装比较
- 计算机硬件系统都是看得见的,计算机组成硬件系统).doc
- 保障危险品的物流安全问题,大数据扮演了重要角色
- Jquery,ajaxFileUpload插件完成图片上传
- 如何编程实现iAMT无线功能的禁用和开启
- 微信小程序报错:invalid credential, access_token is invalid or not latest
- ucgui添加自定义汉字库
- 总结:如何使用ClearCase进行开发工作
- 算法分析之渐近分析(Asymptotic Analysis)
- DirectX游戏开发之3D角色动起来(上)
- PHP+企业微信网页授权登陆
- linux线程详解:线程概念、线程调度、线程安全、线程模型
- 想按最低税率3%缴纳个税,月薪和年终奖最高多少最为合适?
- [附源码]计算机毕业设计ssm校园二手交易平台
- 成都农科院计算机专业考纲,成都农业科技职业学院2020高职单招考试内容
- 读诗经看大河:湛湛汝水九曲湾 前坪水库保安澜