C 嵌入式系统设计模式 08:硬件代理模式

这篇具有很好参考价值的文章主要介绍了C 嵌入式系统设计模式 08:硬件代理模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

本系列描述我对书中内容的理解。本文章描述访问硬件的设计模式之一:硬件代理模式。

硬件代理模式 (Hardware Proxy Pattern) 是硬件抽象的典型模式。目的是封装细节。该模式通过创建软件模块来封装对特定硬件设备的操作,隐藏底层硬件的实现细节和复杂性,提供标准的接口给上层应用程序使用。

假设有一个嵌入式系统需要访问内存、传感器等硬件设备。如果每个应用都直接在程序中访问操作底层硬件,当更换了相同功能的不同硬件设备时,有可能硬件接口并不一致,而且对硬件的操作与控制方式也并不一样。这种情况下,就需要为每个硬件设备编写特定的访问代码,增加了软件开发的复杂性和工作量。

而采用硬件代理模式后,可以创建一个硬件代理来封装对内存、传感器等硬件设备的操作。应用程序通过调用硬件代理提供的标准接口来访问硬件设备,无需关心底层硬件的具体实现。当更换了相同功能的不同硬件设备时,只需要修改硬件代理的实现即可,无需修改客户程序的代码。这样就简化了软件与硬件的交互过程,提高了软件的可移植性和可维护性。

在这个过程中,最难的是定义一系列标准接口。标准接口是对硬件的抽象,而只要涉及到抽象,大都伴随艰难的脑力劳动。一个好的接口,能带来什么益处?答案是稳定。硬件可能随时会变,但好的接口通常不变,它比硬件要稳定。因此在接口之上的应用层,都不用变。这就将变化控制在硬件层这个狭小的范围内,从而让变更变得容易和可控。

抽象

硬件代理模式使用类或结构体来封装对硬件设备的所有访问,而不管其物理接口如何。硬件可以是内存、中断映射,也可以是通过总线、网络连接的设备。硬件代理提供一些服务,这些服务可以与硬件设备交互:初始化、配置、关闭、读写数据等。硬件代理为上层应用提供了一个与编码和连接无关的接口,因此如果硬件设备接口或者连接方式发生变化,则可以方便的修改现有代码。

问题

如果每个上层应用(书中称为“客户端” )都直接访问硬件设备,则由于硬件更改而导致的问题会加剧。比如数据编码方式、内存地址或连接方式发生变化,则必须跟踪并修改每一个上层应用。通过提供位于上层应用和硬件之间的代理,可以极大的减少硬件更改带来的影响。为了便于维护,高层应用不应该知道底层次代码的细节,包括数据编码方式、加密方式、压缩方式等。这些详细信息应由具有内部私有函数的硬件代理进行管理。

模式结构

模式结构见下图。
C 嵌入式系统设计模式 08:硬件代理模式,读书笔记,# C 嵌入式系统设计模式,c语言,设计模式,网络

硬件代理客户端可能有多个,但是硬件设备只有 1 个硬件代理。硬件代理具有公共函数和私有的函数和数据。在 UML 图中,数据放在首部,比如 deviceAddr: void *,函数放在数据的下方,比如 initialize():void;公用函数和数据使用正常字体,私有函数和数据用带下划线的斜体。

模式详情

硬件设备

硬件设备 是一个具体的硬件实体,它本身无需编程即可运作。把它放到图中,只是为了便于理解模式结构。硬件代理硬件设备 之间的 关联 是通过硬件接口实现的,这些接口可以是一个寄存器地址或其他类似机制。关联关系使一个类知道另外一个类的属性和方法,这里硬件代理与硬件设备是双向关联,大家相互知道对方的细节。

硬件代理

硬件代理封装了针对特定硬件的数据和函数,为每种硬件设备提供了一套统一的接口。通常每个硬件都会有 initialize()configure()disable() 等基本操作函数,此外,硬件代理还提供了一组公共函数,用于对硬件进行读写访问。

尽管模式结构图中只标识出一个 access()mutate() 函数,但实际应用中通常有多个这样的函数,每个函数都针对特定的读写目标,具有明确的语义和用途。例如,accessMotorSpeed() 函数用于读取电机的速度,而 accessMotorDirection() 函数则用于读取电机的旋转方向。

这种设计方式使得上层应用程序(客户端)可以通过调用硬件代理提供的函数来与硬件进行交互,而无需关心底层硬件的具体实现细节。这不仅简化了软件与硬件之间的交互过程,还提高了软件的可移植性和可维护性。

