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 | 待补充 |
导出后应做一致性检查:需求工具中每条“已实现”需求是否都能在矩阵中找到对应函数;矩阵中每个函数是否都能在目标文件中找到符号;编译基线是否与当前构建一致。若出现“需求无代码”或“代码无需求”的情况,应作为追溯缺口记录并跟踪关闭。
自动化导出的价值在于可重复、可审计。每次构建后运行同一套脚本,得到的矩阵可以直接作为审查证据。若需求或代码发生变更,矩阵会随之更新,追溯缺口也会被重新暴露。建议把导出脚本与构建脚本放在同一流水线中,并在矩阵中保留生成时间、工具版本和需求基线版本,以便回溯。
综上,需求到代码的追溯建立可以归纳为四个关键动作:在需求工具中维护唯一 ID,在源码注释中嵌入同一 ID,在 Green Hills 编译时保留调试与基线信息,在构建后自动扫描并合并生成矩阵。四者缺一不可,且必须纳入版本控制和持续集成流程,才能真正支撑安全关键项目的审查与交付。