首页
Web开发
Windows程序
编程语言
数据库
移动开发
系统相关
微信
其他好文
会员
首页
>
其他好文
> 详细
uCOSIII任务管理
时间:
2016-05-18 18:09:43
阅读:
1715
评论:
0
收藏:
0
[点我收藏+]
标签:
任务简介:
任务即由系统管理的程序实体,由三部分组成:
任务堆栈:本质是一个数组,不同的任务在创建前可以自己定义相关数组的大小;
任务控制块:本质上是一个结构体,用于保存任务当前的各种状态信息,其成员只可用
uCOSIII
相关函数访问,用户不可直接访问;
任务函数:即表达任务功能的地方,通过系统调用来切换,分为
运行至完成型
(
完成后自我删除
)
和
无限循环型
(while(1))
;
任务还有一些其他属性,如优先级等等,这些在以后使用中会注意到;
任务状态:
用户角度:
休眠态:任务已经在
CPU
的
flash
中了,但
未注册而
不受
UCOSIII
管理
;
就绪态:系统为任务分配了任务控制块,并且满足运行的条件,任务已经在就绪队列中;
运行态:任务获得
CPU
的使用权,正在运行
;
等待态:任务需要等待等待某个事件或外设,进入等待队列中,此时系统就会把
CPU
使用权转交给别的任务
;
中断服务态:当发送中断,当前正在运行的任务会被挂起,
CPU
转而去执行中断服务函数,此时任务
即
中断服务态
;
操作系统角度:
有八种状态,且每种状态在操作系统中都有相关宏定义表示,而
OS_TCB
中也记录了任务当前属于哪种状态:
从图中可以看出进入每种状态的条件
(
调用什么函数
)
;
任务基本属性:
任务栈:
根据实际任务为相应任务分配合理大小的堆栈(
--------
具体方式应查一下);
uCOSIII
中建议用静态分配栈,动态会生成很多碎片;
注意堆栈溢出情况,采取堆栈溢出检测:
MMU
或
MPU
检测:配置硬件;
具有堆栈溢出检测功能
CPU
:
CPU
堆栈指针
SP
高于
/
低于某个预定值产生异常;
这个预定值
(
stk_limit,堆栈限位
)
在创建任务时会作为
OSTaskCreate()
参数传给
OS_TCB
;
此种堆栈限位值可以很接近堆栈底,任务运行时常存在一个寄存器
(
堆栈溢出检测寄存器
)
中;
上下文切换时先让此寄存器指向
NULL
;再改变
SP
的值;之后再改变此寄存器值为新任务
stk_limit;
基于软件堆栈溢出检测:任务切换函数中添加相关代码,模拟硬件实现方式;
没有硬件可靠,且
stk_limit
值离堆栈底应远一点;
系统中的
OSTaskStkChk()
函数可以用于计算任务堆栈使用量;
优先级
:
uCOSIII
优先级个数可为无穷大,默认的是
64
,由
os_cfg.h
中的
OS_CFG_PRIO_MAX
决定,值越小代表优先级越高;
最高优先级任务
(0
优先级
)
为中断服务管理任务
(OS_IntQTask())
,最低优先级为系统的空闲任务;
用户可以为用户任务设置优先级,但设置原则建议为:单调执行率调度法
(
执行频率高的任务优先级高
)
:
高优先级可以抢占低优先级,同优先级间采用轮转时间片调度;
任务相关操作:
任务创建:主要调用
OSTaskCreate()
函数,由于其参数表较为复杂,此处列出:
系统任务:
空闲任务
(OS_IdleTask()
,
os_core.c)
:
是
UCOSIII
创建的第一个任务,
亦是
必须创建的任务,此任务
在
OSInit()
内由系统创建;
任务优先级为
OS_CFG_PRIO_MAX-1
,其他任务不允许使用此优先级;
其他任务未就绪时,系统运行空闲任务;
空闲任务内有两个计数器:
OSIdleTaskCtr
:表示空闲任务活跃度;
OSStatTaskCtr
:由统计任务控制,统计程序运行
CPU
利用情况;
该任务有个
OSIdleTaskHook()
的函数,允许用户做一些额外操作,但这些操作不可使空闲任务进入等待态;
时钟节拍任务
/
时基任务
(OS_TickTask(),os_tick.c)
:
用于处理时钟节拍,是必须创建的任务;
任务优先级在
os_cfg_app.h
文件中
OS_CFG_TICK_TASK_PRIO
设置,其优先级应纸币用户系统中最重要的任务优先级低一点
(
通常设置为
1
或
2)
;
该任务等待时钟节拍
(
定时器
)
发送的信号,进入就绪态,启动任务;
在此任务内,系统会
遍历
所有等待延时或指定时间内等待某内核对象的任务
(
即
时钟节拍列表
---
时钟节拍轮
)---
关于此表在中文书
79
页,很有意思,此处不详述;
更新时钟节拍列表大部分在临界区代码完成的;
统计任务
(OS_StatTask(),os_stat.c)
:
可选任务,通过
os_cfg.h
中的
OS_CFG_STAT_TASK_EN
控制;
任务优先级为
os_cfg_app.h
文件中
OS_CFG_STST_TASK_PRIO
设置;
用于统计总
CPU
使用率
,
各任务
CPU
使用率,各任务
堆栈使用量,
CPU
利用率从
0~10000
表示从
0.00%~100.00%,
具体计算方法不细述;
使用此任务,
main
函数在调用
OSStart()
前只可创建一个用户任务,此任务中应先调用
OSStatTaskCPUUsageInit()
函数,然后才可创建其他任务;
系统会把每个任务运行统计结果存入每个任务
OS_TCB
中;
定时任务
(OS_TmrTask(),os_tmr.c)
:
是可选任务,由
os_cfg.h
中的
OS_CFG_TMR_EN
控制是否使用此任务
;
任务优先级为
os_cfg_app.h
文件中
OS_CFG_TMR_TASK_PRIO
设置,常设为中等优先级;
和时钟节拍任务使用相同的中断源,但会对时钟节拍进行分频,多少个节拍后产生一个相关信号量;
中断服务管理任务
(OS_IntQTask()
、
os_int.c)
:
是可选任务,由
os_cfg.h
中的
OS_CFG_ISR_POST_DEFERRED_EN
控制
;
当通过调度器解
/
上锁管理临界区时,
ISR
调用
Post
函数不会直接操纵等待表等,而是先放入一缓冲队列;
中断结束之后进行任务切换,此时该任务会把相关消息、信号传递给对应任务;
这种方式
(
延迟发布
)
降低了关中断时间;
任务就绪表:
就绪优先级位映射表
(OSPrioTbl[])
:
某一优先级有对应任务就绪,该表对应位会被置
1
;
此表中优先级从左到右从上到下逐渐降低,这样在某些
CPU
中查找最高优先级速度会较快;
该表相关配置和操作函数在
os_prio.h/.c
文件内;
就绪任务列表
(OSRdyList[])
:
是一个包含
OS_CFG_PRIO_MAX
项的结构体数组,每一项对应存储这个优先级任务的队列;
操作就绪任务列表的函数在
os_core.c
文件内,包括创建新任务时会入就绪队列;
初始化时该数组中相关元素相关元素都会被初始化;
任务调度:
调度方式:
是抢占式的,分为直接发布和延迟发布两种模式,最终结果一样:
直接发布:
中断服务函数中,直接向某个任务发布信号量或消息等;
中断结束后直接进入更高优先级的任务,而不先返回原来任务;
延迟发布:
中断中将要发布的信息先放入相关缓冲队列中;
退出中断后会进入最高优先级的中断服务管理任务
(OS_IntQTask())
;
该函数内根据消息队列发布相关操作,这有利于减少关中断事件;
调度点:
任务向另一任务发送信号量或消息:
一个任务调用
OS_XXX_Post()
函数时,该函数结束后即发生任务调度;
当
OS_OPT_POST_NO_SCHED
使能时则不发生任务调度;
当前任务调用
STimeDly()
或
OSTimeDlyHMSM()
:
该任务会被放入等待延时列表
(
时钟节拍轮
)
中,启动调度器;
任务执行到需要等待一个事件发生时:
通常是调用了
OS_XXX_Pend()
函数,当前任务被放入等待事件列表中;
若指定了等待的时间,还会入等待超时队列中;
任务取消等待一个事件:
任务调用
OS_XXX_PendAbort()
取消对一事件的等待,此时会从相关等待队列删除,系统重新调度;
创建任务,删除当前任务:此时亦会启动调度器;
删除内核对象:
系统通知等待该内核任务,这些任务转入就绪态。重新调度;
有任务优先级被改变时;
任务自我挂起或者解挂:
分别调用
OSTaskSuspend()
和
OSTaskResume()
函数;
退出所有嵌套中断时:
此时系统会检查这些中断是否使某些优先级任务进入就绪态;
这时候任务调度通过
OSIntExit()
函数实现;
任务放弃当前时间片
(
礼让
)
;
即调用
OSSchedRoundRobinYield()
函数;
用户手动调度:
即显式的调用
OSSched()
函数,这主要用于使能
OS_OPT_POST_NO_SCHED
时,调用
OS_XXX_Post()
函数不会产生调度时;
这样可以一次发布多个信息后进行一次任务调度,而非每次发布后执行;
轮转时间片:
多个同优先级任务时,系统使用此方式管理,用户可使能或禁止;
允许一个任务主动放弃
CPU
,即“礼让”,
用户可在运行时改变默认时间片长度
(QSTaskTimeQuantaSet()
函数
)
;
可以为每个任务制定不同长度的时间片;
几个调度函数:
OSSched()
函数:
该函数是任务级调度器,不可在
ISR_Func
内被调用;
进入此函数时中断应关闭的,退出时中断应重新开始;
扫描就绪任务表,一旦要调度,则调用任务级上下文切换函数;
OSIntExit()
函数:
此函数通常会在
ISR_Func
结束时被调用来调度任务;
当任务调度器未上锁,且是最后一层嵌套的中断中,该函数执行调度;
查询任务就绪表,调用中断级上下文切换函数;
OS_SshedRoundRobin()
函数:
用于进行同优先级下的时间片轮转调度;
直接发布时由
OSTimeTick()
函数调用,延迟发布时由
OS_IntQTask()
函数调用;
上下文切换:
概述:
主要作用是将当前任务现场保存到任务堆栈中;
不同
CPU
寄存器数不同,故这部分代码移植时应根据实际
CPU
修改,具体在
os_cpu.h
、
os_cpu_c.c
、
os_cpu_a.asm
文件中;
寄存器中的
PC
和状态寄存器
(SR)
先入栈,这是硬件自动完成的,其他由软件入栈,任务堆栈指针不入栈,而直接存入
OS_TCB
中;
具体的两个切换函数都是在
os_cpu_a.asm
中用汇编写的;
任务级
OSCtxSw()
函数:
先将当前任务相关寄存器存入任务堆栈,入栈顺序一般和中断时一样;
将当前堆栈指针值存入当前任务
OS_TCB
中;
将新任务
OS_TCB
中的任务堆栈指针值载入堆栈指针寄存器中;
从新任务堆栈中依次弹栈,恢复现场;
中断级
OSIntCtxSw()
函数:
与任务级不同,中断级在切换前默认发生中断时
CPU
寄存器已被存入相关堆栈内;
所以其只完成任务级的后两步;
任务挂起表:
功能概述:
当前任务等待某一内核对象或者消息时,用来记录的地方;
其本质是一个个链表,每个内核对象或者消息对应一个链表,表中高优先级任务放在前面;
链表的表头中记录等待对象的结构体被称为
OS_PEND_OBJ
,有以下元素:
Type
:表明该表中元素等待的内核对象的类型,四个字节的
ANSII
码表示;
NamePtr
:指向该种内核对象的一个确切实体的名字;
任务挂起表内元素不是
OS_TCB
,而是
OS_PEND_DATA
结构体,位于任务自己的堆栈内;
该结构体内指针可以指向自己的
OS_TCB
,而
OS_TCB
亦可指向自己的
OS_PEND_DATA
;
uCOSIII任务管理
标签:
原文地址:http://blog.csdn.net/chuchaoqundevin/article/details/51445132
踩
(
0
)
赞
(
0
)
举报
评论
一句话评论(
0
)
登录后才能评论!
分享档案
更多>
2021年07月29日 (22)
2021年07月28日 (40)
2021年07月27日 (32)
2021年07月26日 (79)
2021年07月23日 (29)
2021年07月22日 (30)
2021年07月21日 (42)
2021年07月20日 (16)
2021年07月19日 (90)
2021年07月16日 (35)
周排行
更多
分布式事务
2021-07-29
OpenStack云平台命令行登录账户
2021-07-29
getLastRowNum()与getLastCellNum()/getPhysicalNumberOfRows()与getPhysicalNumberOfCells()
2021-07-29
【K8s概念】CSI 卷克隆
2021-07-29
vue3.0使用ant-design-vue进行按需加载原来这么简单
2021-07-29
stack栈
2021-07-29
抽奖动画 - 大转盘抽奖
2021-07-29
PPT写作技巧
2021-07-29
003-核心技术-IO模型-NIO-基于NIO群聊示例
2021-07-29
Bootstrap组件2
2021-07-29
友情链接
兰亭集智
国之画
百度统计
站长统计
阿里云
chrome插件
新版天听网
关于我们
-
联系我们
-
留言反馈
© 2014
mamicode.com
版权所有 联系我们:gaon5@hotmail.com
迷上了代码!