嵌入式软件编程模式

article/2025/10/30 16:42:18

文章目录

    • 嵌入式软件编程模式
      • 基于周期调用的运行模式
      • 基于中断的前后台运行模式
      • 基于事件队列的运行模式
      • 带时间信息的事件队列运行模式
      • 周期任务运行框架

整理自:《AI嵌入式系统:算法优化与实现》
本章介绍嵌入式软件编程模式和通用软件优化方案。嵌入式软件编程模式关注的是底层支撑软件的架构,包括内存和CPU运行时间的分配方案,它服务于上层机器学习软件。
嵌入式软件编程模式和传统的计算机编程模式在概念上有所不同,一般计算机软件编程模式侧重软件开发过程中的代码复用和架构标准化技术,以模块化和层次化的形式构建软件对象,而这一章所讨论的嵌入式编程模式是为了满足多任务的实时响应,在有限内存和有限运算能力的嵌入式CPU上高效地完成运算任务。本章讨论的内容除了编程模式外,还包括通用的嵌入式软件优化方案,它们和嵌入式软件编程模式相结合,保障了机器学习算法在嵌入式平台上高效运行。这一章的内容除了可用于提高机器学习应用软件效率外,也能够应用于其他具有类似特性的嵌入式软件。

嵌入式软件编程模式

嵌人式系统和应用紧密结合,不同应用有不同的软件运行要求。下面将讨论几种常见的嵌入式系统编程模式,每种模式有对应的应用场合,可以单独使用或者混合使用。这里讨论的编程模式主要针对没有操作系统的嵌入式软件运行环境,在这种情况下,CPU的全部算力可以分配到和应用相关的计算,不需要额外执行IO资源状态、内存清理、调度等软件操作系统的管理任务,因此运行效率和内存使用效率会更高,但付出的代价是需要手动管理任务并发、IO状态检查、资源共享等,对开发者有更高的要求。

下面首先给出常见的嵌入式系统运行模式示意图,如图2-1所示。
图中系统的功能是从传感器获得外部数据,进行分析运算后输出控制命令,运行期间还需要接收用户输入。
这一架构模型反映了大多数嵌入式系统的运行模式。比如,在语音识别应用中,嵌入式系统周期性地从ADC读入语音的波形数据,经过处理后识别用户语音指令,并根据识别结果输出控制命令。对于运行机器人视频避障软件的嵌入式系统,车软件需要通过摄像头周期性地获得视频数据,分析视频内容,识别障碍和目的地并输出机器人移动控制命令

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c6cRmA1X-1664682027348)(C:\Users\10521\AppData\Roaming\Typora\typora-user-images\image-20221002104706287.png)]

上面描述的嵌人式系统运行模式涉及了多个需要并行执行的任务,每个任务有不同的运行周期性和处理优先级要求。表2-1给出了一个例子,其中嵌人式系统中需要同时运行4个任务,分别是传感器采样数据读取、数据计算及控制输出、用户输人命令检查、状态显示更新。它们的执行周期如表2-1所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x95suWYv-1664682027349)(C:\Users\10521\AppData\Roaming\Typora\typora-user-images\image-20221002104815876.png)]

这几个任务中,读入传感器数据的时间优先级最高,根据采样率所规定的时间间隔运行,不能错过数据;计算及控制输出同样有实时性要求,但它的执行频率低于数据采样;用户命令的检查和状态显示更新的优先级最低,只要满足人们对信息的感知速度即可。
上面几个任务的时间要求和运行频率要求也各不相同。设计时,需要根据优先级制定软件执行方案。当使用实时操作系统时,可以使用比如“单调速率调度算法”(Rate Monotonic Scheduling,RMS)等方案实现以上多任务并发执行,如图2-2示。我们后面讨论的几种编程模式能够不依赖于操作系统实现,允许开发者根据应用特点实现更灵活的定制化多任务执行模式。

在这里插入图片描述

基于周期调用的运行模式

