C嵌入式编程设计模式~读书笔记
文章平均质量分 82
《c嵌入式编程设计模式》以面向对象的视角,重新审视嵌入式系统,全面总结了嵌入式系统中常见的以及关键的设计模式。本书提出了很多新颖的设计模式,为使用c语言编程的嵌入式系统开发者提供了强有力的工具。通过这些模式,开发者可以用最短的时间设计出性能好、稳定性强、安全性高的嵌入式系统或软件。
Let's Chat Coding
实时嵌入式系统软件开发
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
C嵌入式编程设计模式源码
【代码】C嵌入式设计模式。原创 2023-12-05 22:48:34 · 405 阅读 · 1 评论
-
Bruce Powel Douglass大师介绍
Bruce Powel Douglass是嵌入式软件、系统工程和实时系统开发领域的知名人物。他的职业生涯超过35年,特别是在实时和嵌入式系统的软件工程方法论方面做出了重大贡献。原创 2023-11-28 21:53:41 · 1744 阅读 · 0 评论
-
嵌入式系统设计挑战:提高软件设计透明度与强化设计先行原则
*在嵌入式软件设计领域,"极致"的代码清晰度确实是一个追求的目标,但在实践中,许多因素导致代码难以理解,即使是对于经验丰富的工程师来说也是如此。在某些情况下,项目需求可能不明确或经常变化,导致工程师选择边编码边调整设计,而不是在编码前花费时间设计一个可能会变的系统。在快速发展的项目中,文档和代码注释可能没有得到很好的维护,导致即使是原始作者也可能忘记了代码的具体逻辑和设计意图。有时,工程师可能不认为设计是一个重要的步骤,或者认为它是一个可以省略的奢侈步骤,尤其是在时间有限的情况下。原创 2023-11-13 15:13:54 · 54 阅读 · 0 评论
-
MCU订阅-发布模式
McnHub是 uMCN 的核心结构,负责管理主题的发布和订阅。McnNode代表订阅者,管理订阅的主题和数据更新的回调函数。McnList用于维护所有消息中心的链表。uMCN通过这些结构实现了一个高效的发布-订阅系统,保证了发布者和订阅者之间的松耦合和数据的一致性。原创 2024-10-05 16:07:01 · 1455 阅读 · 0 评论 -
stateMachine状态机框架
关于状态机的背景知识,在上一篇文章,已经有做介绍,还没有看的小伙伴可以先点击进去看一下,如果实在没有时间看,也不影响本篇文章的阅读,本篇文章主要讲一个状态机c语言实现框架,和基于该框架的一些实例。转载 2024-05-08 11:21:10 · 23 阅读 · 0 评论 -
主动对象与被动对象
因为它们有自己的控制流程,主动对象通常负责管理其内部状态的改变,并且能够在没有外部调用的情况下开始处理任务。被动对象没有自己的控制流程,它们不启动操作,而是对来自主动对象或外部源的请求作出反应。在设计嵌入式或者并发系统时,恰当地使用主动对象和被动对象可以帮助开发者有效地管理复杂度和系统的可预测行为,同时确保系统的响应性和性能。在软件工程和程序设计中,主动对象和被动对象是两种不同类型的对象,它们的主要区别在于它们的行为方式和系统资源的使用。,通常用来存储和管理数据,它们的行为总是由其他主动对象触发。原创 2024-04-04 14:27:48 · 59 阅读 · 0 评论 -
根据事务识别对象
在嵌入式软件开发中,根据事务识别对象涉及分析嵌入式系统的具体操作和行为,以确定哪些成分应该作为对象来处理。嵌入式系统通常涉及实时处理、与硬件直接交互以及执行特定的控制任务,这些系统的事务可能包括信号采集、设备状态更新、数据处理、通信任务或用户交互等。原创 2024-04-04 14:26:52 · 57 阅读 · 0 评论 -
根据关键概念识别对象
为对象之间的交互定义清晰的接口。这是嵌入式系统中尤为重要的,因为硬件的限制和实时性要求更高的可靠通信。原创 2024-04-04 14:25:48 · 539 阅读 · 0 评论 -
嵌入式软件设计之对象识别策略
在嵌入式软件开发中,对象识别策略是指在设计阶段识别出应用程序中应当定义为对象的实体。这些策略帮助开发者识别出应该由对象来管理的软件的各个部分,特别是那些与嵌入式硬件紧密交互的部分。在执行对象识别策略时,开发者应考虑系统的实时性需求、资源限制(如内存和处理器速度)、以及与硬件的接口需求。此外,在嵌入式系统中,性能、可靠性和安全性尤为重要,这些因素也应在对象识别和系统设计过程中予以充分考虑。例如,配置数据、系统状态、缓存数据等。系统提供的服务,如I/O处理、数据采集、网络通信等,可以被封装为对象。原创 2024-04-04 14:22:50 · 41 阅读 · 0 评论 -
7.4 Highest Locker Protocol/Pattern
Bruce Powel Douglass大师介绍-CSDN博客嵌入式软件开发从小工到专家-CSDN博客C嵌入式编程设计模式源码-CSDN博客最高锁定模式虽然可以减少优先级反转的情况,但并不能保证完全避免死锁。其他模式,如有序锁定模式(Ordered Locking Pattern)和同时锁定模式(Simultaneous Locking Pattern),则提供了避免死锁的其他方法。原创 2024-02-01 22:58:35 · 1092 阅读 · 0 评论 -
4.7 实时嵌入式:死锁发生条件及解决方案
死锁是指多个进程在等待彼此持有的资源时发生的一种相互阻塞的状态,这种状态下,所有相关进程都无法向前推进。现在让我们结合给出的例子进行详解。原创 2023-11-30 22:37:58 · 342 阅读 · 0 评论 -
5.7 AND-States
通过使用事件传播模式,可以有效地控制AND-states中的事件处理顺序,确保状态机按照预期的方式响应事件。这对于需要精确控制状态机行为的场景特别有用,例如当事件的处理顺序对系统的最终状态有重要影响时。例如,考虑图5-21中的状态机。它包含了一个竞争条件,e1事件在两个AND-states中都有处理,每个AND-state都有一个操作变量x的动作。如果上面的AND-state先处理它的事件,x的最终值是33;尽管这在理论上可行,但实际上我从未见过以这种方式实现AND-states的例子,这也有充分的理由。原创 2023-11-27 00:10:30 · 557 阅读 · 0 评论 -
2.1 C语言 ECG模块设计(推送)
/ 定义客户端接口,所有客户端必须实现这个接口} IClient;首先,我们定义观察者(Observer)和主题(Subject)的基本结构和接口。} Observer;```### 步骤 2:实现主题然后,我们提供TMDQueue作为主题的具体实现。```### 步骤 3:实现观察者现在,我们定义观察者,例如WaveformDisplay。```c```### 步骤 4:主函数中注册观察者并触发更新。原创 2023-11-26 11:28:01 · 551 阅读 · 0 评论 -
3.3 C语言 硬件适配器设计模式
该模式的使用使得应用程序可以无需改变即可适用于同一类型的不同硬件设备,同时也支持不同硬件代理的重用。当应用程序要求或使用一种接口,但实际硬件提供另一种接口时,与其重写硬件设备的客户端来使用提供的接口,不如创建一个适配器,为客户端提供期望的接口,同时转换对实际硬件接口的请求。硬件适配器模式通过创建一个中间适配器层来转换客户端和硬件之间的接口,避免了直接修改客户端代码以适应新硬件接口的复杂性。硬件适配器模式扩展了硬件代理模式,通过增加硬件适配器来适应客户端所期望的接口,并展示了与硬件支持的接口之间的关系。原创 2023-11-11 04:09:02 · 18 阅读 · 0 评论 -
3.5 C语言观察者设计模式
观察者模式(也称为"发布-订阅模式")允许客户端在相关数据发生变化时收到通知。这种模式的优点是数据服务器不需要预先知道其客户端。客户端可以通过订阅/退订接口,可以将自己动态的添加到服务器通知列表或将将自己从服务器通知列表中移除。这允许服务器根据需要实施任何通知策略。通常情况下,每当有新数据时,系统就会通知客户端,但系统也可以设置为定期或按最小/最大频率更新客户端,以此减轻客户端的计算负荷,并保证客户端具有实时数据。原创 2023-11-12 01:36:22 · 24 阅读 · 0 评论 -
5.7 AND-States(与状态)
例如,一个交通灯的状态机可能有两个独立方面:颜色(关闭,红色,黄色,绿色)和显示样式(关闭,稳定,缓慢闪烁和快速闪烁)。如果你看图5-6,会发现共有10个状态。例如,在灯光系统中,可以有一个颜色的AND-State和一个闪烁模式的AND-State,每个AND-State管理自己的状态变化,系统则需要同时在这两个AND-State中各自处于一个状态。当一个系统,如灯光系统,同时具有多个可独立变化的属性(例如颜色和闪烁模式)时,每个属性的每个可能状态都与其他属性的每个可能状态组合,导致状态总数呈指数级增长。原创 2023-11-22 00:37:30 · 349 阅读 · 0 评论 -
5.2.3 状态机之超时定时器
在这种情况下,系统绕过默认的(在go [useDefaults()]转换中采取的)并且转移到MovingRobotArm复合状态内的两个非默认状态。我们之前已经见过的默认和最终伪状态。此外,分支和合并伪状态允许在复合状态内部进行并行状态跟踪,而历史伪状态允许在重新进入复合状态时返回到最后一个活跃的嵌套状态。超时转换是状态机中的一种特殊事件,允许在状态持续存在一定时间后触发状态变化,而不需要外部事件的激活。在状态机设计中使用这些伪状态,可以更灵活地处理复杂逻辑,同时避免状态爆炸,提高模型的清晰度和可维护性。原创 2023-11-22 01:00:03 · 464 阅读 · 0 评论 -
5.2 状态机基本概念
例如,在微波炉的情景中,元素是微波炉(或至少是涉及烹饪的元素集合),状态是该系统的条件,如关闭(Off)、就绪(Ready)、微波烹饪(Microwaving)、门开(DoorOpen)和暂停(Paused)。如果在元素处于不响应特定事件的状态时发生事件,事件将“静默丢弃”,无效果——即状态机只做肯定陈述(“当我处于这个状态并且发生这个事件时,我会做这个”),而不是否定陈述(“如果我不在这个状态或者这个没有发生,那么我会做那个”)。在状态内没有明确处理的事件,在元素处于该状态时发生时会被丢弃。原创 2023-11-21 23:06:06 · 522 阅读 · 0 评论 -
5.4 MERSM状态机
你可以看到TokenizeMultiReceptor为状态机传递的每个事件以及额外的表示每个状态的进入和退出动作的功能都有一个事件接收器。此模式几乎专门应用于同步状态机,因为事件队列通常不解析它们管理的数据的内部内容,因此不知道调用哪个事件接收器(如果有多个的话)。它有两种属性:一种是与状态机的意图相关的(如result),另一种是与状态机的管理相关的(如stateID)。在此模式中,每个从客户端发送的事件都有一个单独的事件接收器。它通常是最简单的,因为每个事件接收器只关注处理单个事件及其关联动作的执行。原创 2023-11-22 01:35:41 · 531 阅读 · 0 评论 -
5.3 SERSM状态机
单一事件接收器模式使用单个事件接收器作为客户端和状态机之间的接口。这个接收器必须能够处理事件类型和随事件传递的数据。这种模式既可以用于同步状态机也可以用于通过事件队列的异步状态机。原创 2023-11-22 01:27:22 · 468 阅读 · 0 评论 -
5.2.1 或状态(OR-States)
值得注意的是,每个抽象层次上都必须有一个默认伪状态,它指示进入该层次时的默认状态。举例来说,家庭报警系统的监控部分中,系统要么处于关闭状态(Off),要么处于启动状态(Armed),不存在其他状态。在这类状态机中,一个对象或实体必须严格只处于它的一个状态中,既不会同时处于多个状态,也不会不处于任何状态。此外,无论系统处于Armed的哪个深层嵌套状态中,当通过evDisarm事件停用系统时,系统都会转换到Off状态。这个转换可以在系统处于Armed状态时激活,无论当前处于哪个嵌套状态。原创 2023-11-21 23:19:00 · 18 阅读 · 0 评论 -
4.3 多任务静态优先级分配:可调度理论分析
整体来看,这个公式用于评估在给定任务的执行时间、周期和阻塞时间的情况下,系统是否有足够的资源来满足所有任务的需求。:这是评估的阈值,是关于任务数 n 的一个函数。:当你将任务的最坏情况执行时间除以它的周期,你得到的是该任务在每个周期内占用 CPU 的比例。这个时间是由于系统中的资源共享和任务之间的交互而产生的,与任务本身的内部计算无关。需要注意的是,阻塞项只涉及到第 n-1 个任务,因为按定义,优先级最低的任务是不会被阻塞的。在具有大量任务的系统中,它可以高效地管理任务的执行,根据它们分配的优先级。原创 2023-11-19 23:21:46 · 24 阅读 · 0 评论 -
4.1 任务识别策略及示例
其中,主要的方式是使用「活动」对象。在这个任务图中,我们可以看到几个活动对象,代表着不同的任务,每个都有其自己的属性,如优先级(Priority)、周期(Period)和截止时间(Deadline),这些属性是任务调度的关键参数。UML类图,它显示了系统中的类(或活动对象)及其属性(如优先级、周期和截止时间),以及这些类之间的关系(例如,哪些类使用信号量进行同步)。在设计实时或嵌入式系统时,考虑这些潜在的缺点并采取相应的补救措施是很重要的,例如引入更灵活的调度策略,或者对非周期性任务使用不同的处理方法。原创 2023-11-19 11:56:34 · 29 阅读 · 0 评论 -
4.1 阻塞与优先级反转
在提供的文件中给出的例子中,出现了一个情况:低优先级任务(任务Z)锁定了资源,然后高优先级任务(任务A)准备运行并立即抢占了任务Z。中间优先级任务占用处理器:由于高优先级任务正在等待资源释放,这时如果有一个或多个中等优先级的任务准备运行,它们将获得处理器的控制权,因为它们的优先级高于低优先级任务,但低于正在等待的高优先级任务。任务Y是次低优先级任务,每800毫秒运行一次,总共运行100毫秒,而任务X是第三低优先级任务,周期为500毫秒,执行时间为80毫秒。当任务Y运行时,任务X准备运行并抢占任务Y。原创 2023-11-19 11:29:16 · 15 阅读 · 0 评论 -
4.1 任务优先级分配
任务优先级分配在任务优先级分配中,重要性和紧迫性是两个关键的原则。它们帮助确定哪些任务应当优先执行,以保证系统的有效和稳定运行。重要性和紧迫性:任务的重要性:这指的是任务对系统整体功能的影响程度。重要性高的任务通常与系统的稳定性、安全性或其他关键功能的执行直接相关。例如,对系统健康状况的监控任务或安全相关的任务通常被认为具有高重要性。任务的紧迫性:这涉及到任务执行的时效性要求。紧迫性高的任务通常与时间限制紧密相关,例如有固定截止时间的任务或需要快速响应的事件。原创 2023-11-19 11:19:35 · 18 阅读 · 0 评论 -
4.1 如何实现任务的并发执行:任务调度策略
单核CPU环境下的伪并发(pseudoconcurrency):在单核CPU中,由于只有一个执行单元,所以在任何给定的时刻只能有一个任务在执行。在采用时间片轮转(time-slicing)或基于优先级的抢占式(priority-based preemptive)调度器的系统中,任务在无限循环中运行,并且当其他任务需要运行时,调度器将中断该任务。多核CPU环境下的并发执行:如果要让任务真正并行地执行,这些任务必须在不同的CPU或多核CPU中的不同核上运行。:当任务数量增加时,这些调度方法的效率会大大降低。原创 2023-11-19 11:14:29 · 21 阅读 · 0 评论 -
4.1 动作、动作序列与任务关系
同步点是并发程序设计中的关键概念,它指的是在程序的执行流程中,不同任务相互协调和同步的特定位置。例如,在一个任务中,程序员可以精确地定义动作A后跟动作B,然后是动作C,这样的顺序是固定的,无需考虑其他任务的动作执行时间或顺序。因为任务可能由不同的处理器或线程并行处理,所以它们开始和结束的具体时刻可能会有所不同,这导致了跨任务的动作执行顺序的不确定性。在不同的任务中,哪个动作先执行通常是不确定的。在并发环境中,任务是独立执行的,它们启动和运行的时间依赖于多种因素,如任务优先级、调度策略和资源可用性。原创 2023-11-19 11:10:30 · 18 阅读 · 0 评论 -
4.1 嵌入式实时操作系统:并发基本概念
并发编程中用于协调任务执行的方法或设计,保证数据一致性和顺序性,Eg:互斥量。:当多个任务访问共享资源,而输出依赖于它们的执行顺序时发生的情况。:高优先级任务因低优先级任务占用所需资源而无法继续执行的情况。:一种调度方式,其中优先级最高的任务可以中断低优先级任务。:任务在设定的期限内完成的属性:在任务截至时间之前完成。:看似同时执行的任务实际上是通过快速切换来实现的。:多任务因等待无法满足的条件而无限期阻塞的情况。:一个动作或动作序列必须完成的特定时间点。:完成一个动作或动作序列所需的时间长度。原创 2023-11-19 10:57:26 · 45 阅读 · 0 评论 -
3.4 C语言`中介者设计模式`
中介者模式是一种设计原则,它用于简化多个组件之间的交互逻辑,通过一个中心化的中介者来协调这些组件的通信。这种模式减少了系统中的耦合,并促进了组件之间的独立性,从而使系统更容易维护和扩展。原创 2023-11-11 13:53:41 · 31 阅读 · 0 评论 -
3.2 C语言硬件代理设计模式
在这种模式下,每个硬件设备通过一个代理类被访问,该类封装了硬件的复杂性,并提供一个与具体硬件实现无关的统一接口。硬件代理模式定义了一种软件设计架构,用于抽象和封装对硬件设备的访问,支持多种通信方式,如串行连接、内存映射、端口映射和无线连接,允许软件通过统一接口与硬件通信。硬件代理模式结构简单,一个硬件代理对应多个客户端,封装了所有公共接口和私有的硬件操作细节,客户端通过代理访问硬件,提高了操作的安全性和简便性。硬件代理模式减少了这种依赖,代理层的存在使得客户端软件对硬件的改动不敏感,降低了维护成本。原创 2023-11-11 02:52:18 · 33 阅读 · 0 评论 -
2.1 C语言设计模式应用: ECG检测设计架构
在这种情况下,TMDQueue 是数据的服务器,为客户端提供服务,而波形显示(WaveformDisplay)、直方图显示(HistogramDisplay)、QRS检测器(QRSDetector)和心律失常检测器(ArrythmiaDetector)是客户端。要实现这一点,必须反转图类图中的关联方向,TMDQueue必须明确知道所有的客户端,以便在数据可用时通知它们。这个结构提供了基本的初始化和清理操作,以及一个设置关联队列的方法,尽管这个方法的具体实现在此文件中没有给出。在这里,它获得了7分的评分。原创 2023-11-10 19:46:46 · 63 阅读 · 0 评论 -
1.2 C 语言CachedQueue
磁盘I/O延迟: 如果 flush 操作涉及到磁盘I/O,并且磁盘操作因为某种原因(如磁盘速度慢、I/O系统负载高)延迟,那么即使 pre_push_queue 被填满并触发了 flush 操作,数据可能仍然不能被及时写入磁盘,导致 pre_push_queue 无法释放空间,而 pre_pop_pre_push_queue 也可能因为没有获得更多的内存空间而保持满状态。如果pre_push_queue已满,则调用 flush 函数,该函数将队列中的所有数据写入到一个文件中,并重置队列以便再次使用。原创 2023-11-07 02:46:29 · 19 阅读 · 0 评论 -
1.2 C语言Queue
QUEUE_SIZE: 定义队列可以容纳的最大元素数。在队列未满时,元素将被插入到头指针当前位置,然后头指针前进到下一个位置(循环移动)。原创 2023-11-06 19:23:38 · 17 阅读 · 0 评论 -
1.2 C语言:嵌入式软件开发-传感器抽象层设计
本文档描述了传感器抽象层的设计和实现需求。该层提供了一个通用的传感器接口和对应的传感器类型实现,如温度传感器。其目的是为不同类型的传感器提供统一的创建、读取、写入和销毁操作接口。为开发人员提供了关于如何实现和使用该传感器抽象层的明确指导,同时确保了代码的质量和系统的可维护性。原创 2023-11-04 23:06:13 · 74 阅读 · 0 评论
分享