Technical Documentation

技术文档

模型开发测试全指南:从需求到认证的完整流程

从需求到认证的完整流程

📋 前言

在当今复杂的嵌入式系统开发中,模型测试已成为确保产品质量和安全性的关键环节。特别是在汽车、轨道交通等安全关键领域,系统化的模型测试不仅是技术要求,更是法规合规的必要条件。

本文将为您详细介绍模型测试的核心概念、方法和最佳实践,帮助您建立一套完整的测试体系。
备注:团队的学习笔记分享,如果需要相关模型测试的工具请联系我们(support@softor.com.cn)文章中如果写的有错误,请批评指正。


🎯 为什么需要模型测试?

1️⃣ 验证模型正确性

  • • 确保模型训练过程没有错误
  • • 验证模型推理结果符合预期
  • • 检查模型是否收敛到合理状态

2️⃣ 评估模型性能

  • • 准确率、精确率、召回率等指标
  • • 推理速度和资源占用
  • • 在不同数据集上的表现

3️⃣ 保证模型稳定性

  • • 检测过拟合和欠拟合
  • • 验证模型在不同输入下的鲁棒性
  • • 确保模型在生产环境中稳定运行

4️⃣ 满足功能安全标准

在高安全要求的行业,模型测试是满足功能安全标准的必要条件:

  • • 证明模型符合安全需求
  • • 提供测试证据和文档
  • • 达到规定的安全完整性等级


🔒 功能安全标准认证

主要认证标准

标准适用领域说明
IEC 61508工业自动化功能安全通用标准
EN 50128轨道交通铁路应用软件开发标准
ISO 25119农业机械农业和林业机械安全标准
IEC 62304医疗设备医疗器械软件生命周期标准
ISO 26262汽车电子道路车辆功能安全标准(最新版支持最高工具置信度水平 TCL 3,可达到最高安全级别 ASIL D)
ASPICE汽车软件汽车软件过程改进和能力评定

为什么需要标准认证?

  • • 法规合规 – 满足行业准入要求
  • • 质量保证 – 确保测试工具本身的可靠性
  • • 责任界定 – 明确工具供应商和使用方的责任
  • • 互认互通 – 国际项目中的通用认可

📝 测试内容详解

1. 基于需求的测试

模型和代码的功能测试

什么是基于需求的测试?

基于需求的测试就是根据产品的功能需求来设计测试用例,确保模型和代码能够正确实现所有要求的功能。简单来说,就是”按要求测试”,确保系统做了它应该做的事情。

测试内容:

  • • 根据需求规格说明书设计测试用例
  • • 验证模型实现是否符合需求
  • • 确保每个需求都有对应的测试覆盖

测试方法:

  1. 1. 需求分析:仔细阅读需求文档,提取出所有需要测试的功能点
  2. 2. 测试用例设计:为每个功能点设计具体的测试场景
  3. 3. 测试执行:运行测试用例并记录结果
  4. 4. 结果验证:检查实际输出是否与预期结果一致

实际例子:自适应巡航控制系统(ACC)

业务场景:在高速公路上,ACC系统需要根据前方车辆的速度自动调整本车速度,以保持安全距离。

需求:当前方车辆减速时,ACC系统应自动减速以保持安全距离(安全距离 = 速度 × 0.3秒)

测试用例

  1. 1. 正常跟随场景:前方车辆以100km/h行驶,测试车辆以100km/h跟随,验证安全距离保持在约8.3米(100km/h × 0.3秒)
  2. 2. 前方车辆减速场景:前方车辆从100km/h突然减速至60km/h,验证测试车辆是否也自动减速至60km/h,并保持约5米的安全距离
  3. 3. 前方车辆停止场景:前方车辆完全停止,验证测试车辆是否安全停止,且与前方车辆保持约2米的停车距离
  4. 4. 前方车辆加速场景:前方车辆从60km/h加速至100km/h,验证测试车辆是否平稳加速跟随

代码示例(简化的ACC控制逻辑):

void acc_control(float target_speed, float front_vehicle_speed, float distance)
{
    float safe_distance = target_speed * 0.3; // 安全距离计算公式
    
    if (distance < safe_distance) {
        // 距离过近,需要减速
        if (front_vehicle_speed < target_speed) {
            set_vehicle_speed(front_vehicle_speed);
        } else {
            set_vehicle_speed(target_speed);
        }
    } else {
        // 距离合适,保持目标速度
        set_vehicle_speed(target_speed);
    }
}

测试覆盖:确保减速、加速、停止等所有功能需求都被完全测试覆盖

2. 测试执行阶段(MiL/SiL/PiL/HiL)

什么是虚拟集成测试?

虚拟集成测试(Virtual Integration Testing)是指在虚拟环境中对嵌入式系统进行测试的方法,通过模拟真实环境来验证系统的功能和性能。它不需要实际的硬件,可以在开发早期就进行测试,大大降低了测试成本和风险。

虚拟集成测试的四个阶段

在嵌入式软件测试中,根据测试执行环境的不同,分为以下四个阶段:

测试阶段英文全称说明特点测试环境
MiLModel-in-the-Loop模型在环测试在模型层面进行仿真测试,验证模型逻辑正确性Simulink/Stateflow等建模环境
SiLSoftware-in-the-Loop软件在环测试在宿主机上运行生成的代码,验证代码功能PC/工作站(Windows/Linux)
PiLProcessor-in-the-Loop处理器在环测试在目标处理器上运行代码,验证处理器兼容性目标ECU或仿真器
HiLHardware-in-the-Loop硬件在环测试在实际硬件环境中测试,验证系统集成实际ECU + 传感器/执行器

各阶段详细说明

1. MiL(Model-in-the-Loop)- 模型在环测试

  • • 定义:在建模环境中直接对控制算法模型进行测试
  • • 测试对象:控制算法模型(如Simulink模型)
  • • 测试环境:PC上的建模软件(Simulink、Stateflow等)
  • • 测试目的
    • • 验证控制算法逻辑的正确性
    • • 检查模型设计的合理性
    • • 早期发现设计缺陷
  • • 优势
    • • 测试速度快,修改方便
    • • 不需要实际硬件
    • • 可以快速迭代
  • • 实际例子% 在Simulink中测试ACC控制模型
    sim('acc_control_model.slx');
    % 分析仿真结果,验证控制逻辑

2. SiL(Software-in-the-Loop)- 软件在环测试

  • • 定义:在宿主机上运行自动生成的代码进行测试
  • • 测试对象:从模型自动生成的C/C++代码
  • • 测试环境:PC或工作站(Windows/Linux)
  • • 测试目的
    • • 验证代码生成的正确性
    • • 检查代码功能是否与模型一致
    • • 进行初步的性能测试
  • • 优势
    • • 不需要目标硬件
    • • 可以使用丰富的调试工具
    • • 测试成本较低
  • • 实际例子// 在PC上编译并运行生成的C代码
    #include "acc_control.h"
    int main() {
        acc_control_init();
        acc_control_run(100.0, 80.0, 10.0); // 测试ACC控制
        return 0;
    }

3. PiL(Processor-in-the-Loop)- 处理器在环测试

  • • 定义:在目标处理器或仿真器上运行代码进行测试
  • • 测试对象:编译后的目标代码
  • • 测试环境:目标ECU、处理器仿真器或开发板
  • • 测试目的
    • • 验证代码在目标处理器上的正确性
    • • 检查处理器兼容性
    • • 测试实时性能
  • • 优势
    • • 接近真实运行环境
    • • 可以测试处理器特定的行为
    • • 验证实时性要求
  • • 实际例子// 在目标ECU上运行代码
    // 通过串口或CAN总线与PC通信
    void main() {
        acc_control_init();
        while(1) {
            float speed = read_speed_sensor();
            float target_speed = read_target_speed();
            acc_control_run(speed, target_speed, 0.0);
        }
    }

4. HiL(Hardware-in-the-Loop)- 硬件在环测试

  • • 定义:在实际硬件环境中对ECU进行测试
  • • 测试对象:完整的ECU系统
  • • 测试环境:HiL测试台架(包含ECU、传感器、执行器等)
  • • 测试目的
    • • 验证系统集成
    • • 测试与外部设备的交互
    • • 模拟各种故障场景
  • • 优势
    • • 最接近真实运行环境
    • • 可以测试完整的系统行为
    • • 可以模拟各种边界和故障情况
  • • 实际例子// 在HiL台架上测试
    // HiL系统模拟车辆动力学、传感器信号等
    // ECU接收模拟信号,输出控制信号
    // 测试各种驾驶场景和故障情况