周期运行模式的一种实现方式如代码清单2-1所示,该代码实现了表2-1给出的嵌入式系统的几个任务周期执行。其中while循环内部的几个任务按执行顺序排列,并且每轮while循环根据周期要求对各个任务执行1次或者多次。

在这里插入图片描述

whi1e循环内的代码对应所需要的任务的一个运行周期,如图2-2所示。但在实际情况中,由于每个模块运行时间存在差异,因此往往得到疏密不均匀的“周期”运行效果,如图2-3所示。这使得系统对传感器输入数据的“采样率”不再固定,并且对用户的输入响应间隔也时快时慢,系统运行缺少“确定性”。改进措施如下:

1)将运行时间过长的任务进行状态分割。

2)将采样固定在时间格点上运行。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BVlmeQo4-1664682027351)(C:\Users\10521\AppData\Roaming\Typora\typora-user-images\image-20221002105212087.png)]

下面详细介绍这两种改进方案。
运行时间长的任务拆分

任务拆分是将一个长时间任务分成几个阶段实现,每次循环执行时仅完成其中一个阶段的任务。例如,假设“状态显示更新”任务由于具有LCD特性而运行很慢,我们将其分成几部分,比如假设原始的操作可以分成三部分,如代码清单2-2所示。
在这里插入图片描述

在这里插入图片描述

该函数内部有static类型状态变量state,它的取值在函数一次调用完成到下一次调用期间是保持不变的。我们第一次调用该函数时,由于state=STAGEO,因此执行“更新测量数据曲线图”;第二次调用时,由于state=STAGE1,因此执行“更新数据计算结果”;第三次调用时,由于state=STAGE2,因此执行“更新用户输人内容”;三次调用后,state回到STAGEO,下次调用再次执行“更新测量数据曲线图”,并重复上面的过程,如图2-4所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j3UDSSU7-1664682027352)(C:\Users\10521\AppData\Roaming\Typora\typora-user-images\image-20221002105517569.png)]

通过上面的例子可以看到,我们能够将需要一次运行时间长的函数拆分成多个阶段实现,使得周期执行循环中,执行该函数的时间降低到各个阶段的执行时间。该模式适用于可以分解为多个执行阶段的函数,并且各个执行阶段相对独立,相邻执行阶段的运行时间可以不连续。

时间格点采样
对于传感器数据读取,当相邻两次调用读取数据的函数的间隔小于采样间隔时,通过代码清单2-4给出的伪代码实现采样时间调整,以确保每次数据读取在特定的时间格点上执行。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hx44jg7p-1664682027352)(C:\Users\10521\AppData\Roaming\Typora\typora-user-images\image-20221002105623571.png)]

确定当前时间是否在采样时间格点上,如果不在,则延退等待固定时间。
值得注意的是,在很多情况下,采样时间间隔可以通过外部数据采样硬件确定,用户程序通过FIFO读取数据,当数据尚未到达时,FIFO为空,这使得我们可以基于FIFO是否为空来判断时间格点上的数据采样是否完成,如代码清单2-5所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KMBDs9g3-1664682027352)(C:\Users\10521\AppData\Roaming\Typora\typora-user-images\image-20221002105801738.png)]

上述模式只有当两次执行传感器采样数据读取”的间隔小于采样间隔时才有效,女如果大于采样间隔,则会导致采样点“遗漏如图2-5所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s9rHijdO-1664682027352)(C:\Users\10521\AppData\Roaming\Typora\typora-user-images\image-20221002105834697.png)]

图2-5中虚线是采样时间格点,在中间由于“计算机控制输出”任务运行时间过长,出现过一次采样缺失现象。下面将讨论另外几种编程模式以避免这一问题。

基于中断的前后台运行模式

