【小黑嵌入式系统第十一课】μC/OS-III程序设计基础(一)——任务设计、任务管理(创建基本状态内部任务)、任务调度、系统函数

上一课:
【小黑嵌入式系统第十课】μC/OS-III概况——实时操作系统的特点、基本概念(内核&任务&中断)、与硬件的关系&实现

文章目录

    • 一、任务设计
      • 1.1 任务概述
      • 1.2 任务的类型
        • 1.2.1 单次执行类任务(运行至完成型)
        • 1.2.2.周期执行类任务(无限循环型)
        • 1.2.3 事件触发执行类任务(一种无限循环型)
      • 1.3 任务的划分
        • 1.3.1 任务划分的目标
        • 1.3.2 任务的优先级
    • 二、任务管理
      • 2.1 任务创建
      • 2.2 任务的基本状态
      • 2.3 系统内部任务
        • 2.3.1 空闲任务 `OS_IdleTask()` (`os_core.c`)
        • 2.3.2 时钟节拍任务 `OS_TickTask() `(os_tick.c)
        • 2.2.3 定时器任务 `OS_TmrTask()` (os_tmr.c)
    • 三、任务调度
      • 3.1 任务调度器
      • 3.2 调度点
    • 四、系统函数概述
      • 4.1 基本原则
        • 4.1.1 配对性原则
        • 4.1.2 中断服务程序调用函数的限制
        • 4.1.3 任务必须调用某个系统函数
      • 4.2 系统函数的分类


一、任务设计

1.1 任务概述

在基于实时操作系统的应用程序设计中,通常需要把要完成的工作分成多个任务(也称线程)来实现,每个任务只负责其中的一部分相对独立的工作,它可以认为在独享CPU。

在只有一个CPU时,任何时刻都只能有一个任务得到执行。操作系统通过任务调度将CPU执行时间在不同任务之间快速切换,以达到多任务“同时”运行的效果。

μC/OS-III允许应用程序有任意多个任务(仅受存储器容量限制),任务优先级数量可由用户配置,不同的任务允许拥有相同的优先级。

对于不同优先级的任务,采用抢占式(可剥夺式)任务调度方式;对于相同优先级的任务,采用时间片轮转调度方式。

在基于实时操作系统的应用程序设计中,任务设计是整个应用程序的基础,其它软件设计工作都是围绕任务设计来展开。

在这里插入图片描述


1.2 任务的类型

按照执行方式分类:

在这里插入图片描述

1.2.1 单次执行类任务(运行至完成型)

在这里插入图片描述


1.2.2.周期执行类任务(无限循环型)

在这里插入图片描述


1.2.3 事件触发执行类任务(一种无限循环型)

在这里插入图片描述


无限循环型的任务中,必须调用等待某个事件或延时的系统API函数(而非自己编写的不受操作系统管理的等待函数,如CyDelay() ),否则将会导致其它优先级更低的任务无法得到执行。(原因见“任务调度”部分)

当任务在等待一个事件或延时时,它不会占用CPU时间,此期间CPU可被系统分配给其它任务执行。


1.3 任务的划分

1.3.1 任务划分的目标

在对一个具体的嵌入式应用系统进行任务划分时,可以有不同的任务划分方案。为了选择最佳划分方案,就必须知道任务划分的目标。

  1. 首要目标是满足“实时性”指标:即使在最坏的情况下,系统中所有对实时性有要求的功能都能够正常实现;

  2. 任务数目合理:对于同一个应用系统,合理的合并一些任务,使任务数目适当少一些还是比较有利;但任务数目少并不一定能保证设计是多么优秀或多么有效率。

  3. 简化软件系统:一个任务要实现其功能,除了需要操作系统的调度功能支持外,还需要操作系统的其它服务功能支持,合理划分任务,可以减少对操作系统的服务要求,简化软件系统;

  4. 降低资源需求:合理划分任务,减少或简化任务之间的同步和通信需求,就可以减少相应数据结构的内存规模,从而降低对系统资源的需求。


1.3.2 任务的优先级

任务的优先级安排原则如下:

