C 嵌入式系统设计模式 17:静态优先级模式

本书的原著为:《Design Patterns for Embedded Systems in C ——An Embedded Software Engineering Toolkit 》,讲解的是嵌入式系统设计模式,是一本不可多得的好书。

本系列描述我对书中内容的理解。本文章描述嵌入式并发和资源管理模式之三:静态优先级模式。

静态优先级模式 (Static Priority Pattern) 是一种 调度模式。在计算机系统中,调度模式指的是对任务、进程或线程进行调度时所采用的一种或多种特定的策略或方法。这些模式旨在优化资源利用率、提高系统性能、确保实时响应等。

静态优先级模式对高优先级事件的响应表现良好,并且能够很好地扩展到大量的任务上。大多数实时操作系统都支持静态优先级模式。

静态优先级 是指在创建任务时,赋予任务一个固定的优先级,该优先级在整个任务的生命周期中保持不变。

在确定任务的 优先级 时,可以采用多种不同的方案,但通常这些方案都基于任务的 紧迫性关键性,或是这两者的某种组合。

当采用 速率单调调度(rate monotonic scheduling)进行优先级分配时,静态优先级模式不仅表现出最优性(即无法通过其他调度策略获得更好的性能),还具有稳定性。在过载情况下,可以预测哪些任务会失败——通常是优先级最低的任务。这种可预测性对于实时系统来说至关重要。

速率单调调度:一种为周期性任务分配优先级的策略,其中较短的周期(即较高的频率)被赋予较高的优先级。

在这种情况下,如果我们假设每个任务的截止时间恰好等于一个完整任务执行周期的时长,那么如下所示的公式给出了任务集中可调度的必要条件:
∑ j C j T j + m a x ( B 1 T 1 , . . . , B n − 1 T n − 1 ) ≤ 利用率 ( n ) = n ( 2 1 n − 1 ) \sum_{j}\frac{C_{j}}{T_{j}} + max(\frac{B_{1}}{T_{1}},...,\frac{B_{n-1}}{T_{n-1}}) ≤ 利用率(n) = n(2^{\frac{1}{n} }-1) jTjCj+max(T1B1,...,Tn1Bn1)利用率(n)=n(2n11)
其中:

  • Cj 是任务 j 的最坏执行时间
  • Tj 是任务 j 的执行周期(也是任务 j 的截止时间)
  • Bj 是任务 j 的最坏阻塞时间
  • n 是任务的数目

对于非周期性任务,会使用任务 j 的最小到达间隔时间作为任务的执行周期。请注意,阻塞项仅扩展到第n-1个任务;这是因为根据定义,最低优先级的任务不能被阻塞。

最小到达间隔时间:指的是非周期性任务两次连续启动执行之间的最小时间间隔。

摘要

静态优先级模式 在嵌入式系统中广泛流行,这得益于实时操作系统的强大支持、易用性以及对紧急事件的出色响应能力。然而,对于规模极小、结构简单或由高度可预测且不受紧急异步事件驱动的系统而言,静态优先级模式可能会显得过于复杂。

尽管该模式在可调度性分析方面表现出色,但使用基于阻塞资源共享的原始实现方式可能会引发 不受控制的优先级反转 问题。幸运的是,存在一些资源共享模式,可以有效地避免这一问题,或者至少将优先级反转限制在单个级别内。

在分配优先级时,最常见的方法是基于截止时间的长短,即任务的 紧迫性。通常情况下,截止时间越短的任务被赋予更高的优先级。当截止时间等于任务执行周期时,这种分配方案称为 速率单调调度,此时截止时间越短,执行周期越短,所以执行频率越高,优先级越高。虽然速率单调调度假设所有任务都是周期性的,但对于非周期性任务,也可以采用最小到达间隔时间来进行处理。然而,这种做法往往会导致系统设计的过度冗余(最小达到间隔时间可能很短),进而对系统的经常性成本产生不良影响。

问题

静态优先级模式为任务调度提供了一种基于优先级的简洁方法。与 循环执行模式 相比,它可以处理更多的任务,而且可以对紧急事件快速的响应。

模式结构

