ucos ii是怎么实现多任务运行的?很通俗易懂的描述

2023-05-16

问题:
ucos上建立一个任务,格式如上图,它是一个死循环,但如果我建立了五个任务,并且五个任务里面没有延时,就只是像无操作系统那样写法,用死循环让它们一直跑,那这五个任务可以实现并行吗。
回答:
作者:不繆
链接:https://www.zhihu.com/question/55265639/answer/143727267
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

最近有用到ucosiii,跟ucosii还是有点区别,但是本质还是没有多大变化。一般跑ucos的都是单片机。如果是Soc基本上都跑linux了。这里我们要说一下基本知识,就是CPU的线程问题,像我电脑的CPU是i7的,四核八线程,所以他可以同时跑个8任务。而单片机只是单核单线程,所以每次只能跑一个任务,如果是裸机,那就是main()函数里面面的while(1)。那中断和定时器也是一样的不是意味着他可以同时执行中断任务和mian函数的任务,而是触发中断之后,暂停main函数中的任务,把当前的任务信息保存起来,然后去执行中断函数里面的任务,执行完了再恢复mian函数,从上次中断的地方继续执行。如果中断任务执行的时候,又有其他中断且是优先级比当前执行中断高的,那个这个中断会暂停,把当前任务状态保存起来,去执行那个优先级更高的中断,执行完成后再执行这个中断,然后再继续执行main函数。
所以,有人就想了这样一个办法,用定时器计时进行计数,然后把任务的总周期定下来,然后把时间分成好几份,分配给不同的函数,此时这每一个函数执行不同的功能,相同于执行不同的任务。这种做法应该叫状态机,不能叫操作系统。匿名四轴飞行器最早期的代码就是这样子写的,不过他全部代码放在中断里面执行,这样就不用自己写任务切换函数了,但是这个方法不是最好的方法,会有一些问题,中断函数应该不能写过于大的任务。
所以,现在的ucos之类的操作系统都采用了分时复用的方法,就是在不同的时间执行不同的任务函数。这个时钟由滴答定时器产生,一般为5ms中断一次,每次中断,都会去检查任务就绪表,如果有高优先级任务就绪了,就去执行他,然后把当前执行的任务保存在任务堆栈中,所以每个任务创建之前,都要先初始化一片内存用于存放当前任务执行的状态,如下面代码所示:
#define NRF24L01_STK_SIZE  128
OS_TCB NRF24L01TCB;
CPU_STK NRF24L01_STK[NRF24L01_STK_SIZE];
OSTaskCreate ((OS_TCB        *)&NRF24L01TCB,
	     (CPU_CHAR      *)"NRF24L01",
	     (OS_TASK_PTR    )NRF24L01_task,
	     (void          *)0,
	     (OS_PRIO        )NRF24L01_TASK_PRIO,
	     (CPU_STK       *)NRF24L01_STK,
	     (CPU_STK_SIZE   )NRF24L01_STK_SIZE/10,
	     (CPU_STK_SIZE   )NRF24L01_STK_SIZE,
	     (OS_MSG_QTY     )0,
	     (OS_TICK        )0,
	     (void          *)0,
	     (OS_OPT         )OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR,
	     (OS_ERR        *)&err);