在这里插入图片描述

  1. 中断关联性:与中断服务程序(ISR)有关联的任务应该安排尽可能高的优先级,以便及时处理异步事件,提高系统的实时性。
    如果优先级安排得比较低,CPU有可能被优先级比较高的任务长期占用,以致于在第二次中断发生时连第一次中断还没有处理,产生信号丢失现象。

  2. 关键性:任务越关键安排的优先级越高,以保障其执行机会;

  3. 频繁性:对于周期性任务,执行越频繁,则周期越短,允许耽误的时间也越短,故应该安排的优先级也越高,以保障及时得到执行;

  4. 快捷性:在前面各项条件相近时,越快捷(耗时短)的任务安排的优先级越高,以使其它就绪任务的延时缩短;

  5. 传递性:信息传递的上游任务的优先级高于下游任务的优先级。如信号采集任务的优先级高于数据处理任务的优先级。


二、任务管理

2.1 任务创建

为了使μC/OS-III知道一个任务的存在,必须先创建该任务,通过调用系统API函数OSTaskCreate()来创建一个任务。

在这里插入图片描述

  • 任务可以在多任务调度开始前建立,也可以在其它任务的执行过程中建立。
  • 在开始多任务调度之前,用户必须至少创建一个用户任务。
  • 任务不能在中断服务程序(ISR)中建立。
  • μC/OS-III通过任务控制块(TCB)对任务进行管理,创建任务实际上就是给任务代码分配一个任务控制块。
  • 任务控制块是一个基于链表的数据结构体,任务控制块主要用于记录任务的堆栈栈顶指针、指向下一个任务控制块的指针、任务等待的延迟时间、任务的当前状态标志与任务的优先级别等一些与任务管理有关的属性。
  • 当任务的CPU使用权被剥夺时,μC/OS-III用任务控制块来保存该任务的状态,从而保证任务重新获得CPU使用权时能从断点处恢复继续执行。

任务的相关资源(图中未含任务控制块):

在这里插入图片描述

  • 任务栈是一个后进先出(LIFO)的线性表。
    每个任务均需有一个栈(任务栈),用于存储局部变量、传递的函数参数、返回地址及CPU寄存器的值。
  • 每个任务均需有一个优先级,取值范围0~OS_CFG_PRIO_MAX-1,用户不能使用最高优先级0和最低优先级 。
  • 任务的具体实现对应于任务函数,任务函数的参数p_arg值由任务创建函数OSTaskCreate()传递而来。
    任务函数由系统择机调用,而不能由用户主动调用。

2.2 任务的基本状态

任务的5种基本状态及转换关系:

在这里插入图片描述

简化地说,任务的状态有5种:休眠态就绪态运行态等待态中断服务态
任务被创建后,将由不受操作系统管理的休眠态转换为就绪态,由任务调度器决定何时使用CPU运行(运行态)。

任务状态的转换由执行了某些特定的OS API函数(或中断进入退出)引起。


2.3 系统内部任务

μC/OS-III共有5个系统内部任务:

  • 空闲任务 OS_IdleTask()
  • 时钟节拍任务 OS_TickTask()
  • 统计任务 OS_StatTask()
  • 定时器任务 OS_TmrTask()
  • 中断服务管理任务 OS_IntQTask()

2.3.1 空闲任务 OS_IdleTask()os_core.c

当所有其它任务都未就绪时,由于CPU仍需执行指令不能停止运行,此时将运行空闲任务。

它是系统创建的第一个任务,必须创建。空闲任务的优先级为最低优先级OS_CFG_PRIO_MAX-1,其它任务不能使用该最低优先级。


2.3.2 时钟节拍任务 OS_TickTask() (os_tick.c)

任务中的延时、等待某事件时的超时,这些都需要依赖一个周期性的时钟源来计时,称为时钟节拍或系统节拍。经历一个周期称为一个时钟节拍。

时钟节拍任务必须创建,其优先级由OS_CFG_TICK_TASK_PRIO(os_cfg_app.h)设定,通常设为只比最重要的用户任务的优先级略低一点。时钟节拍任务负责判定其它任务中的所有延时、超时的结束。

在这里插入图片描述

  • 需配备一个硬件定时器(时钟节拍定时器),工作频率由OS_CFG_TICK_RATE_HZ设定在10~1000(Hz)之间。
  • 时钟节拍任务收到时钟节拍定时器ISR周期发送的信号量时,才开始它的处理工作。否则处于等待态。