模式结构如下图所示:

在这里插入图片描述

彩色类通常由实时操作系统(RTOS)提供。

模式详情

抽象的静态线程

抽象的静态线程调度器关联 。调度器执行线程的 run() 函数来运行线程。这个 run() 函数由抽象的静态线程声明,在具体的静态线程中实现。

具体的静态线程

表示软件中的具体线程。

互斥量类

互斥量类 用于保护共享资源,它对共享资源提供 序列化 访问。确保在任何时候只有一个线程能够访问被保护的资源,从而防止数据竞争和不一致的状态。

当线程需要访问共享资源的受保护函数时,它首先会调用互斥量类的 lock() 函数来尝试获取锁。一旦受保护的代码执行完毕,线程会调用互斥量类的release() 函数来释放锁。

当关联的互斥量被锁定时,调用服务的其他客户端线程将被阻塞,直到互斥量解锁。mutexID 标识哪个互斥量正在阻塞任务。这个元素通常由 RTOS 提供。

序列化 (serializes ) :在编程中,当多个进程或线程尝试同时访问和修改共享资源(如内存中的数据、文件等)时,如果不加以控制,就可能导致数据的不一致或其他未定义的行为。为了解决这个问题,我们需要引入某种机制来确保在任何时候只有一个进程或线程可以访问共享资源,或者至少确保访问是以一种可预测和可控的顺序进行的。
“序列化”访问共享资源就是这样一种机制。通过序列化,我们可以确保对资源的访问请求是按照某种顺序(如先进先出FIFO)排队和处理的。这通常是通过使用锁、信号量、互斥量等同步原语来实现的。当一个进程或线程获得对资源的访问权时,其他进程或线程必须等待直到该资源被释放。

优先级队列

优先级队列 是一个按优先级组织的 StaticTaskControlBlock 指针队列。该模式使用两个独立的优先级队列实例。第一个是 就绪队列 。当任务准备运行时,按其优先级的顺序将其 StaticTaskControlBlock 的指针插入队列中。如果任务的优先级高于当前正在运行的任务(或在当前任务终止时变得更高),那么任务将从就绪队列中移除并运行。另一个优先级队列是 阻塞队列 ;这个队列保存了当前被阻塞的任务集合,因为它们试图访问由锁定的 互斥量类 保护的共享资源。优先级队列通常由RTOS提供。

共享资源

共享资源 由一个或多个 具体的静态线程 共享。为了在所有情况下都能使系统正常运行,共享资源要么是 可重入 的,要么通过访问序列化进行保护。

每个抽象线程都有一个栈,用于存储返回地址和传递的参数。这通常在应用程序线程的汇编语言级别中才是明确的,但它是调度基础设施的重要组成部分。这个元素通常由 RTOS 提供。

静态优先级调度器

静态优先级调度器 基于线程的优先级协调多个线程的执行,它遵循一个简单规则:始终运行优先级最高的就绪线程。当创建任务时,它(或其创建者)会调用 createThread() 函数创建一个线程。每当静态优先级调度器执行此线程时,它都会调用 StartAddr 地址函数(除非线程被阻塞或抢占,在这种情况下,它会调用 EntryPoint 地址函数)。这个元素通常由RTOS提供。

静态任务控制块

静态任务控制块包含其对应的抽象线程对象的 调度信息。这包括线程的优先级、默认起始地址和当前入口地址。静态优先级调度器 为每个现有的抽象线程维护一个静态任务控制块对象。这个元素通常由RTOS提供。

效果

如前所述,静态优先级模式可以很好地运行大量任务,并对传入的事件做出响应。通常情况下,任务大部分时间都在等待启动,只有当触发事件发生时才会激活。当有多个任务时,将优先运行优先级最高的任务。

实现策略

通常情况下我们无需自己实现这个模式,而是使用商业 RTOS 来提供调度基础设施。如今有数十种流行的 RTOS 可以满足大多数嵌入式系统的约束条件。

无论你是购买商业 RTOS 还是自己开发,都必须解决分配优先级的问题。速率单调调度 是分配优先级的最常用方法。它是最优且稳定的。它能获得最好的性能,而且在过载情况下,还可以预测哪些任务会失败(优先级在最低的任务)速率单调调度只是将优先级作为周期的函数——周期越短,优先级越高。