这就是创建一个任务的函数,比ucosii多了好多参数。题主问这个问题是在奇怪为什么每个任务都是while(1),那还么去执行其他任务吗?其实关键就在这个滴答定时器的中断上面,因为只要进了中断,就跳出当前的while(1),然后我们就可以把当前的程序指针(PC寄存器)指向别的地方。其实每一个函数都存放在不同的地方,只要知道我下一个要执行的任务函数的首地址,那我只要把指针指过去就好了。可以看到上面初始中有一个:
(OS_TASK_PTR    )NRF24L01_task,
这个就是任务函数的地址。这个地址会保存在一个数据结构里面,这个叫什么我也不记得了,任务控制块?
所以你只要知道,单片机每次只能执行一个任务,多任务是分时复用来实现的,即ucos采用的方法。每个任务函数都是一个地址指针,要运行哪一个指令,就看PC寄存器指到哪。所以这就是为么要用滴答定时器的中断,因为我们可以在中断里面改变PC寄存器里面的这个地址,从而去到别的任务中,然后我们恢复那个任务上一次的执行状态,这就是为什么要开一个任务堆栈,就是为了存放任务执行的状态,包括各种变量的值。
<img src="https://pic4.zhimg.com/v2-2e0c1e0bf2d8427cbdd02fd74f0e063b_b.png" data-rawwidth="527" data-rawheight="540" class="origin_image zh-lightbox-thumb" width="527" data-original="https://pic4.zhimg.com/v2-2e0c1e0bf2d8427cbdd02fd74f0e063b_r.png">这个是ucosiii的任务状态转换图,只要你在while(1)任务函数里面调用了这些API,都会触发任务调度,例好OSTimeDlyHMSM()系统级延时函数,到了时间之后又会回到上次执行的地方开始执行。这里要说一点的就是,如果高优先级的任务一直不进行任务调度,那么该任务就会一直占用CPU,低优先级任务将一直无法执行。而最低优先级的任务即使没有进行任务调度,也会进行任务切换,因为滴答定时器每5ms进行一次中断,这个时候就会对任务就绪表进行扫描,如果有高优先级的任务进入了就绪状态,那么就会自动进行任务切换。所以后面就会涉及到一些加锁的行为,为了防止在运行的时候,时序被打断,下次回来就无法执行的情况。 这个是ucosiii的任务状态转换图,只要你在while(1)任务函数里面调用了这些API,都会触发任务调度,例好OSTimeDlyHMSM()系统级延时函数,到了时间之后又会回到上次执行的地方开始执行。这里要说一点的就是,如果高优先级的任务一直不进行任务调度,那么该任务就会一直占用CPU,低优先级任务将一直无法执行。而最低优先级的任务即使没有进行任务调度,也会进行任务切换,因为滴答定时器每5ms进行一次中断,这个时候就会对任务就绪表进行扫描,如果有高优先级的任务进入了就绪状态,那么就会自动进行任务切换。所以后面就会涉及到一些加锁的行为,为了防止在运行的时候,时序被打断,下次回来就无法执行的情况。
有错的地方请指各位知友指正。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ucos ii是怎么实现多任务运行的?很通俗易懂的描述 的相关文章

  • PHP获取文件的修改时间、访问时间和inode 修改时间

    filemtime string filename 返回文件上次被修改的时间 xff0c 出错时返回 FALSE 时间以 Unix 时间戳的方式返回 xff0c 可用于 date 例如 xff1a a 61 filemtime 34 log
  • PHP设计模式之单例模式

    最近开始学习设计模式 xff0c 由于一开始没有系统的学习 xff0c 导致学的知识七零八落的 xff0c 得好好整理一下了 单例模式 xff08 职责模式 xff09 xff1a 简单的说 xff0c 一个对象 xff08 在学习设计模式
  • 创业资金来源

    创业资金的获得一般有以下几个途径 xff1a 一 自有资金 这个主要是自身的存款 xff0c 一般工作几年的人或多或少都有点存款 xff0c 这一部分的钱是自己创业的基本基金 二 股权融资 股权融资 xff0c 是指创业者或中小企业让出企业
  • Cannot modify header information解决办法

    如果在执行php程序时看到这条警告 Warning Cannot modify header information headers already sent by 可以尝试以下几种解决方法 Use exit statement 用exit
  • 中国距离VR市场成熟还要多久?

    VR xff08 Virtual Reality的缩写 xff0c 中文翻译 虚拟现实 xff09 概念早在80年代初就被提出来的 xff0c 其具体是指借助计算机及最新传感器技术创造的一种崭新的人机交互手段 中国VR产业仍在摸索阶段 亟缺
  • URL重写规则

    今天给大家详细讲解一下RewriteCond指令与RewriteRule 指令的格式 Rewirte主要的功能就是实现URL的跳转和隐藏真实地址 xff0c 基于Perl语言的正则表达式规范 帮助我们实现拟静态 xff0c 拟目录 xff0
  • 二值信号量与互斥锁区别

    互斥锁和二值信号量在使用上非常相似 xff0c 但是互斥锁解决了优先级翻转的问题 以军长 师长 团长为案例 xff0c 讲解mutex与signal区别 xff0c 以下是时序图 参考 xff1a https www cnblogs com
  • redisson-spring-boot-starter

    redisson spring boot starter spring boot 配置 spring redis redisson config classpath redisson beta yml 或者 spring redis red
  • URL中"#" "?" "&"号的作用

    10年9月 xff0c twitter改版 一个显著变化 xff0c 就是URL加入了 符号 比如 xff0c 改版前的用户主页网址为http twitter com username 改版后 xff0c 就变成了http twitter
  • STAR法则的简历应用

    STAR法则 即为Situation Task Action Result的缩写 xff0c 具体含义是 Situation 事情是在什么情况下发生 Task 你是如何明确你的任务的 Action 针对这样的情况分析 xff0c 你采用了什
  • BI商业智能

    关键字 xff1a 商务智能 xff0c 数据仓库 xff0c ETL BI xff08 Business Intelligence即商务智能 xff09 xff0c 百度百科用的解释是 xff0c 它是一套完整的解决方案 xff0c 用来
  • 遗传算法 一个模拟自然进化过程的启发式搜索算法

    关键字 xff1a 遗传算法 遗传算法 xff08 Genetic Algorithm xff09 是一种模拟自然界 自然选择 和 自然遗传 的启发式搜索算法 xff0c 通过模拟自然进化过程搜索最优解的方法 直到1989年 xff0c 实
  • PHP四大基本排序算法

    冒泡排序 思路分析 xff1a 在要排序的一组数中 xff0c 对当前还未排好的序列 xff0c 从前往后对相邻的两个数依次进行比较和调整 xff0c 让较大的数往下沉 xff0c 较小的往上冒 即 xff0c 每当两相邻的数比较后发现它们
  • 设置centos的YUM源为国内阿里云源

    阿里云Linux安装镜像源地址 xff1a http mirrors aliyun com http mirrors aliyun com repo CentOS系统更换软件安装源 第一步 xff1a 备份你的原镜像文件 xff0c 以免出
  • PHP八大设计模式

    PHP命名空间 可以更好地组织代码 xff0c 与Java中的包类似 Test1 php span class php span class hljs preprocessor lt php span span class hljs key
  • GitLab使用手册

    安装Git 安装环境 xff1a windows下载地址 xff1a git官方网站安装包 xff1a 64位安装过程 xff1a 傻瓜式安装至此安装完毕 生成私钥和公钥 ssh span class hljs attribute keyg
  • echarts使用心得

    前言 第一次参加工作 xff0c 公司使用图表很频繁 xff0c 我之前会highcharts xff0c 但是公司基本上都是使用的echarts xff0c 于是自己开始琢磨echarts xff0c 使用起来却颇费了一番工夫 所以就把使
  • JQuery插件之Masked Input

    Masked Input是一个字符输入格式化的jQuery插件 它可让你轻松的实现对各种数据的输入进行格式限制 xff0c 如日期 电话等 Masked Input在IE Firefox Safari和Chrome通过测试 Mask会自动为
  • 关于jQuery的九大使用误区

    jQuery是如此容易使用 xff0c 以至于我们有时候忘记了CSS的存在 我们在使用CSS时 xff0c 几乎不去考虑性能 xff0c 因为它已经是快得不值得再去做什么优化上 的努力 但现实世界中 xff0c JQuery会导致令开发人员
  • echarts主题属性设置

    theme 61 span class hljs comment 全图默认背景 span backgroundColor span class hljs string 39 rgba 0 0 0 0 39 span span class h