2.2.3 定时器任务 OS_TmrTask() (os_tmr.c)

用于向用户提供较粗的定时服务。该任务可选,由OS_CFG_TMR_EN(os_cfg.h)使能。

定时器任务是一个周期运行的任务,它和时钟节拍任务使用相同的硬件定时器。通过软件方式的分频,定时器任务可实现(比时钟节拍定时器)定时精度低的软件定时器(数量仅受存储器容量限制)。

定时器任务提供的(软件)定时器为递减计数器,计数值减为0时,会引发一个操作,该操作由操作系统调用一个用户定义的回调函数(运行在定时器任务环境中)来实现。

定时器任务的优先级一般设置为中等优先级,由宏OS_CFG_TMR_TASK_PRIO(os_cfg_app.h)来设定。

时钟节拍ISR和定时器任务的关系:

在这里插入图片描述
与时钟节拍任务共用时钟节拍硬件定时器。

定时器任务每收到 N个 时钟节拍定时器ISR周期发送的信号量时,才开始它的处理工作。相当于对时钟节拍定时器进行软件分频。

由定时器任务管理的所有定时器都拥有同样的时间分辨率,即1/OS_CFG_TMR_TASK_RATE_HZ秒,其常用推荐值为0.1秒。


三、任务调度

3.1 任务调度器

任务调度器(简称调度器)负责确定CPU下一个要执行的任务。

μC/OS-III支持两种任务调度算法:抢占式(可剥夺式)调度时间片轮转调度

  • 抢占式(可剥夺式)调度:CPU执行进入就绪态的优先级最高的任务(若当前正运行的任务优先级最高,仍执行它)。

当一个事件的发生使得一个更高优先级的任务就绪时,调度器会“立即”将CPU的控制权剥夺,转交给该更高优先级的任务使用,看起来像是高优先级任务“抢占”了CPU。

  • 时间片轮转调度:有多个就绪任务(以及当前正运行的任务)处于同一优先级时,这些任务轮流运行一段指定的时间(又称时间片),一个时间片包含若干个时钟节拍。

默认各任务有相等的时间片,也可用户指定各任务的时间片长度。

抢占式调度中,任务级的任务调度由OS_Sched()函数完成,而中断级的任务调度由ISR结束时的OSIntExt()函数完成。
时间片轮转任务调度由OS_SchedRoundRobin()函数完成。


3.2 调度点

μC/OS-III 任务调度不可能随时都在进行,当程序调用某些系统服务函数时,调度器才会自动启动,这些时间点称为调度点。

由于调度点很多,几乎可以认为“随时”都在进行任务调度。

在这里插入图片描述


四、系统函数概述

4.1 基本原则

4.1.1 配对性原则

对于μC/OS-III来说,大多数API是设计成成对出现的,而且一部分必须配对使用。部分API如延时,不需要配对使用。配对的函数见下表。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


4.1.2 中断服务程序调用函数的限制

中断服务程序不能调用可能会导致任务调度的函数,它们主要是一些等待事件的函数,这些函数见下表。

在这里插入图片描述

注意:未列入表中的函数OSTaskCreate()OSTaskDel()OSTaskResume()OSTaskSuspend()OSTimeDly()OSTimeDlyHMSM()OSTimeResume()都属于在中断服务程序中禁止调用的函数。

一些函数虽然没有明确地规定不能被中断服务程序调用,但因为中断服务程序的特性,一般不会使用。

  • 1.创建事件和删除事件的函数。
  • 2.与任务相关的函数OSTaskChangePrio()OSTaskTimeQuantaSet()OSTaskStkChk()。至于函数OSSchedLock()OSSchedUnlock(),在中断服务程序中使用没有任何意义。

4.1.3 任务必须调用某个系统函数

因为μC/OS-III是完全基于优先级的操作系统,所以在一定的条件下必须出让CPU占有权以便比自己优先级更低的任务能够运行,这是通过调用部分系统函数来实现的,这些函数见下表。一般的任务必须调用表中至少一个函数,只有一种情况例外,即单次执行的任务,因为任务删除后肯定出让CPU,所以可以不调用表中的函数。