硬件代理关键函数和数据为:

  1. initialize():在首次使用之前调用,初始化设备。
  2. configure():用于配置硬件设备。
  3. disable():关闭或禁用硬件设备。
  4. access_xxx():从硬件设备读取数据。但在实际编程中,更常见的做法是使用get_xxx()
  5. mutate_xxx():向硬件设备写入数据。但在实际编程中,更常见的做法是使用set_xxx()

在编程和软件设计中,函数名通常会给出关于函数功能的一些提示。accessmutate 这两个名字就很有代表性,它们分别暗示了读取(或访问)数据和修改(或变更)数据的操作。

  • access 函数通常用于读取或检索数据,但不修改它。例如,在数据库编程中,一个 access 函数可能是用来从数据库表中读取记录的。在对象导向编程中,access 方法(也称为 getter 方法)可能用于读取对象的某个属性值。
  • mutate 函数则用于修改或变更数据。在数据库编程中,这可能意味着更新数据库表中的记录。在对象导向编程中,mutate 方法(也称为 setter 方法)可能用于设置或修改对象的某个属性值。
  1. marshal():私有函数。将上层应用的数据格式转换成硬件可以理解的数据格式。可能需要加密、压缩或打包。这确保了硬件设备接口的特殊性对上层应用(客户端)是隐藏的。实际硬件设备所需格式的数据被称为“原生格式”数据。容易被软件操作的数据被称为“呈现格式”数据。由于原生格式对上层应用是隐藏的,因此上层应用无法访问此函数。

通过将数据处理和转换的逻辑封装在私有函数中,软件设计可以确保上层应用代码与硬件设备接口的复杂性隔离开来。这样,上层应用开发者只需要关心如何操作 呈现格式 的数据,而不需要了解如何将这些数据转换为硬件设备能理解的 原生格式。这简化了上层应用的开发工作,并提高了系统的可维护性。

  1. unmarshal():私有函数。将硬件数据转换成上层应用可以理解的数据格式。可能需要解密、解压缩或解包。也就是将原生格式数据转换成呈现格式数据。与 marshal() 函数一样,隐藏了硬件设备的细节,因此上层应用无法访问此函数。
  2. deviceAddr:私有变量。提供了对硬件的低层次直接访问。在代理模式中,它显示为 void* ,但它可能是一个整形( int* )或其它数据类型。如果使用了更复杂的方式来访问设备,如 RS232 串行端口或以太网连接,那么这个数据类型及其访问方法将更加复杂。无论如何,硬件代理提供的公共函数完全隐藏了代理如何连接到实际硬件设备的过程。上层应用无法直接访问这个变量。

代理客户端

也就是使用硬件代理的上层应用。上层应用知道硬件代理的公用函数和数据,然后调用这些服务来访问硬件设备。

结果

这种模式非常常见,它提供了封装硬件接口和编码细节的所有好处。它为实际的硬件接口提供了灵活性,使其可以在不改变上层应用代码的情况下变更硬件。这是因为硬件细节都封装在硬件代理中。这意味着上层应用通常不知道数据的原生格式,而只以呈现格式操作它们。

然而,这可能会对运行时性能产生负面影响。有时,让上层应用了解编码细节并以原生格式操作数据可能更高效。但是,这会降低系统的可维护性,因为如果硬件接口或编码发生变化,就需要修改上层应用。

实现策略

如第1章所述,在 C 语言中,类可以通过不同的方式实现,从简单的文件到使用结构体来存储类属性,再到使用支持真正多态性的虚函数表。所有这些方法都可以用来实现这个非常简单的模式。

通常,一个硬件代理支持特定设备的所有功能,并且每个独立的设备都使用一个不同的硬件代理,但这并不是一条绝对的规则。将设备分离成不同的部分意味着这些设备可以遵循独立的维护路径,因此对于未来来说非常灵活。

一般来说,最好将实际硬件的位编码、加密和数据压缩隐藏在上层应用之外。然而,也可以通过使原生格式对上层应用可见来实现该模式,在在这种情况下,无需使用 marshal()unmarshal() 函数。

实例

见原书。文章来源地址https://www.toymoban.com/news/detail-834043.html