速率单调调度任务做了一些假设:

  • 任务是周期性的
  • 任务的截止时间和执行周期相同
  • 任务可无线抢占

但在违反这些假设的情况下,速率单调调度仍然是相当稳健的。

关于第一个假设,如果任务不是周期性的,那么它们可以使用任务调用之间的最小时间间隔来确定优先级。

关于第二个假设,有时截止时间可能小于周期。在这种情况下,可以简单地使用截止时间(Dj)而不是周期(Tj)来分配优先级。

最后一个假设是,一旦有更高优先级的任务准备就绪,当前正在运行的任务就可以立即被抢占。然而,如果当前正在运行的任务处于 临界区(即禁止任务切换的时间段),这一假设则不成立。但是,如果临界区的时间很短,这通常不会成为问题。在这种情况下,可以将所有其他任务的最长临界区持续时间视为正在分析的任务的最坏情况阻塞时间来进行分析。

实例

见原书。






读后有收获,资助博主养娃 - 千金难买知识,但可以买好多奶粉 (〃‘▽’〃)
千金难买知识,但可以买好多奶粉

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Slicer学习笔记(六十五) 3DSlicer的医学图像数据增强扩展模块

1. 医学图像数据增强扩展模块 基于3D Slicer5.1.0 编写了一个测试医学图像的数据增强测试扩展模块。 扩展模块名:DataAugementation 项目地址:DataAugmentation 下载该项目后,可以将该扩展模块添加到3D Slicer的扩展中。 关于如何给3DSlicer…

【STA】多场景时序检查学习记录

单周期路径 建立时间时序检查 在时钟的有效沿到达触发器之前,数据应在一定时间内保持稳定,这段时间即触发器的建立 时间。满足建立时间要求将确保数据可靠地被捕获到触发器中。 建立时间检查是从发起触发器中时钟的第一个有效沿到捕获触发器中时钟后面…

萌新学习RSA第一天

文章来自NSSCTF工坊Xenny的课程 1.非对称加密 2.介绍RSA来源(三位数学家名字开头) 3.RSA数学基础 4.算法实现 from Crypto.Util.number import * #这个是关于RSA很多函数的库 p getPrime(512) #111RSA第一步:生成随机的51…

Sora学习(一):Sora技术路径整体认知

前文:最近跟着DataWhale组队学习这一期“Sora原理与技术实战”,本篇博客主要是基于DataWhale成员、厦门大学平潭研究院杨知铮研究员分享的Sora技术原理详解课件内容以及参考网上一些博客资料整理而来(详见文末参考文献)&#xff0…

鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:禁用控制)

组件是否可交互,可交互状态下响应点击事件、触摸事件、拖拽事件、按键事件、焦点事件和鼠标事件。 说明: 从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 enabled enabled(value: boolean) 设置组…

持续集成(CICD)- Git版本管理工具,Gitee线上仓库

文章目录 一、学习目标:二、什么是Git工具三 、Git环境搭建(windows系统)四、Gitee设置(私钥和公钥绑定)五、Git结合Gittee进行基本设置(重要)六、在Gitee上新建仓库私有仓库(非空仓库)七、Git拉取线上仓库代码,提交代码(重要)八、Git解决版本冲突问题(重要)场景一…

第二讲:用geth和以太坊交互

一:安装geth brew install ethereum geth github网址: https://github.com/ethereum/go-ethereum 二: 用geth连接以太坊 以太坊有主网络(Ethereum Mainnet),有测试网络(Sepolia、Goerli 等等…

leetcode 热题 100_盛最多水的容器

题解一: 双指针遍历:容量计算公式为min(左高度,右高度)*底部距离,我们可以令底部距离逐步递减(左右两边的指针向中部移动)。此时对于min(左高度,右高度),假设较高的线向中部移动&…

如何修炼成“神医”——《OceanBase诊断系列》之一

