背景:
我们正在为新的嵌入式系统建模固件。目前固件正在 UML 中建模,但不会使用 UML 建模工具的代码生成功能。
目标语言是 C(具体来说是 C99)。
低功耗(即性能、快速执行)和正确性很重要,但正确性是重中之重,高于一切,包括代码大小和执行速度。
在对系统建模时,我们已经确定了一组定义明确的组件。每个组件都有自己的接口,并且许多组件与许多组件交互。
模型中的大多数组件将是实时操作系统 (RTOS) 下的单个任务(线程),尽管有些组件只不过是库。任务完全通过消息传递/队列发布相互通信。与库的交互将以同步函数调用的形式进行。
因为建议/建议可能取决于规模,所以我将提供一些信息。现在可能有大约 12-15 个组件,可能会增长到大约 20 个?不是 100 多个组件。假设平均而言,每个组件与 25% 的其他组件交互。
在组件图中,有端口/连接器用于表示组件之间的接口,即一个组件提供另一个组件所需的东西。到目前为止,一切都很好。
这就是问题所在:在很多情况下,我们不希望“组件 A”能够访问所有“组件 B”的接口,即我们希望将组件 A 限制为组件 B 提供的接口的子集。
问题/问题:
是否有一种系统的、相当直接的方式来执行——最好是在编译时——在组件图上定义的接口契约?
显然,编译时解决方案比运行时解决方案更可取(更早的检测,更好的性能,可能更小的代码)。
例如,假设库组件“B”提供函数 X()、Y() 和 Z(),但我只希望组件“A”能够调用函数 Z(),而不是 X() 和 Y() . 同样,即使组件“A”可能能够通过其消息队列接收和处理大量不同的消息,我们也没有任何组件能够向任何组件发送任何消息。
我能想到的最好办法是为每个组件-组件接口设置不同的头文件,并且只公开(通过头文件)组件允许使用的接口部分。显然这可能会导致大量的头文件。这也意味着组件之间的消息传递不会直接使用 OS API 完成,而是通过函数调用完成,每个函数调用都会构建并发送特定的(允许的)消息。对于同步调用/库,只会公开允许的 API 子集。
对于这个练习,你可以假设人们会表现得很好。 换句话说,不要担心人们直接作弊和剪切和粘贴函数原型,或者包含他们不允许的头文件。如果不允许,他们不会直接从“A”向“B”发布消息,依此类推……
也许有一种方法可以通过编译时断言来强制执行合同。也许有一种更优雅的方法可以在运行时检查/执行它,即使它会产生一些开销。
代码必须干净地编译和 lint,所以“函数原型防火墙”方法是可以的,但似乎可能有一种更惯用的方法来做到这一点。