架构与设计 之一 C 嵌入式设计模式(Design Patterns for Embedded Systems in C)的学习记录

  时至今日,已经不知道在嵌入式的道路上到底挣扎了多少个岁月,总感觉要“病入膏肓”了。此间总是不时出现一些疑惑:人家搞 Java、搞 C# 的动不动就是什么架构 / 框架的,搞了这么久的的嵌入式,我到底搞了什么?架构 / 框架统统木听说过。。。似乎那些高大上的东西都是针对上层编程的!难道嵌入式就这么 Low 么?
  最近终于静下心来,有功夫拜读 Bruce Powel Douglass 的《Design Patterns for Embedded Systems in C》。在书中发现了不少更加系统化的东西,一些在实际工作中用到的但是不知道其准确定义的东西!但是,也同时发现,好多东西完全看不懂。。。以下内容主要是边读边记录的一些自己感觉有用的知识点,除此之外没有任何意义!此外,在这本书中,作者都是以面向对象的思想来进行举例说明的。如果你是一个纯嵌入式底层人员,对于面向对象可能有些陌生。
  最开始看的是这本书的中文翻译版,但是里面有些翻译看不懂。可能是个人水平太低,还没有理解那些高深的东西吧!而后直接去看了英文原版。因此,该文的学习记录都是基于英文原版的。具体为:英文原版内容都是 英文 +(翻译) 的形式给出,其他内容都是我自己的一些理解。其中有些部分确实不懂,均已 ??处理。

CHAPTER 1 What Is Embedded Programming?

1.1 What’s Special About Embedded Systems?

  我们常说嵌入式系统,那什么是嵌入式系统?作者给出的定义:“a computerized system dedicated to performing a specific set of real-world functions, rather than to providing a generalized computing environment.(一个旨在处理现实世界中的具体功能的计算机系统,而不是提供通用的计算机环境的系统)”。我们生活中常见到的非 PC 参与的计算机系统基本都属于嵌入式系统。
  An important subset of embedded systems are real-time systems(实时系统是嵌入式系统的一个重要子集). Many people have the mistaken impression that “real time” means “real fast” but that is not true(很多人错误的认为“实时”就是“真正的快”,这是不正确的). A real-time system is one in which timeliness constraints must be satisfied for system correctness(实时系统是为了保证系统的正确性而必须满足时效性约束的系统). A common, if simplistic, categorization of real-time systems is into two groups(实时系统可简单的分为两大类). “Hard” real-time systems(“硬”实时系统) are ones in which timeliness constraints are modeled as deadlines, points in time by which the execution of specific actions are required to be complete(完全以时间作为实时性约束条件,时间到之前必须完成指定动作). “Soft” real-time systems(“软”实时系统) are those that are not “hard”; that is, some other(usually stochastic) measure than deadlines is used to determine timeliness(引入除时间限制外的其他实时性约束条件). This may include average throughput(平均吞吐量), average execution time(平均执行时间), maximum burst length(最大脉冲长度), or some other measure. All systems may be modeled as hard real-time systems, but this often results in “over-designing” the system to be faster or have more available resources than is necessary, raising the recurring cost(approximately “manufacturing cost”) of the system.

1.1.1 Embedded Design Constraints

  From the inside, one of the most striking characteristics of embedded systems is severity of their constraints(从内部来看,嵌入式系统的一个显著地特点就是严格的约束条件).
  Reliability, robustness, and safety are other kinds of constraints levied on embedded systems(可靠性、健壮性、安全性是嵌入式系统需要遵循的另一些约束条件).