随机推荐

  • java keytool证书工具使用小结

    Keytool 是一个Java数据证书的管理工具 Keytool将密钥 xff08 key xff09 和证书 xff08 certificates xff09 存在一个称为keystore的文件中在keystore里 xff0c 包含两种
  • Another app is currently holding the yum lock; waiting for it to exit...

    Another app span class hljs keyword is span currently holding span class hljs keyword the span yum lock waiting span cla
  • Javascript网页打印大全

    目录 普通打印 xff08 整页打 xff09 打印去掉 添加页眉页脚 使用外部控件 方法实现多功能打印 打印背景 普通打印 xff08 整页打 xff09 span class hljs built in window span span
  • centos6.5启动nginx报错

    问题 xff1a nginx emerg socket 80 failed 97 Address family not supported by protocol 解决方案 vim etc nginx conf d default conf
  • echarts和highchart的区别

    echarts 先大体了解一下echarts的历史 xff1a echarts是百度公司前端开发的一个图表库 支持柱状图 饼状图 k线图 map图 热导向图 折线图 主要采用canvas画图 highchart highcharts是国外的
  • vi/vim常用配置和快捷键

    快捷键 命令名功能描述gg将光标移动到文档头部G将光标移动到文档尾部nyy全选文本 xff08 没有全选命令的 xff0c 我的做法就是复制n行 xff0c 只要n大于文本的行数就行 xff09 如何复制文本内容到另一个文件中 使用vim进
  • Cannot resolve module 'child_process'

    ERROR span class hljs keyword in span span class hljs regexp xmlhttprequest span lib XMLHttpRequest js Module not found
  • Cannot resolve module 'fs'

    可能很多人都会遇到这个问题 xff0c 反正我的话已经遇到两次了 xff0c 上一次解决的时候没有记录解决办法 xff0c 这次又遇到了 xff0c 而且国内搜索引擎是搜不到这个问题的解决办法的 xff0c 所以写个博客记录一下吧 xff0
  • 面试题13:机器人的运动范围

    题目描述 地上有一个m行和n列的方格 一个机器人从坐标0 0的格子开始移动 xff0c 每一次只能向左 xff0c 右 xff0c 上 xff0c 下四个方向移动一格 xff0c 但是不能进入行坐标和列坐标的数位之和大于k的格子 例如 xf
  • flex布局知识点Beta

    先看图 xff0c 实现下方列表中的效果 xff0c 名字在左 xff0c 数量在右 xff0c 相对条目居中 html代码 span class hljs tag lt span class hljs title view span sp
  • js如何一次循环删除数组中的多个元素

    思路 xff1a 数组遍历删除一个元素很容易 xff0c 通过splice方法删除对应索引的元素即可 xff0c 但是遍历删除多个元素就复杂了很多 xff0c 首先不能按索引从小到大的顺序删除 xff0c 这样可能会导致索引对应的元素发生变
  • git删除远程分支

    两步删除远程仓库 xff1a git branch r d origin dev 删除远程分支 git push origin dev然后提交到远程 注意 xff1a dev分支前的冒号 不能少
  • nodejs基础篇(一)

    我从2017年开始接触nodejs xff0c 到现在用了一年多了 xff0c 觉得我有必要写点东西出来 xff0c 记录自己的积累的知识体系 xff0c 以便更好的掌握nodejs nodejs专题不是按照严格的学习历程书写 xff0c
  • 滚动到顶部的实现方法

    span class token comment scrollTop animation span span class token keyword export span span class token keyword function
  • 浅谈ES6的Promise对象

    相信凡是写过javascript的童鞋也一定都写过回调方法 xff08 callback xff09 xff0c 简单说回调方法就是将一个方法func2作为参数传入另一个方法func1中 xff0c 当func1执行到某一步或者满足某种条件
  • node版本管理器——nvm

    nvm是管理node版本的一个工具 xff0c 具体介绍不再赘述 xff0c 请到GitHub xff08 https github com creationix nvm xff09 查看 安装 Linux Mac curl o https
  • centos下修改mysql默认端口

    mysql5 6安装 xff1a br wget http repo mysql com mysql community release el7 5 noarch rpm br rpm ivh mysql community release
  • nginx开启gzip压缩

    nginx安装 xff1a yum install y nginx 配置文件默认在 etc nginx nginx conf 打开nginx conf添加 gzip span class hljs function start span c
  • wordpress安装后问题汇总

    问题一 xff1a wordpress写文章界面点击 添加媒体 和 可视化 文本 无反应 解决方法 xff1a 在wp config php中追加 define 34 CONCATENATE SCRIPTS 34 false 问题二 xff
  • ucos ii是怎么实现多任务运行的?很通俗易懂的描述

    问题 xff1a ucos上建立一个任务 xff0c 格式如上图 xff0c 它是一个死循环 xff0c 但如果我建立了五个任务 xff0c 并且五个任务里面没有延时 xff0c 就只是像无操作系统那样写法 xff0c 用死循环让它们一直跑