UCOSIII 系统内部任务
在 UCOSII 中有两个系统任务:统计任务和空闲任务,在但是UCOSIII中系统内部任务扩展到了5 个 。
空闲任务、时钟节拍任务、统计任务、定时任务、中断服务管理任务、钩子函数 。
1.空闲任务:
OS_IdleTask(),在os_core.c 文件中定义。
调用 OS_Init()初始化UCOS 的时候就会被创建。在 OS_Init() 中 调 用 了 函 数OS_IdleTaskInit()
void OS_IdleTaskInit (OS_ERR *p_err)
{
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
OSIdleTaskCtr = (OS_IDLE_CTR)0; (1)
OSTaskCreate((OS_TCB * )&OSIdleTaskTCB,
(CPU_CHAR * )((void *)"uC/OS-III Idle Task"),
(OS_TASK_PTR )OS_IdleTask,
(void * )0,
(OS_PRIO )(OS_CFG_PRIO_MAX - 1u),
(CPU_STK * )OSCfg_IdleTaskStkBasePtr,
(CPU_STK_SIZE )OSCfg_IdleTaskStkLimit,
(CPU_STK_SIZE )OSCfg_IdleTaskStkSize,
(OS_MSG_QTY )0u,
(OS_TICK )0u,
(void * )0,
(OS_OPT )(OS_OPT_TASK_STK_CHK | \
OS_OPT_TASK_STK_CLR | OS_OPT_TASK_NO_TLS),
(OS_ERR * )p_err);
}
任 务 优 先 级 为 OS_CFG_PRIO_MAX – 1,OS_CFG_PRIO_MAX 是一个宏,在文件 os_cfg.h 中定义,OS_CFG_PRIO_MAX 定义了 UCOSIII可用的任务数。
空闲任务堆栈大小为 OSCfg_IdleTaskStkSize , OSCfg_IdleTaskStkSize 也是一个宏,在 os_cfg_app.c 文件中定义,默认为 128 ,则空闲任务堆栈默认为 128*4=512 字节。
空闲任务的任务函数为任务函数为 OS_IdleTask() , OS_IdleTask() 函数代码如下:
void OS_IdleTask (void *p_arg)
{
CPU_SR_ALLOC();
p_arg = p_arg;
while (DEF_ON) {
CPU_CRITICAL_ENTER(); (1)
OSIdleTaskCtr++; (2)
#if OS_CFG_STAT_TASK_EN > 0u (3)
OSStatTaskCtr++; (4)
#endif
CPU_CRITICAL_EXIT(); (5)
OSIdleTaskHook(); (6)
}
}
(1) 和 (5) 、临界段代码保护
(2) 、 OSIdleTaskCtr 加一,每进入一次空闲任务, OSIdleTaskCtr 就加一。我们可以通过查看 OSIdleTaskCtr 变量的递增速度来判断 CPU 执行应用任务的繁忙程度,如果递增的快的话说明应用任务花费时间少,很快就执行完了。
(3) 、宏 OS_CFG_STAT_TASK_EN 大于 0 说明开启了统计任务。
(4) 、 OSStatTaskCtr 默认也是一个 32 位的无符号整形变量,在文件 os.h 中定义。这里将 OSStatTaskCtr 加一,统计任务中用到 OSStatTaskCtr ,用来统计 CPU 的使用率。
(6) 、 OSIdleTaskHook() 叫做钩子函数,我们可以在钩子函数中干一些其他的事情。
2.时钟节拍任务
OS_Ticktask(),在 OS_Init()中调用了一个函数OS_TickTaskInit(),函数代码如下:
{
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
OSTickCtr = (OS_TICK)0u;
OSTickTaskTimeMax = (CPU_TS)0u;
OS_TickListInit();
if (OSCfg_TickTaskStkBasePtr == (CPU_STK *)0) {
*p_err = OS_ERR_TICK_STK_INVALID;
return;
}
if (OSCfg_TickTaskStkSize < OSCfg_StkSizeMin) {
*p_err = OS_ERR_TICK_STK_SIZE_INVALID;
return;
}
if (OSCfg_TickTaskPrio >= (OS_CFG_PRIO_MAX - 1u)) {
*p_err = OS_ERR_TICK_PRIO_INVALID;
return;
}
OSTaskCreate((OS_TCB * )&OSTickTaskTCB,
(CPU_CHAR* )((void *)"uC/OS-III Tick Task"),
(OS_TASK_PTR )OS_TickTask,
(void* )0,
(OS_PRIO )OSCfg_TickTaskPrio,
(CPU_STK* )OSCfg_TickTaskStkBasePtr,
(CPU_STK_SIZE )OSCfg_TickTaskStkLimit,
(CPU_STK_SIZE )OSCfg_TickTaskStkSize,
(OS_MSG_QTY )0u,
(OS_TICK )0u,
(void* )0,
(OS_OPT )(OS_OPT_TASK_STK_CHK |\
OS_OPT_TASK_STK_CLR | OS_OPT_TASK_NO_TLS),
(OS_ERR *)p_err);
}
时钟节拍任务的优先级尽可能的高一点 , 时钟节拍任务的作用是跟踪正在延时的任务,以及在指定时间内等待某个内核对象的任务, OS_TickTask() 任务函数代码如下:
{
OS_ERR err;
CPU_TS ts;
p_arg = p_arg;
while (DEF_ON) {
(void)OSTaskSemPend((OS_TICK )0, (1)
(OS_OPT )OS_OPT_PEND_BLOCKING,
(CPU_TS * )&ts,
(OS_ERR * )&err);
if (err == OS_ERR_NONE) {
if (OSRunning == OS_STATE_OS_RUNNING) {
OS_TickListUpdate(); (2)
}
}
}
}
(1) 、请求信号量, OSTaskSemPend() 是请求任务内建信号量的,信号量会在 OSTimeTick() 中 POST ,这里的信号量是用来做任务同步的 。 OSTimeTick() 会在滴答定时器中断服务函数中调用。
(2) 、信号量请求成功的话就调用函数 OS_TickListUpdate() 函数。
OSTickCtr 组 成 , 表 OSCfg_TickWheel 是 一 个 数 组 , 数 组 元 素 个 数 由 宏OS_CFG_TICK_WHEEL_SIZE 定义,宏 OS_CFG_TICK_WHEEL_SIZE 在 os_cfg_app.h 中定义了。表 OSCfg_TickWheel 中的元素为 os_tick_spoke 类型的, os_tick_spoke 是一个结构体,结构体定义如下:
struct os_tick_spoke {
OS_TCB *FirstPtr;
OS_OBJ_QTY NbrEntries;
OS_OBJ_QTY NbrEntriesMax;
};
FirstPtr: 指针变量,在表头上并属于该表。
NbrEntries: 表示在该表项上等待的任务的数目。
NbrEntriesMax: 表示在该表项上等待的任务的最大数目。
在使用时钟节拍列表时需要先初始化时钟节拍列表,在 OS_TickTaskInit()函数中会调用OS_TickListInit 来初始化时钟节拍列表 。
3.统计任务
OS_CFG_STAT_TASK_EN 置 1 ,宏 OS_CFG_STAT_TASK_EN 在 os_cfg.h 文件中有定义。
OS_StatTaskInit() 函 数 用 来 创 建 统 计 任 务 , 统 计 任 务 的 优 先 级 通 过 宏OS_CFG_STAT_TASK_PRIO 设 置 。
如果要使用统计任务的话就需要在 main()函数创建的第一个也是唯一一个应用任务中调用OSStatTaskCPUUsageInit()函数。
OSStatTaskCPUUsageInit(&err); // 统计任务
#endif
创建其他任务只能在
OSStatTaskCPUUsageInit() 函数之后。 CPU 的总的使用率会保存在变量 OSStatTaskCPUUsage 中,我们可以通过读取这个值来获取 CPU 的使用率。
UCOSIII 提供软件定时器功能,定时任务是可选的,将宏 OS_CFG_TMR_EN 设置为 1 就会使能定时任务,在 OSInit() 中将会调用函数 OS_TmrInit() 来创建定时任务。定时任务的优先级通过宏 OS_CFG_TMR_TASK_PRIO 定义。
当 ISR( 中断服务函数 ) 调用 UCOSIII 提供的“ post ”函数时,要发送的数据和发送的目的地都会存入一个特别的缓冲队列中,当所有嵌套的 ISR 都执行完成以后 UCOSIII 会做任务切换,运行中断服务管理任务,该任务会把缓存队列中存放的信息重发给相应的任务。这样做的好处就是可以减少中断关闭的时间,否则,在 ISR 中还需要把任务从等待列表中删除,并把任务放入就绪表,以及做一些其他的耗时操作。
UCOSIII 系统内部任务相关推荐
- UCOSIII系统内部任务
空闲任务 .这个空闲任务OS_IdleTask()永远设为最低优先级,即OS_LOWEST_PRI0.空闲任务OS_IdleTask()什么也不做,只是在不停地给一个32位的名叫OSIdleTaskC ...
- 图章制作软件测试自学,SecSeal安全电子印章系统内部测试大纲.doc
SecSeal安全电子印章系统内部测试大纲 SecSeal安全电子印章系统 内部测试大纲 2004年3月 测试内容 测试人员: 测试日期: 测试软件版本: 印章管理系统: 盖章系统: 公文阅读器: 安 ...
- 【实时语音转文本】PC端实时语音转文本(麦克风外音系统内部音源)
语音转文字这个功能可以应用在视频动态字幕,语音快速输入,实时记录通话内容,高级应用可以在人工智能,语音识别,智能助手方面,还需要一点机器学习可以做出一些好玩的东西,比如PC端AI助理,类似移动端的 & ...
- Win10:解决Win10的录音设备只能录制系统内部声音无法录制麦克风声音的问题
Win10:解决Win10的录音设备只能录制系统内部声音无法录制麦克风声音的问题 目录 解决问题 解决思路 解决问题 Win10的录音设备只能录制系统内部声音无法录制麦克风声音的 解决思路 将麦克风设 ...
- 安卓微信浏览器唤起系统内部浏览器
安卓微信浏览器唤起系统内部浏览器 最近因为公司项目需求,需要做一个功能.使用微信浏览器打开高德地图导航,经试验,高德web端没有导航功能,其实现原理是调起高德APP来实现导航的操作.然后把代码写进微 ...
- android使用Alsa Aloop录制系统内部声音
alsa aloop是alsa提供的内部loopback功能,可以用来实现录制系统内部声音,在没有硬件支持loopback功能时可以采用这种软件loopback的实现来代替. alsa aloop实现 ...
- Linux学习笔记之——Linux系统内部相关介绍
Linux学习笔记之--Linux系统内部相关介绍 摘要:主要记录一些比较有用的能够帮助理解和使用Linux的知识.比如一些相关概念.没兴趣的看看就好.知道有这么个东西.注意事项.和一些常用目录的作用 ...
- 【软件】windows录音,如何录制系统内部声音(几乎找遍全网的所有方法)
1. 引言 最近因为一些原因,需要录制一些远程会议的音频,便于回溯记录.因此花了一些时间,去找了一下有什么软件可以录制系统内部的声音. 不单单是麦克风收录的声音,还包括系统内部的声音,就是我们耳机里能 ...
- PPC系统内部和注册表的一些解释与修改
关于系统内部和注册表的一些解释与修改 1.来电铃声 铃声放在windows下的rings目录下面,或者在储存卡里建立一个My Documents(注意大小写)把mp3铃声放里面就好了来电铃声支持的格式 ...
最新文章
- memcpy, strcpy, strncpy的区别和用法
- Visual Studio Code常用快捷键
- opengl代码实例_OpenGL-打开一个窗口
- 常见设备分辨率大小,响应式必备啊
- Beaglebone bootloader杂谈
- 【原题】【noip 2003 T2】【动态规划】加分二叉树
- redis存储数据类型_Redis与Memcahe的区别最全整理
- HAProxy用法详解 全网最详细中文文档
- java发送html附件_Java发送邮件(图片、附件、HTML)
- JSK-391 公约公倍【入门】
- 协同过滤工具源码下载
- 如何提高Solidworks运行速度
- Latex 1: 解决latex中遇到一个常见错误:Improper alphabetic constant.
- html页面在ie上出现404怎么解决,ie浏览器网页上有错误解决方法详解
- 写到最前面的话——研究生毕业论文致谢
- 雷军手机使用时长曝光!一天刷抖音、微博、微信,办公仅34分钟
- 数据结构之图:邻接矩阵和邻接表、深度优先遍历和广度优先遍历
- 洛谷 P3354 [IOI2005]Riv 河流【树形dp】
- 三国杀开源系列之四-工程目录分析107@365
- JSOI2014骑士游戏(最短路)