3. 安全关键项目需求到代码的追溯建立

在安全关键项目中,追溯不是文档层面的“附加说明”,而是贯穿需求、设计、实现、编译与验证的证据链。以 DO-178C、ISO 26262 或 IEC 61508 为背景的项目,通常要求从每条高层需求出发,能够定位到实现它的源码、编译产物以及验证用例。本章聚焦“需求到代码”这一段,说明如何把需求管理工具与 MULTI 工程关联起来,把需求标识嵌入源码注释,利用 Green Hills 编译选项生成可追溯信息,并自动化导出追溯矩阵。

一、需求管理工具与 MULTI 工程的关联

常见需求管理工具包括 DOORS、Polarion、Jama、Codebeamer 等。它们与 MULTI 工程的关联方式主要有两类:一类是“标识对齐”,即需求工具中的需求 ID 与源码中的注释标识保持同一命名规则;另一类是“工具集成”,通过插件或命令行接口把需求条目同步到工程侧,形成可查询的映射。

实际落地时,建议先确定需求 ID 的命名规范。例如采用 REQ-FCS-001 这样的格式:REQ 表示需求,FCS 表示飞行控制子系统,001 为序号。该 ID 一旦分配,在需求工具、源码注释、测试用例和追溯矩阵中必须完全一致,不允许出现大小写或分隔符差异。MULTI 工程侧可以通过一个 requirements/ 目录存放导出的需求清单,例如 requirements.csv,字段包括需求 ID、需求描述、版本、状态。工程构建脚本在编译前读取该文件,用于后续追溯信息生成。

如果需求工具支持 ReqIF 或 CSV 导出,可以定期导出需求基线,并纳入版本控制。这样做的目的是让“需求版本”与“代码版本”在同一个提交记录中可对应,避免出现代码已更新而需求基线未同步的情况。

二、需求标识嵌入源码注释

源码注释是需求与代码之间最直接的锚点。推荐在每个实现需求的文件头部或函数头部,使用统一格式的注释块嵌入需求 ID。例如:

/* @req REQ-FCS-001
 * @req REQ-FCS-007
 * @brief 俯仰角速率限制计算
 * @trace 对应设计项 DES-FCS-012
 */
static float limit_pitch_rate(float rate_cmd)
{
    ...
}

这里使用 @req 标签,便于后续用脚本或编译器插件扫描。注释块应放在函数定义之前,而不是文件任意位置,这样追溯工具可以按函数粒度建立映射。对于一条需求由多个函数共同实现的情况,可以在每个相关函数中都写入同一个需求 ID;对于一条函数同时满足多条需求的情况,则并列多个 @req 标签。

需要注意:注释中的需求 ID 必须与需求管理工具中的 ID 完全一致,且不能使用“见需求文档”这类模糊描述。若需求发生变更,应先更新需求工具中的条目,再同步修改源码注释,最后重新生成追溯信息。建议在代码评审检查表中加入“需求 ID 是否有效、是否与需求基线一致”这一项。

三、Green Hills 编译选项与追溯信息生成

Green Hills MULTI 工具链提供了若干与调试信息、符号信息和预处理输出相关的选项,可用于生成追溯所需的中间信息。常用的包括:

  • -g:生成调试信息,保留源码行号与符号的对应关系;
  • -S 或 -save-temps:保留预处理或汇编中间文件,便于检查注释是否被正确保留;
  • --list 或类似选项:生成列表文件,展示源码行与目标代码的对应;
  • -D:定义宏,可用于在编译期标记需求版本或构建标识。

一个典型的编译命令示例如下:

ccarm -g -O2 -DREQ_BASELINE=\"v1.3\" \
      -I./include -c fcs_pitch.c -o fcs_pitch.o