虚拟集成测试的优势

  1. 1. 早期发现问题:在开发早期就能进行测试,降低后期修复成本
  2. 2. 降低测试成本:不需要大量实际硬件,减少测试设备投入
  3. 3. 提高测试效率:自动化程度高,可以快速执行大量测试用例
  4. 4. 增强测试覆盖率:可以模拟各种边界和异常情况
  5. 5. 支持持续集成:可以集成到CI/CD流程中,实现自动化测试

测试流程:

需求分析 → 模型设计 → MiL测试 → 代码生成 → SiL测试 → PiL测试 → HiL测试 → 实车测试

实际应用场景

汽车电子领域

  • • 发动机控制系统测试
  • • 制动系统测试(ABS、ESP)
  • • 自适应巡航控制(ACC)测试
  • • 车身控制模块测试

工业自动化领域

  • • PLC控制系统测试
  • • 机器人控制系统测试
  • • 过程控制系统测试

航空航天领域

  • • 飞行控制系统测试
  • • 航空电子系统测试
  • • 导航系统测试

3. 背靠背测试

全自动等效性测试

什么是背靠背测试?

背靠背测试就像是让两个学生做同一份试卷,然后对比他们的答案是否一致。在模型测试中,就是让模型和生成的代码执行相同的测试用例,然后对比它们的输出结果,确保代码生成过程没有引入错误。

测试内容:

  • • 对比模型在不同环境(如Simulink vs 生成代码)下的输出
  • • 验证代码生成过程没有引入错误
  • • 自动化执行,提高效率

测试方法:

  1. 1. 基准测试:在原始模型环境(如Simulink)中运行测试用例,获取基准输出(MiL)
  2. 2. 代码测试:在目标环境(如生成的C代码)中运行相同测试用例(SiL/PiL)
  3. 3. 结果对比:自动对比两组输出结果
  4. 4. 差异分析:标记差异并生成测试报告

实际例子:发动机燃油喷射控制

业务场景:发动机控制系统需要根据转速、负载等参数精确计算燃油喷射量,以确保发动机高效运行。

模型与代码

  • • 模型:在Simulink中设计的发动机燃油喷射控制算法模型
  • • 代码:通过代码生成工具从模型自动生成的C代码

测试用例

测试场景转速(rpm)负载(%)预期燃油喷射量(ms)
怠速工况800102.5
部分负荷2000504.8
全负荷40001008.2
急加速3000→450080→1006.5→9.0

测试过程

  1. 1. MiL测试:在Simulink中运行上述测试用例,记录模型的燃油喷射量输出作为基准
  2. 2. SiL测试:在宿主机上运行生成的C代码,使用相同的测试用例
  3. 3. PiL测试:在目标ECU处理器上运行代码,使用相同的测试用例
  4. 4. 结果对比:自动对比三种环境下的输出结果
  5. 5. 差异分析:如果结果不一致,分析原因并修复

代码示例(自动生成的燃油喷射控制代码):

float calculate_fuel_injection(float rpm, float load)
{
    // 基于转速和负载的燃油喷射量计算
    float base_injection = 0.001 * rpm + 0.05 * load;
    float correction = 0.0;
    
    // 温度修正
    if (engine_temp < 60.0) {
        correction = 0.5;
    }
    
    return base_injection + correction;
}

4. 覆盖率分析

代码及模型覆盖率统计(死代码检测)

什么是覆盖率分析?

覆盖率分析就像是检查我们的测试用例是否覆盖了所有的代码路径,确保没有遗漏任何重要的功能。它可以帮助我们发现哪些代码没有被测试到,哪些代码可能是多余的(死代码)。

测试内容:

  • • 语句覆盖:确保每一行代码都被执行过
  • • 分支覆盖:确保每个条件分支(如if-else)都被测试过
  • • MC/DC覆盖:确保每个条件的变化都能独立影响决策结果
  • • 死代码检测:识别永远不会被执行的代码
  • • 测试充分性:确保测试用例足够全面
  • • 圈复杂度分析:评估代码复杂度和可测试性

测试方法:

  1. 1. 数据收集:在测试执行过程中收集覆盖率数据
  2. 2. 报告生成:生成详细的覆盖率报告
  3. 3. 路径分析:分析未覆盖的代码路径
  4. 4. 用例补充:针对未覆盖的路径补充测试用例
  5. 5. 死代码处理:识别并处理死代码
  6. 6. 圈复杂度计算:使用McCabe方法计算圈复杂度

覆盖率标准:

覆盖类型要求适用场景
语句覆盖100%基础要求
分支覆盖100%安全关键功能
MC/DC覆盖100%最高安全等级(ASIL D)

圈复杂度(Cyclomatic Complexity)

什么是圈复杂度?

圈复杂度(Cyclomatic Complexity)是由Thomas McCabe提出的一种软件度量指标,用于评估代码的复杂度和可测试性。它反映了程序中独立路径的数量。

计算公式:

圈复杂度 = E - N + 2P

其中:

  • • E:图中边的数量
  • • N:图中节点的数量
  • • P:连通分量的数量

简化计算方法:

圈复杂度 = 判定节点数量 + 1

判定节点包括:if语句、while循环、for循环、case语句等。

圈复杂度标准:

圈复杂度代码质量建议
1-10低风险代码简单,易于测试和维护
11-20中等风险代码复杂度适中,需要关注
21-50高风险代码复杂,建议重构
>50极高风险代码过于复杂,必须重构

实际例子:

// 圈复杂度 = 4(3个if + 1)
void abs_control(float speed, float brake_pressure, float wheel_speed)
{
    float slip_ratio = (speed - wheel_speed) / speed;
    
    if (speed > 100 && brake_pressure > 50 && slip_ratio > 0.2) {  // 判定1
        apply_abs_pulse();
    } else if (speed > 50 && slip_ratio > 0.15) {  // 判定2
        apply_abs_regular();
    } else if (brake_pressure > 70) {  // 判定3
        apply_regular_brake();
    } else {
        apply_light_brake();
    }
}

圈复杂度在测试中的作用:

  1. 1. 测试用例数量:圈复杂度表示至少需要多少个测试用例才能覆盖所有可能的执行路径
  2. 2. 代码质量评估:高圈复杂度通常意味着代码难以理解和维护
  3. 3. 重构指导:当圈复杂度过高时,建议将函数拆分为多个小函数
  4. 4. 安全标准要求:ISO 26262等安全标准对圈复杂度有明确要求

降低圈复杂度的方法:

  1. 1. 函数拆分:将复杂函数拆分为多个小函数
  2. 2. 使用策略模式:用多态替代复杂的条件判断
  3. 3. 卫语句:尽早返回,减少嵌套层级
  4. 4. 状态机:用状态机管理复杂的状态转换

降低圈复杂度示例:

// 原始代码:圈复杂度 = 5
void process_order(Order* order) {
    if (order != NULL) {
        if (order->status == PENDING) {
            if (order->amount > 1000) {
                if (order->customer->vip_level > 2) {
                    apply_discount(order, 0.2);
                } else {
                    apply_discount(order, 0.1);
                }
            } else {
                process_normal(order);
            }
        } else {
            reject_order(order);
        }
    }
}

// 重构后:圈复杂度 = 2
void process_order(Order* order) {
    if (order == NULL) return;
    
    if (order->status != PENDING) {
        reject_order(order);
        return;
    }
    
    if (order->amount > 1000) {
        apply_vip_discount(order);
    } else {
        process_normal(order);
    }
}

void apply_vip_discount(Order* order) {
    if (order->customer->vip_level > 2) {
        apply_discount(order, 0.2);
    } else {
        apply_discount(order, 0.1);
    }
}

实际例子:防抱死制动系统(ABS)控制

业务场景:ABS系统需要根据车速和制动压力自动调整制动模式,以防止车轮抱死。

代码示例

void abs_control(float speed, float brake_pressure, float wheel_speed)
{
    // 计算滑移率
    float slip_ratio = (speed - wheel_speed) / speed;
    
    if (speed > 100 && brake_pressure > 50 && slip_ratio > 0.2) {
        // 高速高压力下的ABS控制
        apply_abs_pulse();
    } else if (speed > 50 && slip_ratio > 0.15) {
        // 中速下的ABS控制
        apply_abs_regular();
    } else if (brake_pressure > 70) {
        // 高压力下的常规制动
        apply_regular_brake();
    } else {
        // 低速或低压力下的轻度制动
        apply_light_brake();
    }
}

覆盖率测试

1. 语句覆盖测试用例

  • • 测试用例1:speed=120, brake_pressure=60, slip_ratio=0.25 → 进入第一个分支
  • • 测试用例2:speed=60, brake_pressure=40, slip_ratio=0.18 → 进入第二个分支
  • • 测试用例3:speed=40, brake_pressure=80, slip_ratio=0.1 → 进入第三个分支
  • • 测试用例4:speed=30, brake_pressure=30, slip_ratio=0.05 → 进入第四个分支