在这里插入图片描述


4.2 系统函数的分类

在这里插入图片描述


系统管理函数是一些与μC/OS-III内核或功能相关的一些函数,详见下表:

在这里插入图片描述
μC/OS-III的初始化函数有2个:OSInit()OSStart(),它们不能在任何任务和中断服务程序中使用,仅在main()函数中按照一定的规范被调用,其中OSInit()函数初始化μC/OS-III内部变量,OSStart()函数启动多任务环境。


μC/OS-III具有简单的动态内存管理能力。μC/OS-III的动态内存管理函数见下表:

在这里插入图片描述


任务管理函数是操作与任务相关功能的函数,详见下表:

在这里插入图片描述
μC/OS-III把信号量等都称为事件,管理它们的就是事件管理函数。μC/OS-III具有的事件有普通信号量、互斥信号量、事件标志组和消息队列,这些都是μC/OS-III用于同步与通讯的工具。


一般的操作系统都提供时间管理的函数,最基本的就是延时函数,μC/OS-III也不例外,μC/OS-III所具有的时间管理函数见下表:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/222121.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

centos7安装开源日志系统graylog5.1.2

安装包链接:链接:https://pan.baidu.com/s/1Zl5s7x1zMWpuKfaePy0gPg?pwd1eup 提取码:1eup 这里采用的shell脚本安装,脚本如下: 先使用命令产生2个参数代入到脚本中: 使用pwgen生成password_secret密码 …

Linux之进程(五)(进程控制)

目录 一、进程创建 1、fork函数创建进程 2、fork函数的返回值 3、fork常规用法 4、fork调用失败的原因 二、进程终止 1、进程终止的方式 2、进程退出码 3、进程的退出方法 三、进程等待 1、进程等待的必要性 2、wait函数 3、waitpid函数 四、进程程序替换 1、概念…

利用ffmpeg cv2取h265码流视频(转换图片灰屏问题解决)

利用海康威视相机拍出来的视频是H265格式的,相比于常规的H264编码,压缩率更高,但因此如果直接用正常取流方法读取,会出现无法读取的情况 1. 如图h265码流取出图片为灰屏 2 、解决灰屏问题 import subprocess import cv2# 将h265流…

100GPTS计划-AI学术AcademicRefiner

地址 https://chat.openai.com/g/g-LcMl7q6rk-academic-refiner https://poe.com/AcademicRefiner 测试 减少相似性 增加独特性 修改http://t.csdnimg.cn/jyHwo这篇文章微调 专注于人工智能、科技、金融和医学领域的学术论文改写,秉承严格的专业和学术标准。 …

使用opencv实现图像中几何图形检测

1 几何图形检测介绍 1.1 轮廓(contours) 什么是轮廓,简单说轮廓就是一些列点相连组成形状、它们拥有同样的颜色、轮廓发现在图像的对象分析、对象检测等方面是非常有用的工具,在OpenCV 中使用轮廓发现相关函数时候要求输入图像是二值图像,这…

华为安防监控摄像头

华为政企42 华为政企 目录 上一篇华为政企城市一张网研究报告下一篇华为全屋wifi6蜂鸟套装标准

【数据结构】二叉树的模拟实现

前言:前面我们学习了堆的模拟实现,今天我们来进一步学习二叉树,当然了内容肯定是越来越难的,各位我们一起努力! 💖 博主CSDN主页:卫卫卫的个人主页 💞 👉 专栏分类:数据结构 👈 &…

大创项目推荐 深度学习 机器视觉 人脸识别系统 - opencv python

文章目录 0 前言1 机器学习-人脸识别过程人脸检测人脸对其人脸特征向量化人脸识别 2 深度学习-人脸识别过程人脸检测人脸识别Metric Larning 3 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习 机器视觉 人脸识别系统 该项目…

LabVIEW开发自动驾驶的双目测距系统

LabVIEW开发自动驾驶的双目测距系统 随着车辆驾驶技术的不断发展,自动驾驶技术正日益成为现实。从L2级别的辅助驾驶技术到L3级别的受条件约束的自动驾驶技术,车辆安全性和智能化水平正在不断提升。在这个过程中,车辆主动安全预警系统发挥着关…

CloudCanal x Debezium 打造实时数据流动新范式

