2.1 构建系统框图
正如硬件设计师需要设计电路原理图一样,我们也应该设计一系列的软件框图来描述软件系统各个不同部分之间的关系。这些框图会让我们对系统有全局的了解,有助于我们定义各个部分之间的相互依赖关系,并且为新功能的设计提供指导。
推荐三种不同的框图:
架构框图
控制层级图
软件层次视图
2.1.1 架构框图
在开始阶段,设计是直观的,因为这个时候面对的是系统的硬件组件,并且可以用面向对象的思维去对硬件组件进行建模,而不管是否使用面向对象的编程语言。连接到处理器的每个芯片都是个对象,连接芯片和处理器之间的线(通信方法)也可以作为另外一组对象。
你可以把这些对象划成一个一个的方框,以此作为设计的起点。将芯片画在中心,通信对象画在处理器里,然后将其他外设一个一个地连接到这些对象上。
举个例子,这里我要介绍一种称为闪存的存储器。撇开其细节不谈,它是一个在很多设备中被广泛使用的一种相对便宜的存储器。大多数闪存芯片都通过SPI总线通信(SPI是一种串行通信,后面会详细讨论)。它通常用做片外部存储器,因为大部分处理器都无法通过SPI接口在闪存上执行代码。图2-1上半部分的原理图展示了如何将闪存通过SPI连接到处理器。
在我们的软件框图中,我们将闪存作为外设(处理器外面的一个方框),在处理器内部增加一个表示SPI的方框,这意味着我们需要写一些驱动SPI的代码。这个时候,我们的软件框图看起来和硬件原理图很相似,但随着我们逐渐加入更多的软件组件,就会慢慢变得不同了。
下一步在处理器内部增加一个表示闪存的方框,提示我们需要写一些驱动闪存的代码。将通信方式和外设分离开来是有益的。如果有多个芯片通过同样的通信方式连接到处理器,那么它们就应该连接到处理器内部同一个通信模块上。这时候,框图就会提醒我们对于共享资源需要格外小心,需要我们考虑共享带来的性能和资源冲突问题。

图2-1展示了在画软件框图时的一部分电气原理图。注意这个原理图是非常粗略的。这个时候,我们需要在更高的层面上去了解系统以便决定我们需要构造哪些对象以及这些对象如何相互配合。将细节部分铭记于心,特别是那些有系统级有影响的,但只要有可能,不要把这些细节画在框图上。

图2-1:原理图和初始软件框图的对比
下一个阶段就是增加一些高层功能。每个外设芯片是做什么用的?如果每个芯片只有一个功能,那就简单了。例如,如果将闪存用做存储位图图片以便在屏幕上显示,我们就可以在架构框图上画一个方框表示显示数据。这时候没有片外组件,因此这个方框置于处理器内部。我们还需要画上一些方框来表示屏幕与屏幕的通信方式,和另一个方框表示将基于闪存的显示数据转换到屏幕。这个时候,多画些功能框比少画好,后面我们会合并它们。
可以将能够想到的其他一些软件构件加到框图上,如数据库、缓存系统、命令处理程序、算法、状态机等。这个时候,可能不是很确切地知道自己是否需要这些(本书的后继章节会对其中一些内容深入讨论),但请试着将从硬件到产品功能的所有东西都表达在框图上,如图2-2所示。
当在一张纸或者白板上画下这个框图后(因为图不够大或者位置不对,可能会经过多次反复),不要以为已经做得足够好了,还有另外一张图会给我们更多的启发。
从多个不同的角度看,你会发现一些隐藏的、不完善的问题点,如关键瓶颈、没有充分理解的需求,或者在这个平台上设计实现产品时会带来一些不可避免的缺陷。通常,这些不足只能从某个角度才能发现,或者当它们出现在不同的框图中时发生了很大的变化。当从恰当的角度去看这些问题时,不仅可以找到这些棘手的模块,而且可以找到这些问题的解决之道。

图2-2:软件框图
2.1.2 控制层级图
另一种软件架构图看起来有点像组织结构图,如图2-3所示。图2-3中展示了各个相互独立的组件,以及组件之间的调用关系。整个系统就是一个分层的结构,Main是最高层的对象。如果已经知道算法将要如何使用每个组件,就可以在下一个层次画上算法相关的对象。如果认为它们不会再变化,那么就可以从产品相关的特征开始,逐步分解到我们已经知道的对象,将最复杂的放在顶层。然后,画上被高层对象使用的低层次对象。例如,我们的SPI对象会被闪存对象调用,闪存对象又会被显示对象调用,依此类推。还可以加上之前没有考虑到的对象或者组件。同时,还需要决定是否将这些组件增加到架构框图上(很有可能)。