2. 分支覆盖测试用例

  • • 测试所有条件的真假组合,确保每个分支都被测试到

3. MC/DC覆盖测试用例

  • • 确保每个条件独立影响决策结果
  • • 例如:测试speed > 100对结果的独立影响,保持其他条件不变

4. 死代码检测

  • • 分析是否存在永远不会执行的代码路径
  • • 例如:如果speed <= 0时的处理逻辑

覆盖率报告示例

覆盖类型目标实际状态
语句覆盖100%100%
分支覆盖100%100%
MC/DC覆盖100%100%
死代码00

5. 形式化规格说明

需求形式化

什么是形式化规格说明?

形式化规格说明就是用数学语言来精确描述需求,消除自然语言的歧义,确保需求的准确性和一致性。简单来说,就是把模糊的文字描述变成精确的数学表达式。

测试内容:

  • • 使用数学语言精确描述需求
  • • 消除自然语言的歧义
  • • 为形式化验证奠定基础

测试方法:

  1. 1. 需求转换:将自然语言需求转换为形式化描述
  2. 2. 规约定义:使用形式化语言(如Z语言、B方法)定义规约
  3. 3. 可追溯性:建立需求与实现之间的可追溯性

实际例子:安全气囊系统

业务场景:安全气囊系统需要在发生碰撞时,根据碰撞严重程度决定是否弹出气囊,以保护乘客安全。

自然语言需求:当汽车发生碰撞时,安全气囊应该在合适的时机弹出

形式化规格说明

安全气囊弹出条件 = 碰撞加速度 > 30g 且 碰撞持续时间 > 10ms 且 车辆速度 > 20km/h

安全气囊不弹出条件 = 碰撞加速度 ≤ 30g 或 碰撞持续时间 ≤ 10ms 或 车辆速度 ≤ 20km/h

形式化语言表示(使用Z语言):

z
气囊弹出?: bool
气囊弹出? = (碰撞加速度 > 30) ∧ (碰撞持续时间 > 10) ∧ (车辆速度 > 20)
z

可追溯性

  • • 需求ID:REQ-001
  • • 形式化规约ID:FSPEC-001
  • • 实现模块:airbag_controller.c

通过形式化描述,我们消除了”合适的时机”这样的模糊表达,明确了安全气囊弹出的具体条件,为后续的验证奠定了基础。

6. 形式化验证

形式验证

什么是形式验证?

形式验证就是使用数学方法来证明系统的正确性,通过穷举所有可能的执行路径,确保系统在所有情况下都能正确运行。这是一种最高级别的验证方法,可以提供数学上的保证。

测试内容:

  • • 通过数学证明验证系统正确性
  • • 穷举所有可能的执行路径
  • • 提供最高级别的正确性保证

测试方法:

  1. 1. 模型建立:建立系统的形式化模型
  2. 2. 属性定义:定义需要验证的属性(如安全性、活性)
  3. 3. 验证执行:使用模型检测或定理证明工具进行验证
  4. 4. 结果分析:分析验证结果并修复问题

实际例子:火车信号控制系统

业务场景:火车信号系统需要控制不同火车在轨道网络中的运行,确保不会发生碰撞。

系统需求:确保在任何情况下,同一轨道上不会有两列火车同时行驶

形式化模型

  • • 状态变量:火车位置、轨道占用状态、信号状态
  • • 转换关系:火车移动规则、信号控制逻辑
  • • 安全属性:对于任何时刻t,任何轨道segment s,最多只有一列火车在s上

形式验证过程

  1. 1. 模型建立:使用模型检测工具(如NuSMV)建立火车信号系统的形式化模型
  2. 2. 属性定义:定义安全属性公式AG (∀s ∈ 轨道, ∀t1,t2 ∈ 火车, t1 ≠ t2 → ¬(在轨道s上(t1) ∧ 在轨道s上(t2)))
  3. 3. 验证执行:使用模型检测工具验证安全属性
  4. 4. 结果分析
    • • 如果验证通过:系统设计正确,不存在碰撞风险
    • • 如果验证失败:工具会生成反例,显示导致碰撞的具体场景

代码示例(信号控制逻辑):

bool is_track_free(int track_id)
{
    for (int i = 0; i < MAX_TRAINS; i++) {
        if (trains[i].current_track == track_id && trains[i].status == RUNNING) {
            return false;
        }
    }
    return true;
}

void control_signal(int track_id, int signal_id)
{
    if (is_track_free(track_id)) {
        set_signal_green(signal_id);
    } else {
        set_signal_red(signal_id);
    }
}

验证结果

  • • 成功案例:验证通过,证明系统在所有场景下都能防止碰撞
  • • 失败案例:发现当两列火车同时接近同一轨道时,信号可能出现竞争条件,导致两列火车同时进入轨道

通过形式验证,我们可以确保火车信号系统的安全性,避免碰撞事故的发生。


📋 七、测试流程

7.1 测试流程概述

模型开发的测试流程包括以下7个关键阶段:

  1. 1. 需求分析
    • • 理解功能需求和安全需求
    • • 识别测试需求
    • • 确定测试范围和目标
  2. 2. 测试设计
    • • 设计测试用例(基于需求)
    • • 确定测试覆盖目标(语句覆盖、分支覆盖、MC/DC覆盖)
    • • 准备测试数据和测试环境
  3. 3. 功能测试
    • • 执行Requirements-based Testing
    • • 验证模型功能正确性
    • • 检查是否满足所有需求
  4. 4. 等效性测试
    • • 执行Back-to-Back Test
    • • 对比模型与代码输出
    • • 确保代码生成的正确性
  5. 5. 覆盖率分析
    • • 执行Coverage Analysis
    • • 统计代码/模型覆盖率
    • • 识别死代码和未覆盖的部分
  6. 6. 形式化验证(高安全等级要求)
    • • 执行Formal Specification
    • • 执行Formal Verification
    • • 确保系统安全性和可靠性
  7. 7. 测试报告与认证
    • • 生成测试报告
    • • 准备认证文档
    • • 确保符合安全标准要求

7.2 测试流程图示

需求分析 → 测试设计 → 功能测试 → 等效性测试 → 覆盖率分析 → 形式化验证 → 测试报告与认证

🔄 八、开发工作流程与测试方法映射

8.1 开发与测试关系

开发阶段对应测试方法测试目标
需求分析Requirements-based Testing确保测试覆盖所有需求
模型设计功能测试、形式化规格说明验证模型功能正确性
代码生成Back-to-Back Test确保代码与模型行为一致
集成测试覆盖率分析确保代码被充分测试
系统测试形式化验证确保系统安全性

8.2 测试执行环境映射

测试方法执行环境适用阶段
功能测试MiL (Model-in-the-Loop)模型设计阶段
等效性测试MiL → SiL → PiL代码生成阶段
覆盖率分析SiL, PiL集成测试阶段
形式化验证模型级、代码级全生命周期
系统验证HiL (Hardware-in-the-Loop)系统测试阶段

8.3 测试方法应用场景

  • • Requirements-based Testing:适用于所有安全等级的功能验证
  • • Back-to-Back Test:适用于代码生成后的一致性验证
  • • Coverage Analysis:适用于ASIL B及以上安全等级的代码测试
  • • Formal Verification:适用于ASIL D安全等级的关键功能验证

💡 九、最佳实践

9.1 测试数据准备

  • • 使用与训练数据分布一致的测试集
  • • 准备边缘案例和异常数据
  • • 确保测试数据的代表性和多样性

9.2 测试指标选择

  • • 根据业务场景选择合适的评估指标
  • • 不仅关注单一指标,要综合评估
  • • 设置合理的性能阈值

9.3 自动化测试

  • • 将模型测试集成到CI/CD流程
  • • 定期运行回归测试
  • • 建立测试报告和告警机制

9.4 持续监控

  • • 上线后持续监控模型表现
  • • 建立数据漂移检测
  • • 及时发现模型退化问题

�� ISO 26262-6 软件单元测试方法

根据ISO 26262-6标准,软件单元测试需要采用以下方法:

软件单元测试方法(Table 10)

方法ASIL AASIL BASIL CASIL D说明
1a 基于需求的测试++++++++根据需求规格设计测试用例
1b 接口测试++++++++验证模块间接口正确性
1c 故障注入测试+++++通过注入故障验证容错能力
1d 资源使用测试+++++验证内存、CPU等资源使用
1e 背靠背对比测试++++++对比模型与代码输出一致性

测试用例设计方法(Table 11)

方法ASIL AASIL BASIL CASIL D说明
1a 需求分析++++++++分析需求以确定测试范围
1b 等价类生成与分析+++++++将输入划分为等价类进行测试
1c 边界值分析+++++++测试边界条件下的系统行为
1d 错误推测++++基于经验推测可能的错误