1.1.3 OS, RTOS, or Bareback?

  在嵌入式系统中,我们可以选择使用操作系统来实现,也可以直接以裸机的形式来实现。嵌入式系统中,经常的系统都是实时操作系统(real-time operating system,RTOS)。实时操作系统(RTOS)是一种用于实时和嵌入式应用的多任务操作系统。
  RTOSs run applications and tasks using one of three basic design schemas(实时操作系统使用三种基本设计模式之一运行应用程序和任务). Event-driven systems handle events as they arise and schedule tasks to handle the processing(事件驱动的系统通过任务调度器来处理出现的多个任务). Most such systems use task priority as a quantitative means by which to determine which task will run if multiple tasks are ready to run(通过任务优先级来决定哪个就绪的任务来运行). Task priorities are most often static(任务优先级通常为静态的)(i.e., specified at design time as such with rate-monotonic scheduling) but some are dynamic(也有动态的), varying the task priorities to account for current operating conditions(such as earliest deadline first scheduling*). The other two approaches to task scheduling implement a “fairness doctrine” either by giving all tasks a periodic time slice in which to run(time-base schemas, such as ***round robin scheduling(轮询调度)***) or by running the task set cyclically(sequence-based schemas, such as cyclic executive scheduling).

1.1.4 Embedded Middleware

  中间件在实际工作中,还是经常用到的!在嵌入式中,RTOS 通常仅仅实现与 RTOS 相关的功能,其他的组件,例如网络协议栈、文件系统等则通常是有其他实现方式的。这行统统都可以称为中间件。

1.1.5 Codevelopment with Hardware

嵌入式系统的开发一个显著的特点就是需要与硬件进行协同开发。任何硬件的变动都可能导致之前设计的软件架构的变动。

1.1.6 Debugging and Testing

  嵌入式系统开发的一个难点就是在指定硬件上进行调试。The state of the art in developing defect-free software is an agile practice known as **test-driven development(TDD)(开发没有缺陷的软件的最先进的方法被称为测试驱动开发(TDD)). In TDD, the unit tests for a piece of software are written simultaneously with, or even slightly before, the software it will verify(在 TDD 中,单元测试程序要与主程序同时编写,甚至提前编写). All too commonly, unit testing is skipped entirely or performed far too late to have any beneficial effect on the software(通常情况下,单元测试被完全跳过,或者执行得太晚,对软件没有任何有益的影响。).
  There are many different kinds of unit tests that can be applied to software in general and embedded software in particular. These include(有许多不同类型的单元测试可以应用于一般的软件,特别是嵌入式软件。具体如下):

  • Functional(功能) – tests the behavior or functionality of a system or system element(测试系统或系统元素的行为或功能)
  • Quality of Service(服务质量) – tests the “performance” of a system or system element, often to measure the performance of the system or element against its performance requirements(测试系统或系统元素的“性能”,通常是根据其性能需求来度量系统或元素的性能)
  • Precondition tests(先决条件) – tests that the behavior of the system or system element is correct in the case that the preconditional invariants are met and in the case that the preconditional invariants are violated(在满足前置条件不变量的情况下以及在违反前置条件不变量的情况下,测试系统或系统元素的行为是否正确)
  • Range(区间) – tests values within a data range(测试数据范围内的值)
  • Statistical(统计) – tests values within a range by selecting them stochastically from a probability density function(PDF) (通过从概率密度函数中随机选择值来测试一定范围内的值(PDF))
  • Boundary(边界) – tests values just at the edges of, just inside, and just outside a data range(测试区间边界内、边界上及边界外的值)
  • Coverage(覆盖率) – tests that all execution paths are executed during a test suite(测试在测试集中执行所有执行路径)
  • Stress(压力) – tests data that exceeds the expected bandwidth of a system or system element
  • Volume(容积) – also known as “load testing(负载测试)” – tests the system with large amounts of data that meet or exceed its design load
  • Fault Seeding(故障播种) – tests in which a fault is intentionally introduced to the system to ensure the system handles it properly(故意将故障引入系统以确保系统正确处理故障的测试)
  • Regression tests(回归测试) – normally a subset of previously passed tests to ensure that modification to a system did not introduce errors into previously correctly functioning systems(通常是先前通过的测试的子集,以确保对系统的修改不会将错误引入先前正确运行的系统)

  即使实在桌面系统(如 Windows)中,测试用例要涵盖以上所有的这些点也是非常困难。在嵌入式平台上就更加困难了。在嵌入式平台我们可以通过以下方式来进行测试:

  • “printf” testing(“printf” 测试) – tests the system by writing to a file or to stdout(通过写入文件或stdout来测试系统)
  • “Test buddies(测试伙伴)” – writing test fixtures that embed the test cases in their own functionality
  • Testing on host(在主机上测试) – performing most of the tests on the host platforms using a host native complier and a critical subset on the target platform using a cross compiler( 在主机平台上使用主机原生编译器执行大多数测试,并在目标平台上使用交叉编译器执行一个关键的子集)
  • Simulating on host(在主机上模拟 ) – simulating the target platform on the host with cross-compiled software and retesting a critical subset on the target with the same object code(使用交叉编译软件在主机上模拟目标平台,并使用相同的目标代码在目标上重新测试一个关键子集)
  • Commercial software testing tools(商业软件测试工具) – using software testing tools, such as TestRT™, LDRA™, or VectorCAST™(使用软件测试工具,如TestRT™,LDRA™ 或 VectorCAST™)
  • Commercial hardware-software integrated tools(商业软硬件集成工具) – this includes tools such as logic analyzers, in-circuit emulators, JTAG-compliant testing tools, and ROM emulators(其中包括逻辑分析仪,在线仿真器,符合 JTAG 标准的测试工具和 ROM 仿真器等工具)

