[首页]
[文章]
[教程]
首页
Web开发
Windows开发
编程语言
数据库技术
移动平台
系统服务
微信
设计
布布扣
其他
数据分析
首页
>
其他
> 详细
uCOSIII任务管理
时间:
2016-05-18 18:08:30
阅读:
267
评论:
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年09月23日 (328)
2021年09月24日 (313)
2021年09月17日 (191)
2021年09月15日 (369)
2021年09月16日 (411)
2021年09月13日 (439)
2021年09月11日 (398)
2021年09月12日 (393)
2021年09月10日 (160)
2021年09月08日 (222)
最新文章
更多>
2021/09/28 scripts
2022-05-27
vue自定义全局指令v-emoji限制input输入表情和特殊字符
2022-05-27
9.26学习总结
2022-05-27
vim操作
2022-05-27
深入理解计算机基础 第三章
2022-05-27
C++ string 作为形参与引用传递(转)
2022-05-27
python 加解密
2022-05-27
JavaScript-对象数组里根据id获取name,对象可能有children属性
2022-05-27
SQL语句——保持现有内容在后面增加内容
2022-05-27
virsh命令文档
2022-05-27
教程昨日排行
更多>
1.
list.reverse()
2.
Django Admin 管理工具
3.
AppML 案例模型
4.
HTML 标签列表(功能排序)
5.
HTML 颜色名
6.
HTML 语言代码
7.
jQuery 事件
8.
jEasyUI 创建分割按钮
9.
jEasyUI 创建复杂布局
10.
jEasyUI 创建简单窗口
友情链接
汇智网
PHP教程
插件网
关于我们
-
联系我们
-
留言反馈
- 联系我们:wmxa8@hotmail.com
© 2014
bubuko.com
版权所有
打开技术之扣,分享程序人生!