2-3:软件架构的结构框图
虽然,我们总希望一个外设完成一个特定的功能(比如,闪存中的显示资源),但系统的约束(成本、速度等)通常不会支持这样做。因此,我们往往会给一个外设上赋予了多个但并不特别兼容的功能。
在图2-3中可以看到文本组件和图像组件共享闪存驱动程序组件及其下面的SPI驱动程序组件。通常,这种共享是必要的,但对设计来说,这是个红灯,因为需要特别当心以避免资源的冲突,并确保资源在需要的时候可用。幸运的是,图2-3中给出了渲染代码组件,它控制这两个组件,并能够确保在任何一个时刻只有一个组件(文本或者图像)可用,因此在它们之间就不大可能再有冲突发生。
比如,设计团队决定系统需要每个单元有一个序列号。这个序列号会在生产的时候烧录进去并在需要的时候提供。我们可以增加另外一个存储器芯片作为外设,但这会增加成本、电路板的复杂度和软件的复杂度。我们已有的闪存有足够的空间存储这个序列号,因此只需要增加软件的复杂度。
在图2-4中,我们通过闪存打印序列号,而这个闪存之前是用于显示组件。如果日志子系统需要从显示组件异步获取序列号(比如,我们有两个线程或者显示组件使用中断),软件需要避免冲突和由此带来的系统崩溃。

图2-4:共享资源的结构框图
每当此类的组件被加到框图上时,就需要考虑一些正在使用A和B的组件可能会给C组件带来的干扰,系统的健壮性就会变得稍微差点。需要额外注意的地方很难用文档记录。共享资源给设计、实现、维护阶段带来痛苦。这里的例子很容易地就解决了,虽然留着一个红灯标记。但是需要考虑所有的共享资源所带来的最终结果。
2.1.3 层次图
最后一张架构图着重在不同的层次划分,如图2-5所示,用对象预计的大小来表达。这张图也一样可以用铅笔在纸上画出来。从纸的下方开始画出那些逐渐远离处理器的对象(比如,我们的通信模块)。如果估计某个对象实现起来相对比较复杂,那么就把它画得大一点。如果不能确定对象的复杂度,那么就把它们画得一样大。然后,在图中增加调用最底层对象的那些对象。如果同一个底层对象被多个上层对象调用,那么这些调用对象都应该和该底层对象关联(意味着可以把这个被调用对象画大一点)。同样,如果同一个上层对象调用多个底层对象,那么这个上层对象也应该和这些底层对象关联(把它画大一点)。
我说根据对象的复杂度决定其大小,然后又说如果一个对象被多个上层对象调用,那么就把它画大一点。这看起来有点难以理解。在2.1.2节中提到,共享资源会增加复杂性。所以,如果在多个对象之间共享一个资源,但是这些对象却不能同时访问,那么即使这个模块的目的很简单,也会增加其复杂度。在图2-5中,开始的时候我把渲染模块画得很小,因为从闪存中将数据传送到LCD是很简单的事情。但是,后来这个渲染模块还需要控制在它下一层的所有位,就把它画大了。在我摘录这张层次图的项目中,最终结果证明了渲染模块确实要比其他两个模块大。

图2-5:软件层次图
最终,这张层次图会表示出每段代码处在哪个层次,让我们有可能将通常一起使用的资源绑定在一起。比如,LCD和并行I/O对象只在两者之间相互联系,所以在最终的设计图中,可以将这两个模块合并成一个模块。对背光模块和PWM输出模块也可以进行一样的处理。
再看看水平方向模块的分组情况。字体和图像模块共享同样的高层和低层连接,也许应该将它们合并到一个模块中,因为它们有相同的输入和输出。这张图的目的就是找出这些点,并且找出合并模块的不同方法。最后,就会得到一个更简单的设计图。
最后,可能会有同一组中的多个模块访问同一个低层对象,这时候也许应该花些时间把这个资源再分解。如果闪存驱动程序只处理序列号,这样设计有必要吗?可不可以在初始化的时候读出序列号,之后就再也不用重复读它,这样让显示子系统能一直控制闪存?理解设计的复杂度,以及有哪些不同的设计方法去改变这个复杂度相当重要。一个好的设计应该是在实现和维护上既省钱又省时间。

