如何在不增加太多开销和复杂性的情况下使嵌入式C代码免受需求变化的影响?

guz*_*elo 9 c embedded requirements

在许多嵌入式应用程序中,需要在使代码非常高效或将代码与特定系统配置隔离以免受不断变化的需求之间进行权衡.

您通常采用哪种C构造来实现两全其美(灵活性和可重新配置而不会降低效率)?

如果你有时间,请继续阅读,看看我在说什么.

当我为安全气囊控制器开发嵌入式软件时,我们遇到的问题是,每当客户改变他们对特定要求的想法时,我们就必须更改代码的某些部分.例如,在开发期间每隔几周就会发生触发安全气囊展开的条件和事件的组合.我们讨厌经常改变这段代码.

那时,我参加了嵌入式系统大会,并听取了Stephen Mellor的精彩演讲,题为"应对不断变化的需求".你可以在这里阅读论文(它们会让你注册,但它是免费的).

这样做的主要思想是在代码中实现核心行为,但以数据的形式配置特定的细节.数据可以轻松更改,甚至可以在EEPROM或闪存的不同部分进行编程.

这个想法对于解决我们的问题听起来很棒.我和我的同事分享了这个,我们立即开始重新设计一些软件模块.

当我们在编码中尝试使用这个想法时,我们在实际实现中遇到了一些困难.对于受约束的嵌入式系统,我们的代码构造非常繁重且复杂.

为了说明这一点,我将详细说明上面提到的例子.我们没有使用一堆if语句来决定输入组合是否处于需要安全气囊展开的状态,而是改为大表.有些条件不是很简单,所以我们使用了很多函数指针来调用许多小助手函数,这些函数以某种方式解决了一些条件.我们有几个层次的间接,一切都变得难以理解.总而言之,我们最终使用了大量的内存,运行时和代码复杂性.调试这个东西也不简单.老板让我们改变了一些东西,因为模块太重了(他可能是对的!).

PS:在SO中有一个类似的问题,但看起来焦点是不同的.适应不断变化的业务需求?

Aid*_*ell 3

作为改变需求的另一种观点……需求涉及到构建代码。那么为什么不采取元方法来解决这个问题:

  1. 分离出程序中可能改变的部分
  2. 创建一个将源代码的各个部分粘合在一起的脚本

通过这种方式,您可以在 C 中维护兼容的逻辑构建块……然后最后将这些兼容的部分粘在一起:

/* {conditions_for_airbag_placeholder} */
if( require_deployment)
     trigger_gas_release()
Run Code Online (Sandbox Code Playgroud)

然后保持独立条件:

/* VAG Condition */
if( poll_vag_collision_event() )
    require_deployment=1
Run Code Online (Sandbox Code Playgroud)

和另一个

/* Ford Conditions */
if( ford_interrupt( FRONT_NEARSIDE_COLLISION )) 
    require_deploymen=1
Run Code Online (Sandbox Code Playgroud)

您的构建脚本可能如下所示:

BUILD airbag_deployment_logic.c WITH vag_events
TEST airbag_deployment_blob WITH vag_event_emitter
Run Code Online (Sandbox Code Playgroud)

真的想大声说出来。这样你就可以得到一个紧凑的二进制 blob,而无需读取 config。这有点像使用覆盖 http://en.wikipedia.org/wiki/Overlay_(programming)但在编译时执行。