Of the various kinds of tests, performance tests are usually the most difficult to adequately perform(在各种测试中,性能测试通常是最难以充分执行的).

1.2 OO or Structured – It’s Your Choice

Structured programming(结构化编程):Structured programming is a disciplined form of software development that emphasizes two separate and distinct aspects(结构化编程是一种规范的软件开发形式,强调两个独立且不同的方面。).

  • On one hand, functions or procedures form the foundation of behavioral programming(函数和过程形成基本的编程基础)
  • The other side of structured programming is the notion of data structuring(数据的结构化).

OO(面向对象):Object-oriented programming is based on an orthogonal paradigm(面向对象编程是基于正交范式的). Rather than have two separate taxonomies, object-oriented programming has a single one based on the notion of a class(面向对象编程没有两个单独的分类法,而是基于类的概念有一个单独的分类法。).

(1)这本书采用了基于面向对象的编程思想,因此后续章节讲了如何用 C 语言来模拟面向对象的思想。
(2)基本的模拟方法就是用结构体来封装数据和方法(函数指针)
(3)如果想要详细了解C实现面向对象的思想,光看本书这一点章节中的东西是远远不够的!

CHAPTER 2 Embedded Programming with The H a r m o n y T M Harmony^{TM} HarmonyTM for Embedded RealTime Process

  整个第二章主要就是以作者自己搞得 Harmony™ for Embedded RealTime 为例,来讲解如何进行嵌入式系统设计。

2.1.2 What Is a Design Pattern?

  A design pattern is “a generalized solution to a commonly occurring problem.”(设计模式是对经常出现的问题的通解)To be a pattern, the problem must recur often enough to be usefully generalizable and the solution must be general enough to be applied in a wide set of application domains. If it only applies to a single application domain, then it is probably an analysis pattern5. Analysis patterns define ways for organizing problem-specific models and code for a particular application domain.

2.1.3 Basic Structure of Design Patterns

According to Gamma, et. al.6, a pattern has four important aspects:

  • Name:The name provides a “handle” or means to reference the pattern.
  • Purpose:The purpose provides the problem context and the QoS aspects the pattern seeks to optimize. The purpose identifies the kinds of problem contexts where the pattern might be particularly appropriate.
  • Solution:The solution is the pattern itself.
  • Consequences:The consequences are the set of pros and cons of the use of the pattern.

CHAPTER 3 Design Patterns for Accessing Hardware