符号说明

  • • ++ 强烈推荐
  • • + 推荐

🔧 测试套件功能

1. 功能测试套件

就像是一个测试管理员

主要功能:

  • • 测试用例管理:手工创建或管理测试用例,就像创建和整理考试题目一样
  • • 需求链接:导入需求(如来自DOORS、Excel等)并自动链接到测试用例,实现双向可追溯,就像给每个测试题目标注对应的知识点
  • • 多环境测试:可对任意层级的子系统自动进行MiL/SiL/PiL测试,就像在不同的考试环境中测试学生的表现
  • • 结果比对:自动和预期结果进行比照,就像自动批改试卷并标记错误
  • • 覆盖率分析:针对需求、模型、C代码,测试并生成覆盖率报告,就像分析学生在各个知识点上的掌握情况
  • • 调试环境:自动生成调试环境,就像为学生提供专门的学习辅导环境

实际例子:
假设我们开发一个汽车空调控制系统:

  • • 从Excel导入需求:”当温度设置为25℃时,系统应将车内温度控制在23-27℃之间”
  • • 功能测试套件自动创建测试用例,在MiL、SiL、PiL环境中测试
  • • 自动比对实际温度与预期范围
  • • 生成覆盖率报告,确保所有温度控制逻辑都被测试到

2. 背靠背测试套件

就像是一个严格的考官

主要功能:

  • • 智能测试生成:自动生成满足C代码结构100%覆盖率的测试用例,就像自动生成一套全面的考试题目
  • • 死代码检测:识别永远不会被执行的代码,就像发现课本中从未被使用的章节
  • • 风险识别:识别计算溢出等风险,就像发现考试中可能出现的陷阱题
  • • 自动比对:自动执行Back-to-Back测试,对比模型和代码的输出,就像让两个学生做同一份试卷并对比答案
  • • 覆盖率目标:通过插件支持用户定义覆盖率目标(等价类、边界值等),并自动生成测试用例满足该目标,就像根据教学大纲自动生成针对性的练习题
  • • 扩展功能:支持可扩展的功能(测试自动化、回归测试等),就像提供更多的学习工具和方法

实际例子:
开发一个发动机燃油喷射控制模型:

  • • 背靠背测试套件自动生成测试用例,确保C代码的每个分支都被测试到
  • • 检测到一段永远不会执行的死代码(如某个条件永远为假的if语句)
  • • 发现一个可能导致计算溢出的变量定义
  • • 自动对比模型和代码在不同转速下的燃油喷射量输出
  • • 生成详细的对比报告,标记任何差异

3. 形式测试套件

就像是一个翻译官

主要功能:

  • • 需求导入:导入自然语言需求(如来自DOORS、Excel等),就像接收一份用日常语言写的任务描述
  • • 图形界面:提供直观的需求形式化图形界面,轻松进行需求形式化,就像使用可视化工具将日常语言翻译成数学公式
  • • 多对象支持:被测对象支持Simulink模型、手写代码、dSPACE HiL系统等,就像能翻译不同类型的文档
  • • 形式化编辑:提供直观的形式化编辑器,就像提供专业的翻译工具

实际例子:
处理一个汽车安全系统的需求:

  • • 导入需求:”当车速超过120km/h时,系统应发出超速警告”
  • • 使用形式测试套件的图形界面,将其转换为形式化描述:”如果 speed > 120 km/h,则 trigger_warning = true”
  • • 保存这个形式化规约,为后续的形式验证做准备

4. 形式验证套件

就像是一个数学证明专家

主要功能:

  • • 结果判定:自动判定仿真结果,就像自动检查数学证明的正确性
  • • 测试生成:自动生成来自需求的测试用例,就像根据数学定理自动生成练习题
  • • 调试支持:自动生成调试模型,就像为数学证明提供辅助工具
  • • 形式测试:自动进行形式测试,生成报告,就像生成详细的数学证明过程
  • • 模型检测:使用Model Checking技术数学穷举是否存在反例,就像通过穷举法验证数学定理的正确性

实际例子:
验证一个火车信号控制系统:

  • • 形式验证套件根据需求自动生成测试用例
  • • 使用Model Checking技术,穷举所有可能的火车运行场景
  • • 验证是否存在两列火车同时进入同一轨道的情况
  • • 生成详细的验证报告,证明系统的安全性
  • • 如果发现问题,会提供具体的反例场景,帮助工程师修复

🚀 测试工具核心优势

提高效率

高质量测试确保按时交付优质产品:

  • • 测试用例的设计解耦于测试技术与执行,易于维护
  • • 一次构建,随时复用:测试设计元素可复用
  • • 自动生成各个测试阶段的测试用例
  • • 测试执行自动化
  • • 通过将需求与测试用例关联,实现出色的可追溯性

一款工具,无限可能

一次测试部署,赋能全流程:

  • • 涵盖整个开发周期:从单元测试到集成测试
  • • 支持Matlab/Simulink、C/C++代码、以及来自各种不同测试供应商的测试工具与平台等
  • • 支持从MiL、SiL、PiL到HiL的各种测试执行方法
  • • 支持云上部署,适用CI流程
  • • 非介入被测件,测试工作和项目时与被测件保持解耦

无缝集成

可以无缝集成到现有的工作流程和工具链中:

  • • 与通用开发环境深度集成
  • • 与所有CI环境和存储库兼容
  • • 支持在Windows和Linux下执行测试
  • • 能与各系统API顺畅通信

易用性

无需编程知识即可轻松应用于整个测试流程中:

  • • 测试工程项目结构清晰
  • • 测试用例和结果展示易于理解
  • • 内置样例模板加速测试工作的开展
  • • 测试执行过程稳定
  • • 友好的用户体验
  • • 一次测试架构搭建完成,即可复用测试用例和测试设计于其他项目,也可用于重构后的软件

🔄 测试流程

  1. 1. 需求分析 – 理解功能需求和安全需求,识别测试需求
  2. 2. 测试设计 – 设计测试用例(基于需求),确定测试覆盖目标,准备测试数据
  3. 3. 功能测试 – Requirements-based Testing,验证模型功能正确性
  4. 4. 等效性测试 – Back-to-Back Test,对比模型与代码输出
  5. 5. 覆盖率分析 – Coverage Analysis,统计代码/模型覆盖率,识别死代码
  6. 6. 形式化验证 – Formal Specification和Formal Verification(高安全等级要求)
  7. 7. 测试报告与认证 – 生成测试报告,准备认证文档

💡 最佳实践

测试数据准备

  • • 使用与训练数据分布一致的测试集
  • • 准备边缘案例和异常数据
  • • 确保测试数据的代表性和多样性

测试指标选择

  • • 根据业务场景选择合适的评估指标
  • • 不仅关注单一指标,要综合评估
  • • 设置合理的性能阈值

自动化测试

  • • 将模型测试集成到CI/CD流程
  • • 定期运行回归测试
  • • 建立测试报告和告警机制

持续监控

  • • 上线后持续监控模型表现
  • • 建立数据漂移检测
  • • 及时发现模型退化问题

🎉 总结

模型测试是确保模型质量和安全性的关键环节。通过遵循功能安全标准(如ISO 26262、IEC 61508等),采用系统化的测试方法(Requirements-based Testing、Back-to-Back Test、Coverage Analysis等),可以有效地:

  1. 1. 验证模型的正确性和可靠性
  2. 2. 满足行业安全标准要求
  3. 3. 降低系统风险
  4. 4. 提高产品质量

在高安全要求的领域,选择合适的测试工具类型并建立完善的测试流程,是项目成功的关键保障。


**如果需要进一步的帮助或有其他问题,请随时联系我们。
support@softor.com.cn
tianpengbo@softor.com.cn
**

希望对您的项目有所帮助!

英飞凌TC3xx\TC4XX Tasking编译器 CMake项目配置与CI搭建详细教程

1. 项目简介

英飞凌TC39x系列微控制器是汽车电子领域的高性能处理器,广泛应用于发动机控制、车身电子、安全系统等场景。本教程将详细介绍如何使用Tasking编译器和CMake构建系统来配置和管理TC39x项目,并搭建完整的CI/CD流程,让新手也能轻松上手。

备注:结合与多位工程师线下/线上的交流和平台资料,写的这篇教程,如有错误之处,请批评指正。需要许可证,安装包等内容,请与我们联系 support@softor.com.cn

1.1 项目特点

  • • 多核心支持:支持TC39x系列的6个CPU核心(Cpu0-Cpu5)
  • • ILLD库集成:使用英飞凌官方的低级别驱动库,简化硬件操作
  • • MISRA C 2012标准:代码符合汽车电子行业的安全标准
  • • CMake构建系统:现代化的跨平台构建工具
  • • Tasking编译器优化:针对TriCore架构的专业编译器,提供优异的代码性能