到了这里,关于C 嵌入式系统设计模式 08:硬件代理模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【新版】系统架构设计师 - 嵌入式技术

    个人总结,仅供参考,欢迎加好友一起讨论 嵌入式系统概述(★) 嵌入式系统开发与设计(★) 嵌入式硬件(★★) 嵌入式操作系统(★★★★) 嵌入式数据库(★) 嵌入式系统是一种以应用为中心,以计算机技术为基础,可以适应不同应用对功能、可靠性、成本、体积

    2024年02月09日
    浏览(41)
  • ARM简单程序设计【嵌入式系统】

    2023-4-6 20:26:54 以下内容源自《【嵌入式系统】》 仅供学习交流使用 Keil 4 安装教程及简单使用【嵌入式系统】 新建工程xxx 芯片:ARM7 (Little Endian) 设置工程属性 Build结果必须是0Error的 如果是下图看配置是否正确 注意这个: 1.每一次修改代码就需要重写Build 2.READWRITE区变量初始

    2023年04月20日
    浏览(45)
  • 嵌入式系统课程设计——温度记录仪

    课程设计目录 一、嵌入式系统基础实验  二、项目需求分析 三、实验方案设计 四、实验程序设计  五、成本核算情况 八、完成情况与问题分析 九、学习心得 一、嵌入式系统基础实验 1.1实验平台的使用 图1 建立新工程图片 图2 选择lpc1114芯片图片 图3 选择头文件图片 图4 编

    2024年02月10日
    浏览(37)
  • 毕业设计 嵌入式 扫地机器人系统

    Hi,大家好,学长今天向大家介绍一个 单片机项目,大家可用于 课程设计 或 毕业设计 基于stm32的智能扫地机器人设计与实现 随着人口老龄化的到来和人民对提升生活品质的需要, 人们对在现实生活场景中取代人力的服务机器人有着迫切的需要。 同时, 机电、 自动控制、

    2024年02月11日
    浏览(37)
  • 嵌入式系统项目设计——电子琴(完整代码)

    内容摘自上学期嵌入式系统课程设计最终的实验报告,我作为小组组长负责代码部分的编写,与上一个实验相比,使用了相同的硬件,所以硬件示意图完全相同,实现的功能不同但原理类似。因为CSDN不支持上传word资料,所以我就摘录下来写进文章里了,希望可以帮助到你。

    2024年02月08日
    浏览(34)
  • 嵌入式室内环境参数监控系统设计

    本次课设要求学生们掌握四个方面,第一是文献检索及实验研究方法,第二是室内环境监控系统一般组成; 第三是掌握技术方案比选方法;最后是掌握STM32 ADC使用,同时本次课设需要做到以下几个方面: 了解国内室内环境参数监控系统组成及技术架构; 设计室内环境参数监

    2024年01月18日
    浏览(33)
  • 嵌入式实时操作系统的设计与开发

    在RTOS中,时钟具有非常重要的作用,通过时钟可实现延时任务、周期性触发任务执行、任务有限等待的计时。 大多数嵌入式系统有两种时钟源,分别为实时时钟RTC(Real-Time Clock)和定时器/计数器。 实时时钟一般是靠电池供电,即使系统断电,也可以维持日期和时间。由于实

    2024年02月11日
    浏览(29)
  • 面向城乡公交的嵌入式系统远程升级设计方案

    针对城乡公交站牌显示终端现场升级与维护困难的问题,提出了一种基于应用程序(IAP)技术的嵌入式系统远程升级设计方案。 通过IAP技术配合改良过的远程升级程序代替传统的现场烧写调试,节约了奔赴现场调试的时间和成本。 针对远程升级过程中被恶意攻击、固件文件

    2024年02月14日
    浏览(32)
  • 基于IAP的嵌入式系统在线编程设计(学习)

    摘要:为了实现嵌入式系统程序的在线升级,提出一种基于IAP在线编程的程序更新方法。 以STM32L431控制器为例,该方法对控制器的片内FLASH进行区域划分,分别存放引导程序、执行程序及待更新程序。 系统通过运行引导程序将待更新程序更新到执行程序的FLASH区域,程序更新

    2024年02月15日
    浏览(40)
  • 嵌入式实时操作系统的设计与开发(一)

    以一款简单、易学的嵌入式开发平台ARM Mini2440(CPU是三星ARM 9系列的ARM S3C2440)为例,通过具体代码实现,介绍如何从裸板入手设计简单的轮询系统、前后台系统,以及如何一步一步在ARM Mini2440上编写RTOS内核,到如何让RTOS内核支持多核嵌入式处理器。 aCoral是2009年创建的开源

    2024年02月12日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包