3.1 Basic Hardware Access Concepts(基本的硬件访问概念)

  整个第三章主要讲了各种访问硬件的设计模式。Probably the most distinguishing property of embedded systems is that they must access hardware directly(嵌入式系统最显著的特性可能是它们必须直接访问硬件). Broadly, software-accessible hardware can be categorized into four kinds – infra­structure, communications, sensors, and actuators(大体上,嵌入式软件可访问的硬件可以分为四类:基础设施、通信、传感器和致动器).

  • 基础设施:Infrastructure hardware refers to the computing infrastructure and devices on which the software is executing(基础设施硬件是指软件正在其上执行的计算基础设施和设备。).
  • 通信:Communications hardware refers to hardware used to facilitate communication between different computing devices, such as standard (nonembedded) computers, other embedded systems,sensors, and actuators(通信硬件是指用于促进不同计算设备之间的通信的硬件,例如标准(非嵌入式)计算机,其他嵌入式系统,传感器和致动器).
  • 传感器:Sensors use electronic, mechanical, or chemical means for monitoring the status of physical phenomena, such as the rate of a heart beat, position of an aircraft, the mass of an object, or the concentration of a chemical(传感器使用电子、机械或化学手段来监测物理现象的状态,例如心跳速率,飞机位置,物体质量或化学物质浓度。).
  • 致动器:Actuators, on the other hand, change the physical state of some real-world element(致动器改变了某些现实世界元素的物理状态). Typical actuators are motors, heaters, generators, pumps, and switches.

  Let’s turn our attention now to a number of design patterns that have proven themselves useful for the manipulation of hardware(开始介绍设计模式). The Hardware Proxy Pattern, discussed next, is an archetypal pattern for the abstraction of hardware for the purpose of encapsulating details that are likely to change from the usage of the information provided to or by the hardware(接下来讨论的硬件代理模式是以封装详细信息为目的的硬件抽象模式的一个比较典型的模式,这里没明白!). The Hardware Adapter Pattern extends the Hardware Proxy Pattern to provide the ability to support different hardware interfaces(硬件适配模式主要是扩展硬件代理抹模式,以提供支持不同硬件接口的能力). The Mediator Pattern supports coordination of multiple hardware devices to achieve a system level behavior(中介模式支持多个硬件设备的协调以实现系统级行为). The Observer Pattern is a way of distributing sensed data to the software elements that need it(观察者模式是将感测数据分发给需要它的软件元素的一种方式). The Debouncing and Interrupt Patterns are simple reusable approaches to interface with hardware devices(去抖动和中断模式是与硬件设备接口的简单可重用方法). The Timer Interrupt Pattern extends the Interrupt timer to provide accurate timing for embedded systems(定时器中断模式扩展了中断定时器,为嵌入式系统提供准确的定时).

3.2 Hardware Proxy Pattern(硬件代理模式)

  The Hardware Proxy Pattern creates a software element responsible for access to a piece of hardware and encapsulation of hardware compression and coding implementation(硬件代理模式创建一个软件元素,负责访问硬件并封装硬件压缩和编码实现).

3.3 Hardware Adapter Pattern(硬件适配模式)

The Hardware Adapter Pattern provides a way of adapting an existing hardware interface into the expectations of the application. This pattern is a straightforward derivative of the Adapter Pattern(硬件适配器模式提供了一种使现有硬件接口适应应用程序期望的方法。 此模式是适配器模式的直接派生).

3.3.7 Related Patterns

  The Hardware Adapter Pattern extends the Hardware Proxy Pattern to provide the ability to support different hardware interfaces(硬件适配器模式扩展了硬件代理模式,以提供支持不同硬件接口的能力). The implementation of the Hardware Proxy and the Hardware Adapter can be merged, but that undermines the reusability of the Hardware Proxy(硬件代理和硬件适配器的实现可以合并,但是这会破坏硬件代理的可重用性).

3.4 Mediator Pattern(中介者模式)

  The Mediator Pattern provides a means of coordinating a complex interaction among a set of elements(中介模式提供了一种协调一组元素之间复杂交互的方法).
  The Mediator Pattern supports coordination of multiple hardware devices to achieve a system level behavior(中介模式支持多个硬件设备之间的协调,以实现系统级行为).