前面基于循环调用的编程模式难以确保各个任务的等时间周期运行,并且把实时性要求高的任务和实时性要求低的任务混在一起,难以同时兼顾不同任务实时性要求的差异。为了能够确保特定任务的实时性,我们通常使用基于中断的前后台编程模式,如图2-6所示。
其中,时钟中断服务程序负责从外部传感器得到数据输入,由于时钟中断信号具有严格的周期性,因此可以确保数据间隔的稳定,并且由于中断服务程序随时能够打断前台的数据处理、用户输入、显示输出程序执行,因此不受它们的运行速度影响。
使用前后台编程模式时,需要考虑中断服务程序的运行效率,对于前面介绍的固定时间间隔的数据采样任务,要求中断服务程序能够在采样间隔内完成,因此需要尽可能地提高运行效率,在中断服务程序中只保留必不可少的代码,尽可能将那些对实时性要求不高的数据操作放到前台应用程序中执行。比如来自传感器的数据经过了压缩和纠错编码,在中断服务程序运行期间执行数据解压缩和纠错可能导致运行时间过长,进而导致错过下一个采样的时间点,为避免这一现象出现,可以将这些运行时间长但又没有必要在中断服务程序内完成的任务转移到“数据计算及控制输出”函数中执行。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fPtHyGBA-1664682027353)(C:\Users\10521\AppData\Roaming\Typora\typora-user-images\image-20221002110256358.png)]

使用前后台编程模式的一个极端示例是将所有操作移入中断服务程序。硬件提供不同重复间隔和优先级的时钟中断,这样主程序会很简单,只有一个无限循环,而所有的工作由中断服务程序完成,如图2-7所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rekpNHyC-1664682027353)(C:\Users\10521\AppData\Roaming\Typora\typora-user-images\image-20221002110335037.png)]

基于中断服务程序实现所有操作的方案中需要编程者处理数据访问冲突问题,比如传感器数据读取中断服务程序有可能打断“数据计算及控制输出”中断服务程序,“改”还未处理完的数据,这就需要可靠的数据交换机制,以确保不同的代码能够安全地访问共享数据交换空间。比如通过图2-8所示的缓冲器交换数据。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v4s8TcdM-1664682027353)(C:\Users\10521\AppData\Roaming\Typora\typora-user-images\image-20221002110441471.png)]

“写指针”,而“数据计算及控制输出”程序负责从环形缓冲器读取数据,每次读完数据就修改缓冲器的“读指针”,避免对相同的共享数据区同时读写。

基于事件队列的运行模式

这一运行模式是基于中断的前后台运行模式的进一步改进。中断服务程序可以是传感器数据读取程序,也可以是用户指令输入检测程序。后台程序由一系列中断服务程序构成,负责读取数据供前台程序处理,还负责根据输入内容生成“事件”,将待处理事件加上数据序则不断检查事件队列,找到其中待处理的事件数据包,提取并执行,如图2-9所示。
事件队列可以以链表形式或者环形缓冲器形式实现,由于它是由中断服务程序和前台处理程序共享的,因此在编程时需要避免访问冲突。
基于事件列表运行模式的一种扩充是在系统中构建多个事件队列,每个事件队列具有对应的优先级,前台程序根据事件队列的优先级优先处理高优先级的事件,这样能够使对实时性要求高的事件(比如数据计算)能够及时得到处理,如图2-10所示。
这一编程模式在实际应用中要求程序员考虑“低优先级事件积压”问题,即高优先级事件不断出现,导致低优先级事件长时间得不到处理、处理延退过长的问题。需要程序员采取特定措施防止低优先级事件长时间得不到处理,一个解决方案是规定一个低优先级事件队列长度门限,当积压的低优先级事件数量超过门限时,临时提升该队列的处理优先级,避免低优先级事件队列内事件被过度积压。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jsvdc1TQ-1664682027353)(C:\Users\10521\AppData\Roaming\Typora\typora-user-images\image-20221002110636135.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jTEoOFos-1664682027354)(C:\Users\10521\AppData\Roaming\Typora\typora-user-images\image-20221002110703040.png)]

带时间信息的事件队列运行模式

