许多嵌入式软件系统问题的优雅解决方案是利用以数据为中心的软件设计。在嵌入式开发中,数据是每个嵌入式系统的核心。首先,通过采样传感器、通信接口和输入/输出设备获取数据。接下来,数据被转换、过滤并处理成系统中的新数据资产。最后,对这些数据进行处理以生成输出。以下是以数据为中心的软件设计的三个技巧。
技巧1——遵循数据
每个软件系统的核心都是以数据为中心的。设计有效且高效的软件架构和实现必须遵循这些数据。不幸的是,数据在软件系统中能做的事情是有限的。
首先,产生数据。例如,在嵌入式系统中,可能有一个模拟传感器产生由微控制器内部模数转换器测量的电压。触摸屏输入可以中断并提供x/y坐标对。数据通常作为系统的输入或输出产生。以数据为中心的软件设计会仔细识别输入和输出,因为这是我们可以找到产生的数据的地方。
接下来,处理数据。我们刚刚提到的产生ADC计数的模数转换是原始形式。可以对传感器数据进行处理,以创建表示传感器科学单位的浮点数值。通常,更常见的是以原始形式保留传感器值,但对数据进行过滤。例如,数据可以具有低通或高通滤波器以去除噪声。嵌入式开发人员需要跟踪数据,了解数据是如何处理的。
最后,存储数据。数据可能作为单个值存储在内存中。数据可以存储在将被一起处理的值的数组中。数据可以保存到非易失性存储器中以备后用。同样,理解数据如何存储对设计过程至关重要。
是传感器还是通信接口产生数据并不重要。无论你是将其存储在SD卡还是存储芯片上,都没有关系。从设计的角度来看,我们关心数据从哪里进入和离开系统(产生)、被处理,然后最终被存储。要创建一个有效的软件设计,你必须遵循数据,记录每种状态下的数据及其转换方式,如果你这样做了,你会发现这个设计自然而然就到位了。
技巧2——记录数据是如何变化的
在每个系统中,原始数据被传输并转换成有价值的数据,然后输出。嵌入式开发人员跟踪数据如何在系统中流动可以很好地驱动软件架构;然而,记录数据如何在整个系统中变化和发展可以帮助设计者确定软件的规模。
例如,如果将一些模拟传感器数据转换成数字并显示在遥测数据中,不需要太多处理能力。数据处理简单。但是,如果检索传感器数据,将其存储在循环缓冲区中,进行过滤,然后转换为科学单位。记录数据流和处理事件有助于设计人员约束和理解他们的设计,即使没有正式的微控制器或硬件被识别。
在设计之初,遵循以下简单步骤:
识别系统中产生的数据
确定每个数据资产如何在软件中移动
记录数据在其整个生命周期中如何变化
记录任何存储介质以及数据是如何被访问的
嵌入式开发人员需要创建一个简单的数据流图可以规定软件架构,并确保它是可伸缩的,而不是过于复杂。
技巧3——在事件或任务开始时对数据采取行动
嵌入式系统中的典型任务将按以下步骤处理信息:
检索新数据
过滤/处理数据
输出结果
这个过程似乎是合乎逻辑的。不幸的是,它不一定适合实时嵌入式系统设计。实时系统的主要目标是确定性和最小化抖动。上述过程会使抖动的可能性最大化,而不是最小化。
举个例子,电机控制任务读入最新的模拟电流和电压测量值,然后通过PID控制器运行。PID控制器将为新的电机状态提供输出。根据控制器的设计,每次通过PID控制器可能不会在相同数量的时钟周期内运行。如果考虑到在PID计算过程中触发中断的可能性,时间值的范围可能会很大。结果是电机输出永远不会同时更新,它会稍微移动和抖动,这可能会影响电机的响应。
嵌入式开发人员最大限度降低抖动的一种更可靠的方法是将步骤改为:
输出以前的结果
检索新数据
过滤/处理数据
在这种情况下,新的输出总是在循环开始时,在进一步处理或其他不确定性活动发生之前发送到电机。因此,我们正在对可能稍旧的数据采取行动,但我们可以考虑这一点,并大幅降低我们的抖动。
结论
当你分解我们为设计和实现嵌入式软件所做的工作时,一切都归结于数据。嵌入式软件只不过是以一种确定的方式集体处理、存储和输出数据。嵌入式开发人员遵循以数据为中心的软件设计方法将会产生一个突出数据最重要的部分的架构。你会发现这个设计是高效的,有效的,并且不会被现代的设计模式和填充物所膨胀。想要一个优秀的软件设计,跟着数据走就行了。