1.2 IDE与CMake构建方式对比

在英飞凌TC39x项目开发中,主要有两种构建方式:使用 tasking IDE和使用CMake命令行构建。下面详细对比这两种方式的优缺点。

1.2.1  IDE

优点:

优点说明
图形化界面友好提供直观的图形界面,适合初学者快速上手
项目管理便捷通过项目浏览器可以方便地管理源文件、头文件和库文件
代码编辑功能强大集成代码高亮、自动补全、语法检查等功能
调试功能完善集成调试器,支持断点、单步执行、变量查看等
一键构建点击按钮即可完成编译、链接和生成可执行文件
配置可视化编译选项、链接选项等都可以通过图形界面配置
多工程管理可以同时打开多个工程,方便切换和对比
代码生成集成支持从Simulink等工具自动生成代码

缺点:

缺点说明
依赖IDE环境必须在安装了ide的环境中才能编译,无法在服务器上运行
自动化困难难以集成到CI/CD流程,无法实现自动化构建
版本控制冲突IDE生成的配置文件容易产生版本控制冲突
构建效率较低图形界面占用资源,构建速度相对较慢
配置不透明编译选项隐藏在IDE配置中,难以追踪和复现
批量构建困难无法方便地批量构建多个项目或多个配置

1.2.2 CMake命令行构建

优点:

优点说明
跨平台支持支持Windows、Linux、macOS等多个平台
自动化友好可以轻松集成到CI/CD流程,实现自动化构建
构建效率高命令行构建速度快,资源占用少
配置透明所有编译选项都在CMakeLists.txt中,清晰可见
版本控制友好配置文件是文本文件,易于版本控制
批量构建可以方便地批量构建多个项目或多个配置
灵活可扩展可以轻松添加自定义构建步骤和脚本
并行构建支持多核并行编译,大幅提高构建速度
服务器部署可以在无图形界面的服务器上运行
工具链灵活可以方便地切换不同的编译器和工具链
社区支持CMake有庞大的社区支持和丰富的文档

缺点:

缺点说明
学习曲线陡峭需要学习CMake语法和命令行操作
配置复杂初次配置需要编写CMakeLists.txt和工具链文件
调试不便需要额外配置调试器,不如IDE集成方便
缺少图形界面没有直观的图形界面,对初学者不友好
错误定位困难编译错误信息不如IDE直观,需要手动定位
依赖管理需要手动管理依赖和包含路径
代码编辑需要配合其他代码编辑器使用
缺少IDE功能没有代码高亮、自动补全等功能

1.2.3 对比总结

对比项ADS IDECMake
学习难度⭐ 简单⭐⭐⭐⭐ 较难
开发效率⭐⭐⭐⭐ 高⭐⭐⭐ 中等
构建速度⭐⭐⭐ 中等⭐⭐⭐⭐⭐ 快
跨平台⭐⭐ 有限⭐⭐⭐⭐⭐ 优秀
自动化⭐ 困难⭐⭐⭐⭐⭐ 优秀
调试功能⭐⭐⭐⭐⭐ 完善⭐⭐ 需配置
版本控制⭐⭐⭐ 中等⭐⭐⭐⭐⭐ 优秀
CI/CD集成⭐ 困难⭐⭐⭐⭐⭐ 优秀
团队协作⭐⭐⭐ 中等⭐⭐⭐⭐⭐ 优秀
成本⭐⭐⭐ 需要IDE许可证⭐⭐⭐⭐⭐ 免费

1.2.4 推荐使用场景

使用TASKING IDE的场景:

  • • 初学者学习TC39x开发
  • • 快速原型开发和调试
  • • 单人开发或小团队开发
  • • 需要频繁调试和测试
  • • 使用Simulink等工具自动生成代码

使用CMake的场景:

  • • 大型项目或团队协作开发
  • • 需要实现CI/CD自动化流程
  • • 需要在服务器上构建项目
  • • 需要跨平台支持
  • • 需要批量构建多个配置
  • • 追求构建效率和可重复性

1.2.5 混合使用方案

在实际项目中,可以结合两种方式的优点:

  • • 开发阶段:使用TASKING IDE进行代码编写、调试和测试
  • • 构建阶段:使用CMake进行自动化构建和CI/CD集成
  • • 团队协作:使用CMake确保构建环境一致性

这种混合方案可以兼顾开发效率和自动化需求,是实际项目中的最佳实践。

2. 环境搭建

2.1 软件准备清单

软件名称版本要求用途下载来源
CMake3.15+构建系统CMake官网
MinGW最新版Windows环境下的GNU工具链MinGW官网
Git最新版版本控制Git官网
Tasking TriCore编译器6.3r1+TriCore架构专用编译器英飞凌官网或Tasking官网
Aurix Development Studio (ADS)1.9.20+集成开发环境英飞凌官网