其中 -g 保证调试信息中包含源码行号,-DREQ_BASELINE 把需求基线版本写入编译单元,便于在目标文件中区分不同基线构建。编译完成后,可以使用 elftoolchain 或 MULTI 自带的符号查看工具,从 .o 或 .elf 中提取函数与源文件、行号的对应关系。再结合源码扫描得到的 @req 注释,就能建立“需求 ID → 函数 → 目标文件 → 编译选项”的链路。

建议在构建脚本中固定编译选项,并把 -g 作为追溯构建的必备选项。若发布构建使用 -O3 且不带 -g,应单独保留一份带调试信息的追溯构建产物,用于生成追溯矩阵。

四、追溯矩阵自动化导出方法

追溯矩阵的自动化导出通常分为三步:扫描源码提取需求标识、解析编译产物提取函数与文件映射、合并生成矩阵。下面给出一个可参考的实现思路。

第一步,使用脚本扫描 src/ 下所有 .c 和 .h 文件,匹配 @req 标签,输出 req_to_func.csv,字段为需求 ID、函数名、文件名、行号。第二步,使用 nm 或 MULTI 的符号导出功能,从 .o 文件中提取函数符号,输出 func_to_obj.csv,字段为函数名、目标文件、编译选项摘要。第三步,以函数名为键做连接,生成 trace_matrix.csv,字段包括需求 ID、需求描述、函数名、源文件、目标文件、编译基线、验证状态。

下面是一个简化的追溯矩阵示例:

需求 ID 函数名 源文件 目标文件 编译基线 验证状态
REQ-FCS-001 limit_pitch_rate fcs_pitch.c fcs_pitch.o v1.3 已覆盖
REQ-FCS-007 limit_pitch_rate fcs_pitch.c fcs_pitch.o v1.3 已覆盖
REQ-FCS-012 check_roll_limit fcs_roll.c fcs_roll.o v1.3 待补充

导出后应做一致性检查:需求工具中每条“已实现”需求是否都能在矩阵中找到对应函数;矩阵中每个函数是否都能在目标文件中找到符号;编译基线是否与当前构建一致。若出现“需求无代码”或“代码无需求”的情况,应作为追溯缺口记录并跟踪关闭。

需求到代码追溯链路与自动化导出 需求管理工具 DOORS / Polarion REQ-FCS-001 REQ-FCS-007 需求基线导出 requirements.csv ReqIF / CSV 纳入版本控制 源码注释锚点 /* @req REQ-FCS-001 */ 函数级嵌入 ID 严格一致 Green Hills 编译选项 -g -DREQ_BASELINE 保留调试信息 扫描源码 匹配 @req 标签 输出 req_to_func.csv 解析编译产物 nm / 符号导出 输出 func_to_obj.csv 合并生成矩阵 以函数名为键连接 输出 trace_matrix.csv 追溯矩阵 trace_matrix.csv 需求 ID | 函数 | 源文件 | 目标文件 | 编译基线 | 验证状态 一致性检查:需求无代码 / 代码无需求 追溯缺口 REQ-FCS-012 待补充 记录并跟踪关闭

自动化导出的价值在于可重复、可审计。每次构建后运行同一套脚本,得到的矩阵可以直接作为审查证据。若需求或代码发生变更,矩阵会随之更新,追溯缺口也会被重新暴露。建议把导出脚本与构建脚本放在同一流水线中,并在矩阵中保留生成时间、工具版本和需求基线版本,以便回溯。

不要把追溯矩阵当作一次性文档。它必须与需求基线、代码提交和编译产物保持同步。若矩阵长期未更新,审查时无法证明“当前代码满足当前需求”,追溯链即失效。

综上,需求到代码的追溯建立可以归纳为四个关键动作:在需求工具中维护唯一 ID,在源码注释中嵌入同一 ID,在 Green Hills 编译时保留调试与基线信息,在构建后自动扫描并合并生成矩阵。四者缺一不可,且必须纳入版本控制和持续集成流程,才能真正支撑安全关键项目的审查与交付。