4. 升级条件检查

任务说明

在OTA升级包下载或安装前,车辆必须处于安全状态。本案例实现一个升级条件检查模块,对电量、车速、挡位、发动机状态和驻车制动五项条件进行校验,全部满足时返回允许升级,否则给出具体拦截原因。

核心实现

// upgrade_condition_check.c
#include <stdbool.h>
#include <string.h>
#include <stdio.h>

typedef enum {
    GEAR_P = 0,
    GEAR_R,
    GEAR_N,
    GEAR_D
} GearPosition;

typedef enum {
    ENGINE_OFF = 0,
    ENGINE_ON
} EngineState;

typedef struct {
    int   soc_percent;       // 电池电量 0-100
    int   vehicle_speed_kmh; // 车速 km/h
    GearPosition gear;       // 挡位
    EngineState   engine;    // 发动机状态
    bool  parking_brake;     // 电子手刹是否拉起
} VehicleStatus;

typedef struct {
    bool  allowed;
    char  reason[128];
} UpgradeDecision;

// 各项条件阈值
#define MIN_SOC_FOR_UPGRADE  30   // 电量需 ≥30%
#define MAX_SPEED_FOR_UPGRADE 0   // 车速必须为 0

static void set_reason(UpgradeDecision *d, const char *msg) {
    strncpy(d->reason, msg, sizeof(d->reason) - 1);
    d->reason[sizeof(d->reason) - 1] = '\0';
}

UpgradeDecision check_upgrade_conditions(const VehicleStatus *v) {
    UpgradeDecision decision = {false, ""};

    if (v == NULL) {
        set_reason(&decision, "invalid vehicle status");
        return decision;
    }

    // 电量检查
    if (v->soc_percent < MIN_SOC_FOR_UPGRADE) {
        set_reason(&decision, "battery SOC too low");
        return decision;
    }

    // 车速检查
    if (v->vehicle_speed_kmh > MAX_SPEED_FOR_UPGRADE) {
        set_reason(&decision, "vehicle is moving");
        return decision;
    }

    // 挡位检查:必须处于 P 挡
    if (v->gear != GEAR_P) {
        set_reason(&decision, "gear not in PARK");
        return decision;
    }

    // 发动机状态检查:必须熄火
    if (v->engine != ENGINE_OFF) {
        set_reason(&decision, "engine is running");
        return decision;
    }

    // 驻车制动检查
    if (!v->parking_brake) {
        set_reason(&decision, "parking brake not engaged");
        return decision;
    }

    decision.allowed = true;
    snprintf(decision.reason, sizeof(decision.reason), "all conditions met");
    return decision;
}

// 测试入口
int main(void) {
    // 用例1:全部满足,应允许升级
    VehicleStatus ok = {65, 0, GEAR_P, ENGINE_OFF, true};
    UpgradeDecision r1 = check_upgrade_conditions(&ok);
    printf("Case1 allowed=%d reason=%s\n", r1.allowed, r1.reason);

    // 用例2:电量不足
    VehicleStatus low_batt = {20, 0, GEAR_P, ENGINE_OFF, true};
    UpgradeDecision r2 = check_upgrade_conditions(&low_batt);
    printf("Case2 allowed=%d reason=%s\n", r2.allowed, r2.reason);

    // 用例3:车速非零
    VehicleStatus moving = {80, 5, GEAR_D, ENGINE_ON, false};
    UpgradeDecision r3 = check_upgrade_conditions(&moving);
    printf("Case3 allowed=%d reason=%s\n", r3.allowed, r3.reason);

    return 0;
}

编译与运行

gcc -o upgrade_check upgrade_condition_check.c
./upgrade_check

验证方法

程序输出应满足以下条件:

  • Case1:allowed=1 reason=all conditions met,表示五项条件全部通过时允许升级。
  • Case2:allowed=0 reason=battery SOC too low,验证电量低于30%时被拦截。
  • Case3:allowed=0 reason=vehicle is moving,验证车速非零时被拦截(即使挡位和发动机状态也不满足,但车速检查优先返回)。

通过条件:三个用例输出与上述预期一致,且拦截原因与触发条件一一对应。如需扩展其他条件组合,可修改main()中的VehicleStatus字段值重新编译验证。

关键说明

  • 检查顺序为电量→车速→挡位→发动机→驻车制动,返回第一个不满足项的原因,便于诊断。
  • 实际工程中,车速信号通常来自CAN总线,电量来自BMS,本案例用结构体字段模拟输入,接入时替换为真实信号读取即可。
  • 阈值MIN_SOC_FOR_UPGRADE和MAX_SPEED_FOR_UPGRADE可按车型策略调整,建议从配置中心读取而非硬编码。