简述 Debezium 是一个开源的数据订阅工具,主要功能为捕获数据库变更事件发送到 Kafka。 CloudCanal 近期实现了从 Kafka 消费 Debezium 格式数据,将其 同步到 StarRocks、Doris、Elasticsearch、MongoDB、ClickHouse 等 12 种数据库和数仓,…

simulink代码生成(一)——环境搭建

一、安装C2000的嵌入式环境; 点击matlab附加功能, 然后搜索C2000,安装嵌入式硬件支持包;点击安装即可;(目前还不知道破解版的怎么操作,目前我用的是正版的这样,完全破解的可能操作…

华为数通方向HCIP-DataCom H12-831题库(多选题:201-220)

第201题 在多集群RR组网中,每个集群中部署了一台RR设备及其客户机,各集群的RR与为非客户机关系,并建立IBGP全连接。以下关于BGP路由反射器发布路由规则的描述,正确的有哪些? A、若某RR从EBGP对等体学到的路由,此RR会传递给其他集群的RR B、若某RR从非客户机IBGP对等体学…

Axure之中继器的使用(交互动作reperter属性Item属性)

目录 一.中继器的基本使用 二.中继器的动作(增删改查) 2.1 新增 2.2 删除 2.3 更新行 2.4 效果展示 2.5 模糊查询 三.reperter属性 在Axure中,中继器(Repeater)是一种功能强大的组件,用于创建重复…

C# 使用MSTest进行单元测试

目录 写在前面 代码实现 执行结果 写在前面 MSTest是微软官方提供的.NET平台下的单元测试框架;可使用DataRow属性来指定数据,驱动测试用例所用到的值,连续对每个数据化进行运行测试,也可以使用DynamicData 属性来指定数据&…

Flink系列之:Savepoints

Flink系列之:Savepoints 一、Savepoints二、分配算子ID三、Savepoint 状态四、算子五、触发Savepoint六、Savepoint 格式七、触发 Savepoint八、使用 YARN 触发 Savepoint九、使用 Savepoint 停止作业十、从 Savepoint 恢复十一、跳过无法映射的状态恢复十二、Resto…

IEEE TASLP | 联合语音识别与口音识别的解耦交互多任务学习网络

尽管联合语音识别(ASR)和口音识别(AR)训练已被证明对处理多口音场景有效,但当前的多任务ASR-AR方法忽视了任务之间的粒度差异。细粒度单元(如音素、声韵母)可用于捕获与发音相关的口音特征&…

ruoyi若依前后端分离版部署centos7服务器(全)

目录 VMware虚拟机 centos7 安装环境如下 一、msql 5.7 二、nginx1.23.3 三、java8 四、redis 3.2.1 五、部署若依前端 六、部署若依后端 前言 虚拟机的桥接与nat模式 : 重点 重点!!! 无线不可以用桥接模式 ,而你用了nat模式会…

安全狗云原生安全-云甲·云原生容器安全管理系统

随着云计算的快速发展,容器技术逐渐成为主流。然而,随着容器的普及,安全问题也日益突出。为了解决这一问题,安全狗推出了云原生容器安全管理系统——云甲。 云甲是安全狗云原生安全的重要组成部分,它采用了先进的云原生…

版本化数据库管理工具Flyway介绍和Spring Boot集成使用

文章目录 核心功能如何使用 Flyway最佳实践Spring Boot使用 Flyway 是一个版本化数据库管理工具,用于跟踪、管理和应用数据库的变化。它非常适合在团队开发环境中使用,其中多个人员可能会在数据库结构进行更改。Flyway 通过版本控制可以帮助你确保所有人…

Redis-Day3实战篇-商户查询缓存(缓存的添加和更新, 缓存穿透/雪崩/击穿, 缓存工具封装)

Redis-Day3实战篇-商户查询缓存 什么是缓存添加Redis缓存业务流程项目实现练习 - 给店铺类型查询业务添加缓存 缓存更新策略最佳实践方案案例 - 给查询商铺的缓存添加超时剔除和主动更新 缓存穿透/雪崩/击穿缓存穿透概述项目实现 - 商铺查询缓存 缓存雪崩缓存击穿概述互斥锁逻辑…