对于需要在特定时间执行指定动作的应用,比如有特定时序要求的硬件设备控制和网络通信协议等,可以使用带时间信息的事件队列的设计模式(见图2-11)。这一设计模式和带优先级的事件队列运行模式相似,差别是这里的每个事件队列的优先级被执行时间所取代,系统根据当前时间检查事件队列,对于时间匹配的事件队列,执行队列中的所有事件,执行完删除该队列。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ACvfTfVB-1664682027354)(C:\Users\10521\AppData\Roaming\Typora\typora-user-images\image-20221002111104158.png)]

事件队列可以由当前正在执行的事件生成,也可以由中断服务程序生成。代码清单2-6中显示了这一模式的运行过程。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jHFzA5zK-1664682027354)(C:\Users\10521\AppData\Roaming\Typora\typora-user-images\image-20221002111132477.png)]

周期任务运行框架

可以参考这两篇文章:

周期任务框架在裸机、RTOS上的实现

软件定时器管理


http://chatgpt.dhexx.cn/article/f8bTm05B.shtml

相关文章

其实嵌入式编程还是很难很复杂的

关注、星标公众号,直达精彩内容 来源:coolbacon 能从PC机器编程去看嵌入式问题,那是第一步;学会用嵌入式编程思想,那是第二步;用PC的思想和嵌入式的思想结合在一起,应用于实际的项目&#xff0c…

嵌入式开发常用技巧及编程知识

嵌入式开发常用技巧及C/C知识 引言查询程序占据的内存大static 静态变量介绍static在函数中的用法 ‘##’连接符断言函数宏定义与条件变量#if...#else...#endif选择是否使用串口调试 memcpy函数void 指针指针大小 字符串小写转大写字符串大写转小写字符串命令处理将某几位清0&a…

嵌入式程序编写方法与规范

嵌入式程序编写方法与规范 前言 本文主要讲解嵌入式单片机程序的编写方法以及编写规范,以MSP430单片机作为例子,无论是51,AVR还是STM32单片机都同样适用,本文对C语言各种语法各种关键字进行详细解释,对操作物理地址的方法进行剖析…

嵌入式系统C语言编程基础

目录 关于本环节前言专栏为什么进行本环节 小测验解答 C语言复习1.循环与分支2.作用域与存储类3.内存与指针指针 4.位操作(1)位操作的用途(2)位运算符(3)用法:掩码(4)用法:打开位、关闭位、转置位(5)用法:查看某一位的值(6)用法:移…

密码学学习笔记三:同余定理

同余定理 我们在《密码学学习笔记二:RSA加密法》里面提到过同余,此处把同余作为补充知识,单独写一篇文章讲解一下。 同余定理是数论中的重要概念。给定一个正整数m,如果两个整数a和b满足(a-b)能够被m整除&a…

简单理解-同余定理

本文章仅用于笔记。部分知识点来源于网络,授权请联系作者(947043511qq.com)。 直接抛出自己的理解: 2个不同的整数a、b,被一个整数m相除时,得到相同的余数,那么我就可以称a、b同余。 因为a、b同…

以太坊EVM源码注释之执行流程

以太坊EVM源码分析之执行流程 业务流程概述 EVM是用来执行智能合约的。输入一笔交易,内部会将之转换成一个Message对象,传入 EVM 执行。在合约中,msg 全局变量记录了附带当前合约的交易的信息,可能是为了一致,这里也…

【密码学探秘】EVM链和并行执行交易

概述 在web3.0世界中,交易的处理性能一直是公链面临的一大技术挑战,如何在不降低安全性和去中心化程度的前提下显著的提升区块链交易的TPS无疑成为众多公链技术专家追逐的目标。以Solana、Aptos为代表的新一代公链的出现更是吹响了通过并行执行交易来攻…

MATLAB计算EVM函数