2.2 安装Tasking编译器详细步骤

  1. 1. 下载安装包
    • • 联系我们:support@softor.com.cn ; tianpengbo@softor.com.cn
    • • 需要许可证请联系我们
    • • 保存到本地目录(例如:D:\Downloads
  2. 2. 运行安装程序
    • • 双击安装包,启动安装向导
    • • 点击”Next”继续
    • • 阅读并接受许可证协议,点击”Next”
    • • 选择安装目录(建议使用默认路径:C:\Tasking\TriCore6.3r1\ctc
    • • 选择安装组件(默认全选即可)
    • • 点击”Install”开始安装
    • • 等待安装完成,点击”Finish”退出向导
  3. 3. 打最新补丁(可选)
    • • 访问Tasking官网下载最新补丁(如v6.3r1p8)
    • • 安装补丁以获得最新功能和修复
  4. 4. 验证安装
    • • 打开命令提示符
    • • 输入命令:ctc -V
    • • 如果显示编译器版本信息,说明安装成功

2.3 配置环境变量

  1. 1. 打开环境变量设置
    • • 右键点击”此电脑” → “属性” → “高级系统设置” → “环境变量”
  2. 2. 编辑系统PATH变量
    • • 在”系统变量”中找到Path变量,点击”编辑”
    • • 点击”新建”,添加Tasking编译器的bin目录路径(例如:C:\Tasking\TriCore6.3r1\ctc\bin
    • • 添加CMake的bin目录路径(例如:C:\Program Files\CMake\bin
    • • 添加MinGW的bin目录路径(例如:C:\mingw64\bin
    • • 点击”确定”保存设置
  3. 3. 验证环境变量
    • • 关闭所有命令提示符窗口
    • • 重新打开一个命令提示符
    • • 输入命令:cctc -v
    • • 输入命令:cmake --version
    • • 输入命令:gcc --version
    • • 如果都显示版本信息,说明环境变量配置成功

3. 项目结构详解

3.1 核心文件说明

文件名用途重要性
CMakeLists.txt主构建配置文件⭐⭐⭐⭐⭐
tasking_tricore.cmakeTasking编译器工具链配置⭐⭐⭐⭐⭐
win.ps1Windows环境构建脚本⭐⭐⭐⭐
.gitlab-ci.ymlCI/CD配置文件⭐⭐⭐⭐
Lcf_Tasking_Tricore_Tc.lslTasking链接脚本⭐⭐⭐⭐
Cpu0_Main.cCPU0核心主函数⭐⭐⭐
Cpu1_Main.c – Cpu5_Main.c其他CPU核心主函数⭐⭐⭐

3.2 目录结构

tc397_min_project/
├── .tasking/                # 项目配置文件
├── .settings/           # IDE设置
├── Configurations/      # 配置文件
│   ├── Debug/           # 调试配置
│   ├── Ifx_Cfg.h        # 全局配置头文件
│   └── Ifx_Cfg_Ssw.c    # 系统启动配置
├── Libraries/           # 库文件
│   ├── Infra/           # 基础架构库
│   ├── Service/         # 服务库
│   └── iLLD/            # 英飞凌低级别驱动库
├── CMakeLists.txt       # 主构建文件
├── tasking_tricore.cmake # 工具链配置
├── win.ps1              # Windows构建脚本
├── .gitlab-ci.yml       # CI配置
├── Lcf_Tasking_Tricore_Tc.lsl # 链接脚本
└── Cpu0_Main.c          # CPU0主函数

3.3 关键文件内容解析

3.3.1 tasking_tricore.cmake(工具链配置)

set(CMAKE_SYSTEM_NAME Generic)

# 查找Tasking编译器和汇编器
find_program(COMPILER_C cctc PATHS ENV TOOLCHAIN_ROOT PATH_SUFFIXES bin)
find_program(COMPILER_ASM astc PATHS ENV TOOLCHAIN_ROOT PATH_SUFFIXES bin)

# 设置编译器
set(CMAKE_C_COMPILER ${COMPILER_C})
set(CMAKE_CXX_COMPILER ${COMPILER_C})
set(CMAKE_ASM_COMPILER ${COMPILER_ASM})

# 设置查找模式
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

# 编译选项
add_compile_options(
  --misrac-version=2012    
  -D__CPU__=tc39xb         # 定义CPU类型
  --iso=99                 # 使用C99标准
  --c++14                  # 使用C++14标准
  --language=+volatile     # 支持volatile关键字
  --exceptions             # 启用异常
  --anachronisms           # 允许使用过时的语法
  --fp-model=3             # 浮点模型
  -O0                      # 优化级别
  --tradeoff=4             # 代码优化权衡
  -Wc-w544 -Wc-w557        # 禁用特定警告
  -Ctc39xb                 # CPU类型
)

# 链接选项
add_link_options(
  -d${PROJECT_SOURCE_DIR}/Lcf_Tasking_Tricore_Tc.lsl  
  -Wl-mc -Wl-mf -Wl-mi -Wl-mk -Wl-ml -Wl-mm -Wl-md -Wl-mr -Wl-mu  
  -Wl--error-limit=42      # 错误限制
  --fp-model=3             # 浮点模型
  --lsl-core=vtc           # 链接脚本核心
  --strict                 # 严格模式
  --anachronisms           # 允许过时语法
  --force-c++              # 强制C++模式
  -Ctc39xb                 # CPU类型
  --format=ihex            # 输出HEX格式
)

3.3.2 CMakeLists.txt(主构建文件)

# 要求CMake版本
cmake_minimum_required(VERSION 3.15)
# 定义项目名称和支持的语言
project(tc397_min_project LANGUAGES CXX C ASM)

# 排除目录
set(EXCLUDE_DIRS "build" "TriCore Debug (TASKING)" "TriCore Release (TASKING)")

# 源文件
set(EXCLUDE_FILES "ert_main.c")
file(GLOB_RECURSE SOURCES
    ${CMAKE_CURRENT_SOURCE_DIR}/*.c
    ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/*.cc
)
# 排除指定目录的文件
foreach(_dir IN ITEMS ${EXCLUDE_DIRS})
    file(GLOB_RECURSE FILES RELATIVE ${PROJECT_SOURCE_DIR} "${_dir}/*")
    list(FILTER SOURCES EXCLUDE REGEX "${_dir}/.*")
endforeach()
# 排除指定文件
foreach(_file IN ITEMS ${EXCLUDE_FILES})
    list(FILTER SOURCES EXCLUDE REGEX "${_file}")
endforeach()

# 包含目录
set(INCLUDE_DIRS "")
file(GLOB_RECURSE FILES RELATIVE ${PROJECT_SOURCE_DIR} "*.h")
foreach(_dir IN ITEMS ${EXCLUDE_DIRS})
    list(FILTER FILES EXCLUDE REGEX "${_dir}/.*")
endforeach()
# 收集所有头文件目录
foreach(_source IN ITEMS ${FILES})
    get_filename_component(_source_path "${_source}" PATH)
    string(REPLACE "/" "\\" _source_path_msvc "${_source_path}")
    list(APPEND INCLUDE_DIRS "${_source_path}")
    # 收集上级目录
    while(NOT "${_source_path}" STREQUAL "")
        get_filename_component(_source_path "${_source_path}" DIRECTORY)
        list(APPEND INCLUDE_DIRS "${_source_path}")
    endwhile()
endforeach()
# 添加根目录
list(APPEND INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}")
# 去重
list(REMOVE_DUPLICATES INCLUDE_DIRS)

# 创建可执行文件
add_executable(${PROJECT_NAME} 
    ${SOURCES}
)

# 设置链接语言
set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE C)
# 设置包含目录
target_include_directories(${PROJECT_NAME} PUBLIC ${INCLUDE_DIRS})

# 构建后复制ELF为HEX
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.elf ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.hex
#   COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.elf
)

4. 构建流程详解

4.1 Windows环境构建(使用脚本)

4.1.1 win.ps1脚本详细功能解析

win.ps1是一个PowerShell脚本,用于在Windows环境下自动化构建TC39x项目。它提供了三个主要功能:构建项目、清理构建文件和显示帮助信息。下面详细解析脚本的每个部分:

function Build {
  $startTime = Get-Date

  $exePath = (Get-Command cctc.exe).Source
  $env:TOOLCHAIN_ROOT = (Split-Path (Split-Path $exePath -Parent) -Parent).Replace("\", "/")
  Write-Host "TOOLCHAIN_ROOT: $env:TOOLCHAIN_ROOT"

  if (!(Test-Path -Path "build")) {
    New-Item -Path "build" -ItemType "directory" -ErrorAction SilentlyContinue
  }

  # cross-compiling toolchain
  $env:CMAKE_TOOLCHAIN_FILE = "$PSScriptRoot\tasking_tricore.cmake"
  Write-Host "CMAKE_TOOLCHAIN_FILE: $env:CMAKE_TOOLCHAIN_FILE"
  
  cmake -B build -G "MinGW Makefiles" .
  $totalLogicalCores = ( `
    (Get-CimInstance -ClassName Win32_Processor).NumberOfLogicalProcessors | `
      Measure-Object -Sum `
  ).Sum
  cmake --build build -- -j $totalLogicalCores

  # if cmake or make failed, exit with the same error code
  if ($LASTEXITCODE -ne 0) {
    exit $LASTEXITCODE
  }

  $endTime = Get-Date
  $timeSpan = New-TimeSpan -Start $startTime -End $endTime
  Write-Host "Build time taken: $($timeSpan.Minutes) minutes $($timeSpan.Seconds) seconds"
}

Build函数功能详解:

  1. 1. 记录构建时间
    • • $startTime = Get-Date:记录构建开始时间
    • • $endTime = Get-Date:记录构建结束时间
    • • $timeSpan = New-TimeSpan -Start $startTime -End $endTime:计算构建耗时
    • • Write-Host "Build time taken: $($timeSpan.Minutes) minutes $($timeSpan.Seconds) seconds":显示构建耗时
  2. 2. 自动检测Tasking编译器路径
    • • $exePath = (Get-Command cctc.exe).Source:获取cctc.exe的完整路径
    • • $env:TOOLCHAIN_ROOT = (Split-Path (Split-Path $exePath -Parent) -Parent).Replace("\", "/"):计算并设置TOOLCHAIN_ROOT环境变量
    • • Write-Host "TOOLCHAIN_ROOT: $env:TOOLCHAIN_ROOT":显示TOOLCHAIN_ROOT路径
  3. 3. 创建构建目录
    • • if (!(Test-Path -Path "build")):检查build目录是否存在
    • • New-Item -Path "build" -ItemType "directory" -ErrorAction SilentlyContinue:如果不存在则创建build目录
  4. 4. 设置工具链文件
    • • $env:CMAKE_TOOLCHAIN_FILE = "$PSScriptRoot\tasking_tricore.cmake":设置CMAKE_TOOLCHAIN_FILE环境变量
    • • Write-Host "CMAKE_TOOLCHAIN_FILE: $env:CMAKE_TOOLCHAIN_FILE":显示工具链文件路径
  5. 5. 生成构建文件
    • • cmake -B build -G "MinGW Makefiles" .:使用MinGW Makefiles生成构建文件
  6. 6. 获取CPU核心数
    • • $totalLogicalCores = (Get-CimInstance -ClassName Win32_Processor).NumberOfLogicalProcessors | Measure-Object -Sum).Sum:获取系统逻辑CPU核心数
  7. 7. 执行构建
    • • cmake --build build -- -j $totalLogicalCores:使用多核并行构建,提高构建速度
  8. 8. 检查构建结果
    • • if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }:如果构建失败,退出并返回错误代码
function Clean {
  if (Test-Path -Path "build") {
    Remove-Item -Path "build" -Recurse -Force
  }
}

Clean函数功能详解:

  • • if (Test-Path -Path "build"):检查build目录是否存在
  • • Remove-Item -Path "build" -Recurse -Force:如果存在则递归删除build目录及其所有内容
function Help {
  Write-Host "Usage: win.ps1 [command]"
  Write-Host "Commands:"
  Write-Host "  build: build the project"
  Write-Host "  clean: clean the project"
  Write-Host "  help: show this help message"
}

Help函数功能详解:

  • • 显示脚本的使用方法和可用命令
if ($args.Length -eq 0) {
  Help
  exit 0
}

switch ($args[0]) {
  "build" {
    Build
  }
  "clean" {
    Clean
  }
  "help" {
    Help
  }
  default {
    Write-Host "Unknown command: $args[0]"
    Help
  }
}

命令行参数处理:

  • • if ($args.Length -eq 0) { Help; exit 0 }:如果没有提供命令行参数,显示帮助信息并退出
  • • switch ($args[0]):根据命令行参数执行相应的函数
    • • “build”:执行Build函数
    • • “clean”:执行Clean函数
    • • “help”:执行Help函数
    • • default:显示错误信息并执行Help函数

4.1.2 win.ps1脚本的优势

  1. 1. 自动化程度高:一键完成整个构建过程,无需手动执行多个命令
  2. 2. 智能检测:自动检测Tasking编译器路径,无需手动设置环境变量
  3. 3. 并行构建:自动获取CPU核心数,使用多核并行构建,提高构建速度
  4. 4. 错误处理:构建失败时会返回错误代码,便于集成到其他脚本中
  5. 5. 构建时间统计:显示构建耗时,便于评估构建性能
  6. 6. 目录管理:自动创建和清理build目录
  7. 7. 命令行友好:提供清晰的帮助信息和命令选项

4.1.3 脚本使用示例

构建项目:

.win.ps1 build

清理构建文件:

.win.ps1 clean

查看帮助信息:

.win.ps1 help

预期输出示例(构建成功):

TOOLCHAIN_ROOT: C:/Tasking/TriCore6.3r1/ctc
CMAKE_TOOLCHAIN_FILE: D:/temp/tc397_min_project/tasking_tricore.cmake
-- The C compiler identification is Tasking 6.3.1.0
-- The CXX compiler identification is Tasking 6.3.1.0
-- The ASM compiler identification is Tasking
-- Found assembler: C:/Tasking/TriCore6.3r1/ctc/bin/astc.exe
-- Configuring done
-- Generating done
-- Build files have been written to: D:/temp/tc397_min_project/build
[  5%] Building C object CMakeFiles/tc397_min_project.dir/Cpu0_Main.c.obj
[ 10%] Building C object CMakeFiles/tc397_min_project.dir/Cpu1_Main.c.obj
[ 15%] Building C object CMakeFiles/tc397_min_project.dir/Cpu2_Main.c.obj
[ 20%] Building C object CMakeFiles/tc397_min_project.dir/Cpu3_Main.c.obj
[ 25%] Building C object CMakeFiles/tc397_min_project.dir/Cpu4_Main.c.obj
[ 30%] Building C object CMakeFiles/tc397_min_project.dir/Cpu5_Main.c.obj
[ 35%] Building C object CMakeFiles/tc397_min_project.dir/Configurations/Ifx_Cfg_Ssw.c.obj
[ 40%] Building C object CMakeFiles/tc397_min_project.dir/Configurations/Ifx_Cfg_SswBmhd.c.obj
[ 45%] Building C object CMakeFiles/tc397_min_project.dir/Configurations/Debug/sync_on_halt.c.obj
[ 50%] Building C object CMakeFiles/tc397_min_project.dir/Libraries/Infra/Platform/Tricore/Compilers/CompilerTasking.c.obj
...
[100%] Linking C executable tc397_min_project.elf
[100%] Built target tc397_min_project
Build time taken: 1 minutes 32 seconds

通过使用win.ps1脚本,开发者可以更加高效地构建TC39x项目,特别是在需要频繁构建的开发过程中,大大提高了工作效率。

4.1.4 执行构建步骤

  1. 1. 打开PowerShell
    • • 按下Win + X,选择”Windows PowerShell”
  2. 2. 进入项目目录cd d:\temp\tc397_min_project
  3. 3. 执行构建命令.\win.ps1 build
  4. 4. 查看构建结果
    • • 构建成功后,在build目录中会生成tc397_min_project.hex文件

4.2 手动构建步骤(不使用脚本)

  1. 1. 打开命令提示符
    • • 按下Win + R,输入cmd,回车
  2. 2. 进入项目目录cd d:\temp\tc397_min_project
  3. 3. 创建build目录mkdir build
    cd build
  4. 4. 生成构建文件cmake -G "MinGW Makefiles" -DCMAKE_TOOLCHAIN_FILE=..\tasking_tricore.cmake ..
  5. 5. 执行构建cmake --build .
  6. 6. 查看构建结果
    • • 构建成功后,会生成tc397_min_project.hex文件

5. CI/CD配置超详细指南

5.1 .gitlab-ci.yml文件详解

# 定义CI流程阶段
stages:
  - build

# 构建任务
tasking_build:
  # 指定Runner标签
  tags:
    - 这里填入服务器设置的tag
  # 所属阶段
  stage: build
  # 触发条件(只在创建Tag时执行)
  only:
    - tags
  # 构建脚本
  script:
    # 设置工具链根目录
    - export TOOLCHAIN_ROOT=/opt/Tasking/TriCore6.3r1/ctc
    # 生成构建文件
    - cmake -B build -DCMAKE_TOOLCHAIN_FILE=tasking_tricore.cmake -G 'Unix Makefiles' .
    # 执行构建,使用多核并行
    - cmake --build build -j$(nproc)
  # 构建产物配置
  artifacts:
    # 保存的路径
    paths:
      - build
    # 过期时间(60天)
    expire_in: '60'
    # 保存条件(构建成功时)
    when: on_success
  # 构建失败时不允许继续
  allow_failure: false

5.2 搭建GitLab CI服务器详细步骤

5.2.1 服务器准备

  1. 1. 选择服务器
    • • 推荐使用Ubuntu 20.04 LTS或CentOS 7
    • • 最低配置:2核CPU,4GB内存,50GB硬盘
    • • 确保服务器可以访问互联网
  2. 2. 安装基础依赖# Ubuntu系统
    sudo apt update
    sudo apt install -y cmake make git curl

    # CentOS系统
    sudo yum update
    sudo yum install -y cmake make git curl

5.2.2 安装Tasking编译器

  1. 1. 上传安装包
    • • 使用SCP或FTP工具将Tasking编译器安装包上传到服务器
    • • 例如:scp Tasking_TriCore_Installer.run user@server:/tmp/
  2. 2. 执行安装# 进入安装包目录
    cd /tmp
    # 添加执行权限
    chmod +x Tasking_TriCore_Installer.run
    # 运行安装程序
    sudo sh Tasking_TriCore_Installer.run
  3. 3. 按照安装向导操作
    • • 选择安装目录(默认:/opt/Tasking/TriCore6.3r1/ctc
    • • 选择安装组件(默认全选)
    • • 等待安装完成

5.2.3 配置环境变量

  1. 1. 编辑系统配置文件sudo nano /etc/profile
  2. 2. 添加环境变量# Tasking编译器环境变量
    export TOOLCHAIN_ROOT=/opt/Tasking/TriCore6.3r1/ctc
    export PATH=$PATH:$TOOLCHAIN_ROOT/bin
  3. 3. 保存并生效# 保存文件(按Ctrl+X,然后按Y,回车)
    source /etc/profile

5.2.4 配置Tasking许可证

  1. 1. 编辑用户配置文件nano ~/.bashrc
  2. 2. 添加许可证环境变量# Tasking许可证
  3. 3. 保存并生效# 保存文件
    source ~/.bashrc

5.2.5 安装并注册GitLab Runner

  1. 1. 安装GitLab Runner# Ubuntu系统
    # 下载并执行GitLab Runner安装脚本
    sudo apt-get install gitlab-runner

    # CentOS系统
    # 下载并执行GitLab Runner安装脚本
    sudo yum install gitlab-runner
  2. 2. 注册Runnersudo gitlab-runner register
  3. 3. 按照提示输入信息
    • • GitLab服务器URL:例如 GitLab服务器地址
    • • 注册令牌:从GitLab项目的Settings → CI/CD → Runners获取
    • • Runner描述:例如 Tasking Build Runner
    • • 标签:例如 tasking,build,tricore
    • • 执行器:选择 shell
  4. 4. 启动Runnersudo gitlab-runner start
  5. 5. 验证Runner状态sudo gitlab-runner status
    • • 显示”gitlab-runner: Service is running!”表示成功

6. 测试CI流程

6.1 创建Tag触发CI

  1. 1. 打开Git Bash
    • • 按下Win + R,输入git bash,回车
  2. 2. 进入项目目录cd d:\temp\tc397_min_project
  3. 3. 提交代码(如果有修改)git add .
    git commit -m "Update code for CI test"
    git push
  4. 4. 创建Taggit tag v1.0.0
    git push origin v1.0.0

6.2 查看CI构建状态

  1. 1. 登录GitLab
    • • 打开浏览器,访问GitLab网站
    • • 登录账号
  2. 2. 进入项目页面
    • • 导航到您的项目
  3. 3. 查看CI/CD状态
    • • 点击左侧菜单中的”CI/CD” → “Pipelines”
    • • 您应该看到一个新的构建任务正在运行
  4. 4. 查看构建日志
    • • 点击构建任务,查看详细的构建日志
    • • 等待构建完成

6.3 下载构建产物

  1. 1. 构建完成后
    • • 点击构建任务中的”Artifacts”部分
    • • 点击”Download”按钮下载构建产物
  2. 2. 查看产物内容
    • • 解压下载的文件
    • • 您应该看到build目录,其中包含生成的tc397_min_project.hex文件

7. 关键技术点解析

7.1 浮点模型设置

Tasking编译器默认使用单精度浮点模型,double会被当作float对待。如果需要修改浮点模型,可以在编译选项中调整--fp-model参数。

7.2 链接脚本配置

链接脚本Lcf_Tasking_Tricore_Tc.lsl定义了内存布局,包括:

  • • 各个CPU核心的栈空间(USTACK、ISTACK、CSA)
  • • 内存分配(DSRAM、PSRAM、PFLS等)
  • • 中断向量表位置
  • • 启动代码位置
  • • BMHD(Boot Mode Header)配置

7.3 静态库集成

如果有第三方静态库或自己创建的静态库,可以在CMakeLists.txt中通过target_link_libraries命令添加:

target_link_libraries(${PROJECT_NAME}
    PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}/libraries/libexample.a
)

7.4 CMake 3.25+新特性

CMake 3.25版本及以后新增了CMAKE_TASKING_TOOLSET变量,简化了Tasking工具链的配置。使用方法:

set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_TASKING_TOOLSET "TriCore")

8. 常见问题与解决方案

8.1 编译器找不到

问题cctc.exe not found

解决方案

  1. 1. 检查Tasking编译器是否正确安装
  2. 2. 确认PATH环境变量是否包含编译器bin目录
  3. 3. 尝试重启电脑使环境变量生效
  4. 4. 手动指定编译器路径:set TOOLCHAIN_ROOT=C:\Tasking\TriCore6.3r1\ctc

8.2 许可证错误

问题:License error: No valid license found

解决方案

  1. 1. 检查许可证密钥是否正确
  2. 2. 确认许可证服务器是否可访问
  3. 3. 验证许可证是否过期
  4. 4. 在群聊中联系我们或者邮件 support@softor.com.cn

8.3 CMake错误

问题:CMake Error at tasking_tricore.cmake

解决方案

  1. 1. 检查tasking_tricore.cmake文件是否存在
  2. 2. 确认TOOLCHAIN_ROOT环境变量是否正确设置
  3. 3. 尝试使用绝对路径指定工具链文件:cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/tasking_tricore.cmake
  4. 4. 检查CMake版本是否满足要求(最低3.15)

8.4 链接错误

问题:Linker error: undefined reference to…

解决方案

  1. 1. 检查源文件是否包含所有必要的函数定义
  2. 2. 确认链接脚本是否正确配置
  3. 3. 检查内存分配是否合理
  4. 4. 查看链接脚本中的内存布局是否与硬件匹配
  5. 5. 检查是否缺少必要的库文件

8.5 CI构建失败

问题:CI构建失败,显示各种错误

解决方案

  1. 1. 查看CI构建日志,确定具体错误原因
  2. 2. 在本地重现构建过程,排查问题
  3. 3. 检查服务器环境是否与本地环境一致
  4. 4. 确认环境变量和许可证配置是否正确
  5. 5. 尝试在服务器上手动执行构建命令,查看具体错误

9. 项目扩展与优化

9.1 添加新功能模块

  1. 1. 创建新的源文件
    • • 在项目目录中创建新的.c.h文件
    • • 例如:src/led.csrc/led.h
  2. 2. 修改CMakeLists.txt
    • • 如果使用了file(GLOB_RECURSE),新文件会自动被包含
    • • 如果手动指定源文件,需要在add_executable中添加新文件
  3. 3. 更新链接脚本
    • • 如果新模块需要特殊的内存布局,可能需要修改Lcf_Tasking_Tricore_Tc.lsl

9.2 优化构建过程

  1. 1. 使用缓存cache:
      paths:
        - build/
    • • 在CI配置中添加缓存,加速构建
  2. 2. 并行构建
    • • 使用-j$(nproc)参数启用多核并行构建
    • • 在本地构建时也可以使用:cmake --build build -- -j8(8核)
  3. 3. 减少构建产物大小
    • • 优化编译选项,例如提高优化级别:-O2-O3
    • • 启用链接时优化:-Wl-Of
    • • 移除调试信息:去掉-g选项

9.3 代码质量检查

  1. 1. 集成静态分析工具
    • • 在CI流程中添加静态分析步骤
    • • 例如使用cppcheck或Tasking编译器的内置静态分析
  2. 2. MISRA C检查
    • • 确保代码符合MISRA C 2012标准
    • • Tasking编译器已启用--misrac-version=2012选项
  3. 3. 单元测试
    • • 集成单元测试框架(如Unity)
    • • 在CI流程中自动运行测试

10. 学习资源

10.1 官方文档

  • • CMake官方文档
  • • CMake Tutorial
  • • CMake Toolchains
  • • Tasking TriCore编译器文档
  • • 英飞凌iLLD库文档

最快的方法直接联系我们: support@softor.com.cn ; tianpengbo@softor.com.cn

11. 总结与展望

通过本教程,您已经掌握了:

  1. 1. 环境搭建:Tasking编译器、CMake、MinGW等工具的安装与配置
  2. 2. 项目结构:了解了TC39x项目的基本结构和关键文件
  3. 3. 构建流程:Windows环境下的构建脚本和手动构建步骤
  4. 4. CI/CD配置:GitLab CI服务器的搭建和配置
  5. 5. 问题排查:常见问题的解决方案
  6. 6. 技术要点:浮点模型、链接脚本、静态库集成等关键技术

未来展望

  1. 1. 自动化测试:集成单元测试和硬件测试
  2. 2. 持续部署:实现自动烧录和测试
  3. 3. 多平台支持:扩展到其他英飞凌微控制器系列
  4. 4. 代码生成:使用代码生成工具提高开发效率
  5. 5. 性能优化:进一步优化编译选项和链接配置

本教程提供了一个完整的英飞凌TC39x项目配置和CI搭建方案,希望能帮助您快速上手并应用到实际项目中。如果您有任何问题或建议,欢迎在评论区留言讨论。


附录:常用命令速查

Windows命令

命令用途示例
cctc --version查看Tasking编译器版本cctc --version
cmake --version查看CMake版本cmake --version
gcc --version查看GCC版本gcc --version
.\win.ps1 build使用脚本构建项目.\win.ps1 build
.\win.ps1 clean清理构建文件.\win.ps1 clean
.\win.ps1 help显示帮助信息.\win.ps1 help

Linux命令

命令用途示例
sudo apt update更新软件包列表sudo apt update
sudo apt install cmake安装CMakesudo apt install cmake
sudo gitlab-runner status查看GitLab Runner状态sudo gitlab-runner status
sudo gitlab-runner start启动GitLab Runnersudo gitlab-runner start
sudo gitlab-runner stop停止GitLab Runnersudo gitlab-runner stop

Git命令

命令用途示例
git tag查看所有Taggit tag
git tag v1.0.0创建Taggit tag v1.0.0
git push origin v1.0.0推送Tag到远程仓库git push origin v1.0.0
git add .添加所有修改到暂存区git add .
git commit -m "message"提交修改git commit -m "Update code"
git push推送到远程仓库git push

CMake命令

命令用途示例
cmake -B build -G "MinGW Makefiles" .生成构建文件cmake -B build -G "MinGW Makefiles" .
cmake --build build执行构建cmake --build build
cmake --build build -- -j8使用8核并行构建cmake --build build -- -j8
cmake -DCMAKE_TOOLCHAIN_FILE=tasking_tricore.cmake ..指定工具链文件cmake -DCMAKE_TOOLCHAIN_FILE=tasking_tricore.cmake ..


版权声明

本教程基于英飞凌TC39x项目示例和Tasking编译器官方文档编写,仅供学习参考。如有错误或不足之处,欢迎指正和改进。

12、关于索弗特

索弗特新能源是翠展集团旗下汽车电子软件工具链专业提供商,2018年成立于浙江嘉兴。公司以“让工具创造便捷与安全”为使命,致力于成为“全球汽车软件安全的卓越企业”。

核心业务:

量产烧录器:打造“快、准、稳”的在线烧录解决方案,兼容英飞凌、瑞萨、NXP、ST等主流芯片,满足车规级产线严苛要求。

汽车软件工具链:提供从需求分析、开发编译到调试测试、量产交付的一站式解决方案,集成TASKING、ISYSTEM、Suresoft等国际顶尖工具,支持ISO26262 ASIL D认证,并联合同星智能、东软睿驰提供TSMaster HIL、AUTOSAR等方案,成本优化40%,已量产超50款车型。

在线留言