关闭
搜索
搜索
本版
帖子
用户
热搜:
程序员
简洁模式
高级模式
用户组: 游客
消息
提醒
新听众
我关注的
帖子
道具
勋章
任务
设置
退出
请
登录
后使用快捷导航
没有帐号?
立即注册
设为首页
收藏本站
开启辅助访问
切换到窄版
登录
or
立即注册
快捷导航
搜索
首页
论坛
BBS
MCU单片机技术
程序员交流
uCos的多任务实现
[复制链接]
作者:
襄垣战队收人
版块:
›
灌水·股票·程序员大本营·工作之余需要点阳光·我们不只是工程师
›
IT业界资讯
发布时间:
2018-11-2 22:05:42
1513
0
返回列表
襄垣战队收人
当前离线
新手上路
新手上路, 积分 36, 距离下一级还需 14 积分
新手上路
新手上路, 积分 36, 距离下一级还需 14 积分
积分
36
发消息
楼主
电梯直达
襄垣战队收人
发表于 2018-11-2 22:05:42
|
只看该作者
|
倒序浏览
|
阅读模式
作为操作系统(OS),最基本的一项服务就是提供多线程,在实时操作系统uCos里,多线程被称为多任务(Task)。多任务并不是CPU能真正同时运行多个程序,实际是靠CPU在多个任务之间转换切换实现的,CPU轮番的服务于一系列的任务,这样CPU在宏观上好像在同时执行多个任务,实际在微观上CPU绝对是“单任务”的。这里要注意区别多线程和多核,如果系统里是有多个CPU,则可以实现真正的多线程了。
按照上面的思路,多任务的实现,就是要实现CPU在不同的任务之间切换。按照uCos作者的话说:“就是不断的保存,恢复CPU的那些寄存器”。
我们知道uCos的多任务(这里以两个任务为例)的程序模型如下:
使用uCos,程序将在这两个任务之间轮换,这两个while(1)里的程序都可以得到执行。
我们知道,在裸机编程里,如果出现while(1)这样的语句,那么程序将永远在这个循环里执行(当然是要程序主动调用break除外),他是不会放弃CPU的,那为什么加了操作系统后,程序能在这两个while(1)之间轮换?
操作系统都需要使用“时钟节拍”技术来实现对任务的监控,并能主动调度和切换任务的执行。
uCos也同样是使用“时钟节拍”来实现任务的监管的,以STM32单片机为例,一般用SysTick这个系统时钟定时器来实现,比如我们设置这个定时器10ms的定时间隔,那么每隔10ms都会调用下面的中断服务(所以移植的时候,需要实现这个函数):
这个函数很简单,他是uCos的内核函数,主要是给中断嵌套计数器OSIntNesting加一,因为uCos内核需要实时的判断程序的当前执行是不是在中断里,要知道,大部分的处理器是可以中断嵌套的,这里我们先不管判断程序是不是在中断里有什么用,后面马上会说到。
然后开始执行OSTimeTick(),这个函数我们只分析关键代码,也就是跟任务管理有关的代码:
在这个函数里,出现了一个全局变量OSTCBList,这个变量是uCos内核里任务控制块(TCB)链表的表头指针,问题又来了,TCB是什么,TCB链表又是什么?
原来uCos的每个任务都需要有一个TCB来管理,这个TCB记录了该任务的所有信息,同时uCos用链表来管理所有的这些TCB,TCB的结构如下:
这结构体稍微有点大,这里我们先知需要关心OSTCBDly这个成员,这个成员记录该任务的延时值,当我们调用uCos的系统函数OSTimeDly(),OSQPend()等这些阻塞类型的函数时,该任务的TCB成员OSTCBDly就会被赋予相应值。
我们继续分析OSTimeTick(),这个函数,在这个函数里,主要是给每个TCB的OSTCBDly的计数值减一,如果OSTCBDly为零了,则在任务就绪表里标记该任务,这里又引出了一问题,什么是就绪表,uCos的就绪表的实现用了一个比较巧妙的算法,这里先不仔细去分析,只有知道就绪表里记录了当前系统中,哪些任务是处于就绪态,也就是可被CPU执行的状态。
好,到这里OSTimeTick()分析完了,他完成了对每个任务的延时值减一操作,并更新了就绪表。
下面开始执行OSIntExit(),这个函数是个很关键的函数,她将实现任务的上下文切换。
OSIntExit函数的源码如下:
从上面的源码和代码注释可以总结出该函数完成的功能为:找出就绪表里的最高优先级任务,并执行OSIntCtxSw函数来进行任务切换。这里要注意,虽然执行了任务切换,但不会立刻进行上下文的切换,这个实现过程跟CPU的硬件有关,在STM32中,上下文的切换是用的“悬起中断”,该中断只有当CPU的所有中断完成了,也就是退出了所有的中断嵌套后,才会执行。
OSIntCtxSw函数是移植uCos的一个非常关键的函数,他负责恢复运行任务的上次中断现场,这个函数跟CPU体系有紧密的联系,这里先不仔细分析。
到这里我们基本可以看到uCos利用系统时钟滴答实现多任务的大概流程如下:
uCos的任务切换过程就分析跟踪完了,这里要注意几点,任务的切换并不只会发生在系统时钟滴答的中断服务里,调用发送信号量,发送消息等这些系统函数时也会引起任务切换,但大致的原理都差不多,这里我们只对程序的原理和框架做了说明,实际还是有些细节需要处理的。
长按识别二维码
关注
嵌入式ARM
长按识别二维码
关注
21ic官方微信
长按识别二维码
关注
电源Fan
长按识别二维码
关注
德州仪器公开课
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有帐号?
立即注册
收藏
0
相关帖子
•
长文|花了两天时间整理了STM32中的一些C语言知识点
•
深入理解高性能网络开发路上的绊脚石-同步阻塞网络IO
•
Linux上TCP的几个内核参数调优
•
Linux运维入门教程07-01-Linux网络原理及基础设置
•
Linux内核继续打造WWAN子系统发展通用驱动并加强扩展能力
•
干货|深度剖析C语言的main函数
•
红帽linux[基础命令]特殊变量列表
•
如何在内核中操作某个文件?
•
利用BATS测试Bash脚本和库|Linux中国
•
《Linux内核编码风格》官方手册最新中译本
回复
使用道具
举报
返回列表
高级模式
B
Color
Image
Link
Quote
Code
表情
@朋友
您需要登录后才可以回帖
登录
|
立即注册
本版积分规则
发表回复
回帖后跳转到最后一页
浏览过的版块
linux
生活交流*灌水区*工程师滋润生活*
招聘&找工作
ARM
硬件综合
单片机入门及综合应用
快速回复
返回顶部
返回列表