3.4.3 Pattern Structure

The Mediator Pattern uses a mediator class to coordinate the actions of a set of collaborating devices to achieve the desired overall effect(中介模式使用中介类来协调一组协作设备的操作,以达到预期的总体效果。). The Mediator class coordinates the control of the set of multiple Specific Collaborators (their number is indicated by the ‘*’ multiplicity on the association between the Mediator and the Specific Collaborator in Figure 3-5). Each Specific Collaborator must be able to contact the Mediator when an event of interest occurs.
架构与设计 之一 C 嵌入式设计模式(Design Patterns for Embedded Systems in C)的学习记录_第1张图片

3.5 Observer Pattern(观察者模式)

  The Observer Pattern is a way of distributing sensed data to the software elements that need it.
  The Observer Pattern is one of the most common patterns around. When present, it provides a means for objects to “listen in” on others while requiring no modifications whatsoever to the data servers. In the embedded domain, this means that sensor data can be easily shared to elements that may not even exist when the sensor proxies are written.

Debouncing Pattern(去抖模式)

  This simple pattern is used to reject multiple false events arising from intermittent contact of metal surfaces.
  Push buttons, toggle switches, and electromechanical relays are input devices for digital systems that share a common problem – as metal connections make contact, the metal deforms or “bounces”, producing intermittent connections during switch open or closure. Since this happens very slowly(order of milliseconds) compared to the response speed of embedded systems(order of microseconds or faster), this results in multiple electronic signals to the control system. This pattern addresses this concern by reducing the multiple signals into a single one by waiting a period of time after the initial signal and then checking the state(嵌入式的许多输入设备,例如按键、开关等受制于物理限制,其响应速度与嵌入式设备处理速度不是一个数量级)
