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

news2024/12/25 16:07:55

上一课:
【小黑嵌入式系统第十课】μ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.coloradmin.cn/o/1327096.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ai学习笔记-入门

目录 一、人工智能是什么?可以做什么? 人工智能(Artificial Intelligence): 人工智能的技术发展路线: 产业发展驱动因素:数据、算力、算法 二、人工智能这个工具的使用原理入门 神经网络⭕数学基础 1.神经网络的生物表示 …

成都爱尔蔡裕主任提醒眼前有条状黑影飘动,该治疗吗?

眼前有好多影子,有的看起来是黑色有的仿佛透明,呈现条状、点状,它们还跟随脑袋的移动而移动,仿佛在眼前打转,尤其在阳光明媚的时候或者注视白墙壁时尤为明显。 这是病吗?需要治疗吗? 飞蚊症 飞蚊症在医学上称为“玻璃…

JavaScript系列-循环语句

文章目录 1. JavaScript 函数常用的循环语句有以下1 打遍所有可循环对象的 for 循环2 for in :遍历对象3 for of :遍历有迭代器对象,如数组4 while 循环5 do while6 switch case 2.各循环方法的使用场景和方法for 循环第一种用法(…

Java-Secruity-2

可以先看这篇文章 Secruity-1👈 1、授权 1.1 权限管理 在日常使用的系统中都会涉及到权限相关的操作,管理员有管理员的操作,用户有用户的操作,不同的用户可以使用不同的功能,这需要使用到权限管理。 所以在写接口…

openGauss学习笔记-168 openGauss 数据库运维-备份与恢复-导入数据-使用gs_restore命令导入数据

文章目录 openGauss学习笔记-168 openGauss 数据库运维-备份与恢复-导入数据-使用gs_restore命令导入数据168.1 操作场景168.2 操作步骤168.3 示例 openGauss学习笔记-168 openGauss 数据库运维-备份与恢复-导入数据-使用gs_restore命令导入数据 168.1 操作场景 gs_restore是…

PyQt6 信号与槽

锋哥原创的PyQt6视频教程: 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计51条视频,包括:2024版 PyQt6 Python桌面开发 视频教程(无废话版…

makefile例子

1、目录结构 2、文件 2.1、 test.h extern void test(void); 2.2 、test.c #include <stdio.h>void test(void) {printf("Hello world!\n"); }2.3 、main.c #include "test.h"int main(void) {test();return 0; }2.4、makefile TEST_DIR : $(s…

【QT表格-6】QTableWidget的currentCellChanged实现中途撤销

背景&#xff1a; 【QT表格-1】QStandardItem的堆内存释放需要单独delete&#xff0c;还是随QStandardItemModel的remove或clear自动销毁&#xff1f;-CSDN博客 【QT表格-2】QTableWidget单元格结束编辑操作endEditting_qtablewidget 单元格编辑事件-CSDN博客 【QT表格-3】Q…

做一个类似东郊到家系统都有哪些功能特点?

随着科技的发展&#xff0c;人们的生活方式也在不断变化&#xff0c;在快节奏的生活中&#xff0c;身心疲惫的人们需要一种快速有效的方式来缓解压力。同城预约上门按摩小程序就是为满足这种需求而诞生的。用户可以通过小程序&#xff0c;方便地预约按摩服务&#xff0c;无需浪…

力扣日记12.21【二叉树篇】98. 验证二叉搜索树

力扣日记&#xff1a;【二叉树篇】98. 验证二叉搜索树 日期&#xff1a;2023.12.21 参考&#xff1a;代码随想录、力扣 98. 验证二叉搜索树 题目描述 难度&#xff1a;中等 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义…

24_28-Golang函数详解

**Golang **函数详解 主讲教师&#xff1a;&#xff08;大地&#xff09; 合作网站&#xff1a;www.itying.com** **&#xff08;IT 营&#xff09; 我的专栏&#xff1a;https://www.itying.com/category-79-b0.html 1、函数定义 :::info 函数是组织好的、可重复使用的、用…

云渲染如何使用?其实很简单,只需3步就搞定了!

很多人第一次接触云渲染&#xff0c;对云渲染不了解&#xff0c;不知道云渲染怎么用&#xff0c;其实很简单&#xff0c;只需要3步就搞定了。 第一步&#xff1a;下载并安装客户端 到炫云官网下载客户端&#xff0c;下载完直接点击安装就可以&#xff0c;炫云的效果图渲染和动…

【代码规范】统一参数校验、结果返回

统一参数校验&#xff1a; 在编写Controller层的代码时&#xff0c;时常会有这种情况出现&#xff1a; RestController RequestMapping("/user") public class UserController {Resourceprivate UserService userService;PostMapping("register")public S…

【基础知识】大数据组件YARN简述

YARN是一个分布式的资源管理系统。 YARN是Hadoop系统的核心组件&#xff0c;主要功能包括负责在Hadoop集群中的资源管理&#xff0c;负责对作业进行调度运行以及监控。 ResourceManager 负责集群的资源管理与调度&#xff0c;为运行在YARN上的各种类型作业分配资源。 非HA集…

设计模式03结构型模式

结构型模式 参考网课:黑马程序员Java设计模式详解 博客笔记 https://zgtsky.top/ 结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式&#xff0c;前者采用继承机制来组织接口和类&#xff0c;后者釆用组合或聚合来组合对象。 由于…

通过讯飞 API 接口用 Vue 实现实时语音转写

通过讯飞 API 接口用 Vue 实现实时语音转写 项目地址 前言 本项目中实时语音能够转写的最大时间为 60 s&#xff0c; 这个数据也是由 API 提供方给限制掉的 为什么我会需要这个点击按钮以后能够实现实时语音的转写呢&#xff0c;因为被课程所迫&#xff0c;选了这个方向就必…

linux 性能优化-内存优化

CPU 管理一样&#xff0c;内存管理也是操作系统最核心的功能之一。内存主要用来存储系统和应 用程序的指令、数据、缓存等。 1.内存原理 1.1.内存映射 1.1.1.日常生活常说的内存是什么? 我的笔记本电脑内存就是 8GB 的这个内存其实是物理内存物理内存也称为主存&#xff0…

Java最全面试题专题---5、Spring面试题(1)

Spring概述&#xff08;10&#xff09; 什么是spring? Spring是一个轻量级Java开发框架&#xff0c;最早有Rod Johnson创建&#xff0c;目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的JavaSE/JavaEE full-stack&#xff08;一站式&#xff…

联合体(C语言)

小伙伴们又来学习知识啦~&#xff0c;今天我要给大家介绍一下联合体的使用&#xff0c;话不多说&#xff0c;我们开始今天的正题吧&#xff01; 联合体的介绍 C语言的联合体&#xff08;union&#xff09;是一种特殊的数据类型&#xff0c;它可以在同一内存空间中存储不同的数…

龙迅LT86102UXE HDMI一分二HDMI,支持音频剥离,支持4K60HZ

描述&#xff1a; 龙迅 LT86102UXE HDMI2.0 分路器具有符合 HDMI2.0/1.4 规范的 1&#xff1a;2 分路器、最大 6Gbps 高速数据速率、自适应均衡 RX 输入和预加重 TX 输出&#xff08;用于支持长电缆应用&#xff09;、内部 TX 通道交换以实现灵活的 PCB 布线。 LT86102UXE HDM…