《 嵌入式系统设计与实践》一一2.1 构建系统框图相关推荐

  1. 《 嵌入式系统设计与实践》一一3.6 测试硬件(和软件)

    3.6 测试硬件(和软件) 虽然我强烈建议准备好工具箱.数字万用表和示波器,但是,如果大家没有准备好独自拥有这些,那么将这些留给硬件工程师也在情理之中.作为一个软件工程师,更重要的是将用于测试硬件的软 ...

  2. 在linux下进行嵌入式系统设计,一种应用于测控系统的基于Linux的嵌入式系统的设计...

    描述 1.前言 随着网络控制技术的快速发展,工业以太网得到逐步完善,在工业控制领域获得越来越广泛的应用.工业以太网使用了TCP/IP协议,便于联网,并具有高速控制网络的优点.随着32位嵌入式CPU价格 ...

  3. 嵌入式系统设计与应用

    目录 第一章 嵌入式系统概述 第二章 ARM处理器体系结构 第三章 ARM指令集 第四章 S5PV210处理器 第五章 Linux操作系统和内嵌式汇编 第十章 SQL数据库 第十一章 开发设计案例 第 ...

  4. 【计算机系统设计】实践笔记(2)数据通路构建:第一类R型指令分析(2)

    待办事项 时钟频率高,取指周期长,远大于执行周期,如何处理? 不可综合逻辑的处理 接上一篇 [计算机系统设计]实践笔记(2)数据通路构建:第一类R型指令分析(1) 8.2 ALU运算器 `timesc ...

  5. 【计算机系统设计】实践笔记(2)数据通路构建:第一类R型指令分析(1)

    0 回顾 上一次实践笔记(0)我们实现了一个最简单的,能够每个上升沿+4的PC. 我们最需要关注的就是器件功能的独立性,避免内外功能混杂,同时一定要注意脑中有电路(RTL级描述的抽象电路而不是实际的门 ...

  6. 知乎容器化构建系统设计和实践

    知乎选用 Jenkins 作为构建方案,因其强大和灵活,且有非常丰富的插件可供使用和扩展.早期,应用数量较少时,每个开发者都手动创建并维护着几个 Job,各自编写 Jenkins Job 的配置,以及 ...

  7. 网际风全推数据接口_智能风控系统设计与实践

    导读 在主流互联网产品中,比如搜索和推荐的系统,为了挖掘用户潜在购买需求,缩短用户到商品或信息的距离,提高用户的使用体验,都需要使用大量的特征来刻画用户的行为.在信息安全领域,建立在人工智能技术之上的 ...

  8. 嵌入式系统设计(三):Vim编辑器的学习

    前言: 在接下来的时间里将更新一个专栏:嵌入式系统设计.在这个专栏里将会介绍基于iTOP-4412 Cortex A9开发板的嵌入式系统设计,从入门到实践可以无障碍的学习.欢迎大家关注收藏学习!!!! ...

  9. 嵌入式计算机课程设计,嵌入式系统设计课设报告.doc

    嵌入式系统设计课设报告.doc 福州大学嵌入式系统设计课设报告书题 目 基于28027的虚拟系统 姓 名 学 号 学 院 电气工程与自动化学院 专 业 电气工程与自动化 年 级 起讫日期 指导教师 目 ...

  10. 嵌入式系统设计(一)

    嵌入式系统设计 [课程来源:电子科技大学 陈虹老师 研究生课程 <嵌入式系统设计>] [说明:个人课程笔记,仅供参考] 课程体系: 理论与实践相结合 以嵌入式硬件的核心嵌入式微处理器及嵌入 ...

最新文章

  1. Python学习笔记:异步IO(2)
  2. 08.存储Cinder→4.Cinder组件详解→3.cinder-volume
  3. 浅析C++ Compile-time Assertion技术
  4. java ee监听器编程,java EE开发之Servlet第四课:监听器(Listener)
  5. 助力双十一,促销海报设计模板收好!
  6. TCP/IP and Socket
  7. 增强for循环 泛型
  8. Android的硬件缩放技术优化执行效率 Screen.SetResolution
  9. linux 常用命令
  10. 常见计算机英语词汇翻译,常见计算机英语词汇翻译.doc
  11. HihoCoder - 1370 快乐数字
  12. 1.27(Bomb Game)
  13. JavaSE-饿了么项目实战
  14. dp主机_怎样设置显示器DP接口信号优先?
  15. 【工程/物理光学(二)——几何光学基础与光的成像】
  16. 可爱猫+python3+Flask+aiohttp简单搭建微信机器人
  17. 初学Web前端会用到开发工具【零基础web前端入门视频教程】
  18. c语言编程电机星三角启动,plc控制电机星三角启动梯形图
  19. 芦荟妙用(摘自网络)
  20. Java静态数组和动态数组的定义方式

热门文章

  1. 宠物商店项目mysql_北大青鸟java宠物商店+MySQL数据库
  2. MySQL最全整理!java技术总监面试常见问题及答案
  3. 括号匹配(POJ2955)题解
  4. Linux服务器搭建24小时直播平台
  5. SpringDataJPA使用Specification动态查询和分页
  6. 博途PLC如何通过FB285实现V90 PN的速度控制
  7. Resize operation completed for file#
  8. 登陆apple pay显示无法登录服务器,apple pay无法添加卡怎么办?未能连接到apple pay的解决方法...
  9. STM32按键总结(低电平有效及上升沿有效)
  10. chromium编译android,Ubuntu下编译Chromium for Android