![按键](https://img-blog.csdn.net/20180618110836660?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1pDU2hvdUNTRE4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
![去抖模式](https://img-blog.csdn.net/20180618110848887?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1pDU2hvdUNTRE4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

Interrupt Pattern(中断模式)

  The physical world is fundamentally both concurrent and asynchronous; it’s nonlinear too, but that’s a different story. Things happen when they happen and if your embedded system isn’t paying attention, those occurrences may be lost. Interrupt handlers(a.k.a. Interrupt Service Routines, or ISRs) are a useful way to be notified when an event of interest occurs even if your embedded system is off doing other processing.
![中断模式](https://img-blog.csdn.net/20180618110244360?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1pDU2hvdUNTRE4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

Polling Pattern(轮询模式)

  Another common pattern for getting sensor data or signals from hardware is to check periodi­cally, a process known as polling(通过周期性访问来获取数据,即为轮询). Polling is useful when the data or signals are not so urgent that they cannot wait until the next polling period to be received or when the hardware isn’t capable of generating interrupts when data or signals become available(非紧急性数据或没有中断时,该模式非常有用!).
  This pattern comes in two flavors(这个模式有两种版本). Figure 3-17 shows the pattern structure for opportunistic polling(机会轮询) while Figure 3-18 shows the pattern for periodic polling(周期轮询). The difference is that in the former pattern the applicationFunction will embed calls to poll() when convenient, and in the latter, a timer is created to start polling(区别是:前者是在何时的实际去轮询,而后者则是在定时器中轮询).
![机会轮询](https://img-blog.csdn.net/20180618105836589?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1pDU2hvdUNTRE4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
![定时轮询](https://img-blog.csdn.net/20180618105850441?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1pDU2hvdUNTRE4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
  Periodic polling is a special case of the Interrupt Pattern(周期轮序时中断模式的一个特殊情况). In addition, the hardware checks may be done by invoking data acquisition services of Hardware Proxies or Hardware Adapters. In addition, the Observer Pattern can be merged in as well, with the polling element(Opportu­nisticPoller or PeriodicPoller) serving as the data server and the PollDataClients serving as the data clients.

CHAPTER 4 Design Patterns for Embedding Concurrency and Resource Management

先跳过,看看后面的状态机

CHAPTER 5 Design Patterns for State Machines

5.1 Oh Behave!

  Behavior can be defined as a change in condition or value over time(行为可以定义为条件或值随时间的变化). It is often a response to an external event or request, but autonomous systems decide for themselves when and how to behave(它通常是对外部事件或请求的响应,但自治系统自行决定何时以及如何表现。). 本书中将行为分为四类:

  • 简单行为: Simple behavior is behavior independent of any history of the object or system(简单行为是与对象或系统的任何历史无关的行为). 书中给出的例子是:计算 cos(π / 4)
  • 连续行为: Continuous behavior, on the other hand, does rely upon the history of the object or system(另一方面,连续行为确实依赖于对象或系统的历史。). 书中给出的例子是:移动平均数字滤波器的计算 和 比例积分微分(Proportional Integral-Differential,PID)如下图:
    架构与设计 之一 C 嵌入式设计模式(Design Patterns for Embedded Systems in C)的学习记录_第2张图片
  • 状态行为(不连续行为): The third kind of behavior, to which this is dedicated, is discontinuous or stateful behavior(第三种行为是不连续的行为或者称为状态行为。).In stateful systems. the behavior depends on the new data (typically incoming events of interest) and the current state of the system, which are determined by that system’s history(在有状态系统中, 行为取决于新数据(通常是感兴趣的传入事件)并且系统的当前状态由系统的历史决定). However, the difference is the kind of actions the system performs not the value of the outputs( 但是,不同之处在于系统执行的操作类型而不是输出值。).本书中给出的例子是微波炉状态机,如下图:
    架构与设计 之一 C 嵌入式设计模式(Design Patterns for Embedded Systems in C)的学习记录_第3张图片
    The state machine may also be visualized as a state x transition table(状态机也可以可视化为状态x转换表),如下图:
    架构与设计 之一 C 嵌入式设计模式(Design Patterns for Embedded Systems in C)的学习记录_第4张图片
  • 分段连续行为: Lastly, the fourth type of behavior is a combination of the previous two, known as piece-wise continuous behavior (see Figure 5.3)(最后,第四种行为是前两种行为的组合,称为分段连续行为(见图5.3)。). In PC behavior, within a state, continuous (and, for that matter, simple) the behaviors that occur are of the same kind, but between states, different kinds of behaviors occur. A simple example of this is using different sets of differential equations depending on the state of the system.

5.2 Basic State Machine Concepts(基本状态机概念)

  A Finite State Machine(FSM) is a directed graph composed of three primary elements: states, transitions, and actions(有限状态机(FSM)是由三个主要元素组成的有向图:状态,转换和动作). A state is a condition of a system or element(usually a class in an object-oriented system)(状态是系统或元素的状态(通常是面向对象系统中的类)).
架构与设计 之一 C 嵌入式设计模式(Design Patterns for Embedded Systems in C)的学习记录_第5张图片
  A transition is a path from one state to another, usually initiated by an event of interest(转换是从一个状态到另一个状态的路径,通常由感兴趣的事件启动); it connects a predecessor state with a subsequent state when the element is in the predecessor state and receives the triggering event.
  The actual behaviors executed by the element are represented in actions(实际的动作通过代表动作的元素来执行).

5.3 Single Event Receptor Pattern

  Single event receptor state machines(henceforth known as SERSMs,单事件接收器状态机) can be used for both synchronous and asynchronous events(同时用于同步事件和异步事件).

5.4 Multiple Event Receptor Pattern

  Multiple event receptor finite state machines(MERSMs,多事件接收器状态机) are generally only used for synchro­nous state machines(通常用于同步事件状态机) because the client is often aware of the set of events that it might want to send to the server state machine. In this pattern, there is a single event receptor for each event sent from the client.

未完待续。。。。

你可能感兴趣的:(架构与设计)