本系列是基于OcenaBase 开发工程师在工作中的一些诊断经验,也欢迎大家分享相关经验。 1. 关于神医的故事 扁鹊,中国古代第一个被正史记载的医生,他的成才之路非常传奇。年轻时,扁鹊是一家客栈的主管。有一位名叫长桑君的客人来到…

HTTPS的实现原理

图片来源:HTTPS 详解一:附带最精美详尽的 HTTPS 原理图 - 个人文章 - SegmentFault 思否 加密流程按图中的序号分为: 客户端请求 HTTPS 网址,然后连接到 server 的 443 端口 (HTTPS 默认端口,类似于 HTTP 的80端口)。…

小程序和页面生命周期详解

目录 小程序的生命周期 创建(onLoad): 显示(onShow): 隐藏(onHide): 卸载(onUnload): 错误监听(onError)…

使用最新Hal库实现USART中断收发功能(STM32F4xx)

目录 概述 1 认识STM32F4XX的USART 1.1 USART 功能说明 1.2 USART的中断 1.3 USART 模式配置 1.4 USART的寄存器 2 使用STM32CubeMX 生成工程 2.1 配置参数 2.2 生成工程代码 3 实现软件功能 3.1 软件功能介绍 3.2 认识USART Hal库 3.2.1 初始化函数组 3.2.2 发送…

66-ES6:var,let,const,函数的声明方式,函数参数,剩余函数,延展操作符,严格模式

1.JavaScript语言的执行流程 编译阶段:构建执行函数;执行阶段:代码依次执行 2.代码块:{ } 3.变量声明方式var 有声明提升,允许重复声明,声明函数级作用域 访问:声明后访问都是正常的&…

殿堂级Flink源码极精课程预售

一、为什么我们要读源码? 1、让个人技术快速成长: 优秀的开源框架,底层的源码设计思想也非常优秀,同时还有含有大量的设计模式和并发编程技术,优秀的解决方案,熟读源码对猿们技术提升有很大帮助 2、新技术学习能力: Java开源码框架的源码熟读后,若出现…

挑战杯 基于机器视觉的车道线检测

文章目录 1 前言2 先上成果3 车道线4 问题抽象(建立模型)5 帧掩码(Frame Mask)6 车道检测的图像预处理7 图像阈值化8 霍夫线变换9 实现车道检测9.1 帧掩码创建9.2 图像预处理9.2.1 图像阈值化9.2.2 霍夫线变换 最后 1 前言 🔥 优质竞赛项目系列,今天要分…

Doris实战——银联商务实时数仓构建

目录 前言 一、应用场景 二、OLAP选型 三、实时数仓构建 四、实时数仓体系的建设与实践 4.1 数仓分层的合理规划 4.2 分桶分区策略的合理设置 4.3 多源数据迁移方案 4.4 全量与增量数据的同步 4.5 离线数据加工任务迁移 五、金融级数仓稳定性最佳实践 5.1 多租户资…

返回数据(返回视图所需要的数据)

在上篇文章中,小编带领大家了解到:返回静态数据-CSDN博客,但是,仅仅返回一个静态页面,对于静态页面的数据没正常返回! 所以,本篇文章便讲述如何返回数据?? 还是先不管前…

AI大语言模型【成像光谱遥感技术】ChatGPT应用指南

遥感技术主要通过卫星和飞机从远处观察和测量我们的环境,是理解和监测地球物理、化学和生物系统的基石。ChatGPT是由OpenAI开发的最先进的语言模型,在理解和生成人类语言方面表现出了非凡的能力。本文重点介绍ChatGPT在遥感中的应用,人工智能…

Revit-二开之创建墙-(6)

Revit API窗间墙 protected override Result OnExecute(ExternalCommandData commandData, ref string message, ElementSet elements) {try{// 获取当前活动的文档

html基础标签+Http请求

文章目录 目录 文章目录 前言 一.网址组成 二.HTTP协议解析 Http 请求报文 报文请求方法 报文头 Cache-Control 常见缓存控制行为 cookie 解析 Http 响应报文 常见状态码 三.域名解析(DNS) DNS域名服务器分类 递归查询 迭代查询 四.端口号 五.路径信息 六.Https协议 ​对称…