function [rmsEVM,maxEVM,pctEVM,numSym] EVMcalculate(RxSig,TxSig)%RxSig为接收信号解调后复基带信号;TxSig是发射信号的复基带信号。 %计算接收信号EVM和画星座图 %RxSig,TxSig长度要一样; evm comm.EVM(‘MaximumEVMOutputPort’,true,… ‘XPerce…

通信算法之149:EVM测量

1.星座图 h scatterplot(sqrt(sps)*txSig(sps*span1:end-sps*span),sps,offset); hold on scatterplot(rxSigFilt(span1:end-span),n,offset,bx,h) scatterplot(dataMod,n,offset,r,h) legend(Transmit Signal,Received Signal,Ideal,location,best) 2. 眼图 Eye Diagram D…

以太坊虚拟机 EVM(2)Solidity运行原理

作者:储雨知|FISCO BCOS 核心开发者 引 言 作为一门面向智能合约的语言,Solidity与其他经典语言既有差异也有相似之处。 一方面,服务于区块链的属性使其与其他语言存在差异。例如,合约的部署与调用均要经过区块链网…

IMA/EVM完整性检测代码分析

IMA/EVM完整性检测 IMA(Integrity Measurement Architecture)是一个内核安全子系统,用于检测文件或数据的完整性和安全性。IMA的hook机制指的是内核接口钩子(kernel interface hooks),用于向IMA注册和实现…

为何Cable Loss没补好 EVM会变差

当EVM不好 或是灵敏度不好时 先别急着找硬件问题 先检查Cable Loss 先说结论 先谈谈标题 为何Cable Loss没补好 EVM会变差 多数射频功放输出 会接一个耦合器 将输出功率 耦合到收发器 用意是校正时 侦测输出功率的正确性与否 假设天线头为20dBm Cable loss为5dB 假设天线头…

TI毫米波级联雷达评估板 MMWCAS-DSP-EVM 和MMWCAS-RF-EVM

1. 前言 本文主要是TI的MMWCAS-DSP-EVM 和MMWCAS-RF-EVM 两块评估板的一些使用心得和毫米波雷达的学习总结。 2. 相关原理 毫米波(mmWave)是一类使用短波长电磁波的特殊雷达技术。通过捕捉反射的信号,雷达系统可以确定物体的距离、速度和角度。毫米波雷达可发射波…

DCA1000EVM使用指南

DCA1000EVM使用指南 一、开发环境 1、硬件 AWR1243/xWR1443/xWR1642BOOST(本文以IWR1642BOOST为例)DCA1000EVM5V/2.5A(电流要求不小于2.5A)电源适配器1个或2个 micro USB线2条RJ45网线1根60引脚Samtec连接线(DCA100…

EVM误差矢量幅度

EVM误差矢量幅度是衡量调制精度的一个主要指标,镜像频率的抑制度对EVM的影响取决于镜像频率的抑制度,一般镜像频率抑制度达到31dBc时,对EVM的影响约为5%。镜像频率对信号的影响是因为镜像频率的信号带宽与所需信号的带宽一样,而无…

区块链 以太坊 虚拟机 EVM 详解

一、虚拟机 虚拟机用来 执行以太坊上的交易,更改以太坊状态。 交易分两种: 普通交易智能合约交易。 在执行交易时需要支付油费。 智能合约之间的调用有四种方式。 二、以太坊虚拟机 以太坊虚拟机,简称 EVM,是用来执行以太坊…

以太坊EVM智能合约中的数据存储

目录 EVM基本信息 数据管理 Stack Args Memory Storage 固定长度的值 动态长度数组 Mappings 复杂类型的组合 总结 EVM基本信息 以太坊是一种基于栈的虚拟机,基于栈的虚拟机数据的存取为先进先出,在后面介绍EVM指令的时候会看到这个特性。同时基…

以太坊虚拟机EVM究竟是个啥

基本概念 EVM(ETHereum Virtual Machine)是「以太坊虚拟机」的缩写。如果你有一些软件开发的背景,一定听过java虚拟机。通俗的解释java虚拟机的就是: 我们写的java代码(不只是java,groovy,scala等也可以&a…

介绍 EVM 等效性

介绍 EVM 等效性 上个月,我们宣布了Optimistic 以太坊历史上最重要的升级。最近,我们将Optimistic Kovan迁移到真正的一键式部署,并增加了稳定性,主网在不到三周的时间内就会跟上。 这篇文章是关于我们相信EVM 等效性——完全符合…