3. 同步节点启动

同步节点启动 学习卡片

任务说明

本案例实现FlexRay同步节点的冷启动(Coldstart)过程。冷启动是同步节点在总线无通信时建立时间基准并进入同步运行状态的关键机制,其核心目标包括:完成冷启动节点(CSN)的启动序列、观测启动帧(Startup Frame)的发送时序、验证节点最终进入同步运行状态(POC state: NORMAL_ACTIVE)并具备参与后续通信的能力。

冷启动序列概述

FlexRay冷启动由同步节点(Sync Node)执行,典型序列如下:

  1. 冷启动节点发送启动帧(Collision Avoidance Symbol, CAS):节点在总线空闲后发送CAS,宣告自身为冷启动发起者;
  2. 发送启动帧对(Startup Frame Pair):在偶数通信周期发送偶数启动帧(A帧),在奇数周期发送奇数启动帧(B帧),形成帧对;
  3. 监听并集成其他节点帧:冷启动节点在发送启动帧后监听总线,若收到其他同步节点的帧,则进入集成过程;
  4. 进入NORMAL_ACTIVE状态:当节点完成至少4个通信周期的集成且时间基准确立后,状态机从COLDSTART_INTEGRATE切换到NORMAL_ACTIVE,同步状态置位。

代码实现

以下代码模拟FlexRay同步节点的冷启动状态机,实现启动序列的核心逻辑,并输出状态转换与关键事件,用于验证冷启动过程是否符合协议规范。


#include <stdio.h>
#include <stdint.h>
#include <string.h>

/* POC状态定义 */
typedef enum {
    POC_DEFAULT_CONFIG,
    POC_READY,
    POC_COLDSTART_LISTEN,
    POC_COLDSTART_COLLISION_RESOLUTION,
    POC_COLDSTART_CONSISTENCY_CHECK,
    POC_COLDSTART_GAP,
    POC_COLDSTART_INTEGRATE,
    POC_NORMAL_ACTIVE,
    POC_NORMAL_PASSIVE
} poc_state_t;

/* 同步节点上下文 */
typedef struct {
    poc_state_t state;
    uint8_t     cycle_counter;      /* 当前通信周期计数 */
    uint8_t     startup_frames_sent; /* 已发送启动帧数量 */
    uint8_t     integrated_cycles;   /* 已成功集成的周期数 */
    uint8_t     sync_state;          /* 同步状态: 1=同步, 0=未同步 */
    uint8_t     cas_sent;            /* CAS是否已发送 */
} sync_node_t;

/* 初始化节点 */
void node_init(sync_node_t *node) {
    node->state = POC_DEFAULT_CONFIG;
    node->cycle_counter = 0;
    node->startup_frames_sent = 0;
    node->integrated_cycles = 0;
    node->sync_state = 0;
    node->cas_sent = 0;
}

/* 状态名映射 */
const char* state_name(poc_state_t s) {
    switch(s) {
        case POC_DEFAULT_CONFIG: return "DEFAULT_CONFIG";
        case POC_READY: return "READY";
        case POC_COLDSTART_LISTEN: return "COLDSTART_LISTEN";
        case POC_COLDSTART_COLLISION_RESOLUTION: return "COLDSTART_COLLISION_RESOLUTION";
        case POC_COLDSTART_CONSISTENCY_CHECK: return "COLDSTART_CONSISTENCY_CHECK";
        case POC_COLDSTART_GAP: return "COLDSTART_GAP";
        case POC_COLDSTART_INTEGRATE: return "COLDSTART_INTEGRATE";
        case POC_NORMAL_ACTIVE: return "NORMAL_ACTIVE";
        case POC_NORMAL_PASSIVE: return "NORMAL_PASSIVE";
        default: return "UNKNOWN";
    }
}

/* 执行冷启动状态机的一个步骤 */
void coldstart_step(sync_node_t *node) {
    switch(node->state) {
        case POC_DEFAULT_CONFIG:
            /* 配置完成后进入READY */
            node->state = POC_READY;
            printf("[Cycle %d] State: DEFAULT_CONFIG -> READY\n", node->cycle_counter);
            break;

        case POC_READY:
            /* 启动命令后进入COLDSTART_LISTEN */
            node->state = POC_COLDSTART_LISTEN;
            printf("[Cycle %d] State: READY -> COLDSTART_LISTEN\n", node->cycle_counter);
            break;

        case POC_COLDSTART_LISTEN:
            /* 监听总线: 若总线空闲超时, 发送CAS并进入碰撞解决 */
            if (!node->cas_sent) {
                node->cas_sent = 1;
                node->state = POC_COLDSTART_COLLISION_RESOLUTION;
                printf("[Cycle %d] Bus idle detected. Sending CAS...\n", node->cycle_counter);
                printf("[Cycle %d] State: COLDSTART_LISTEN -> COLDSTART_COLLISION_RESOLUTION\n", node->cycle_counter);
            }
            break;

        case POC_COLDSTART_COLLISION_RESOLUTION:
            /* 发送启动帧对: 偶数周期发A帧, 奇数周期发B帧 */
            if (node->cycle_counter % 2 == 0) {
                printf("[Cycle %d] Sending Startup Frame A (even cycle)\n", node->cycle_counter);
            } else {
                printf("[Cycle %d] Sending Startup Frame B (odd cycle)\n", node->cycle_counter);
            }
            node->startup_frames_sent++;
            node->state = POC_COLDSTART_CONSISTENCY_CHECK;
            printf("[Cycle %d] State: COLLISION_RESOLUTION -> CONSISTENCY_CHECK\n", node->cycle_counter);
            break;

        case POC_COLDSTART_CONSISTENCY_CHECK:
            /* 检查是否收到其他同步节点的帧 */
            /* 模拟: 在发送2个启动帧后收到其他节点帧 */
            if (node->startup_frames_sent >= 2) {
                printf("[Cycle %d] Received frame from another sync node. Integration possible.\n", node->cycle_counter);
                node->state = POC_COLDSTART_GAP;
                printf("[Cycle %d] State: CONSISTENCY_CHECK -> COLDSTART_GAP\n", node->cycle_counter);
            } else {
                /* 未收到其他节点帧, 继续发送启动帧 */
                node->state = POC_COLDSTART_COLLISION_RESOLUTION;
                printf("[Cycle %d] No external frame. Continue sending startup frames.\n", node->cycle_counter);
            }
            break;

        case POC_COLDSTART_GAP:
            /* 等待一个通信周期, 进入集成阶段 */
            node->state = POC_COLDSTART_INTEGRATE;
            printf("[Cycle %d] State: COLDSTART_GAP -> COLDSTART_INTEGRATE\n", node->cycle_counter);
            break;

        case POC_COLDSTART_INTEGRATE:
            /* 集成阶段: 持续接收帧并建立时间基准 */
            node->integrated_cycles++;
            printf("[Cycle %d] Integrating... (integrated cycles: %d)\n", 
                   node->cycle_counter, node->integrated_cycles);
            
            if (node->integrated_cycles >= 4) {
                /* 完成4个周期集成, 进入NORMAL_ACTIVE */
                node->state = POC_NORMAL_ACTIVE;
                node->sync_state = 1;
                printf("[Cycle %d] Integration complete. Entering NORMAL_ACTIVE.\n", node->cycle_counter);
                printf("[Cycle %d] State: COLDSTART_INTEGRATE -> NORMAL_ACTIVE\n", node->cycle_counter);
                printf("[Cycle %d] *** SYNC STATE: SYNCHRONIZED ***\n", node->cycle_counter);
            }
            break;

        case POC_NORMAL_ACTIVE:
            /* 正常运行: 每个周期递增计数 */
            printf("[Cycle %d] NORMAL_ACTIVE: sync maintained.\n", node->cycle_counter);
            break;

        default:
            break;
    }
}

/* 推进一个通信周期 */
void advance_cycle(sync_node_t *node) {
    node->cycle_counter++;
    printf("--- Cycle %d start ---\n", node->cycle_counter);
    coldstart_step(node);
}

int main() {
    sync_node_t node;
    node_init(&node);

    printf("=== FlexRay Sync Node Coldstart Simulation ===\n\n");

    /* 模拟冷启动过程: 运行足够周期直到进入NORMAL_ACTIVE */
    int max_cycles = 20;
    int cycle = 0;

    /* 初始状态转换 */
    coldstart_step(&node);  /* DEFAULT_CONFIG -> READY */
    coldstart_step(&node);  /* READY -> COLDSTART_LISTEN */

    /* 主循环: 推进周期直到同步 */
    while (node.state != POC_NORMAL_ACTIVE && cycle < max_cycles) {
        advance_cycle(&node);
        cycle++;
    }

    /* 若已同步, 再运行2个周期展示稳定状态 */
    if (node.state == POC_NORMAL_ACTIVE) {
        printf("\n=== Coldstart successful. Running 2 more cycles to verify stability ===\n");
        advance_cycle(&node);
        advance_cycle(&node);
    }

    printf("\n=== Simulation End ===\n");
    printf("Final state: %s\n", state_name(node.state));
    printf("Sync status: %s\n", node.sync_state ? "SYNCHRONIZED" : "NOT SYNCHRONIZED");
    printf("Startup frames sent: %d\n", node.startup_frames_sent);
    printf("Integrated cycles: %d\n", node.integrated_cycles);

    return 0;
}

编译与运行

将上述代码保存为 coldstart.c,使用任意C编译器编译并运行:


gcc -o coldstart coldstart.c
./coldstart

验证方法与判定标准

运行程序后,观察输出序列,按以下标准判定冷启动过程是否正确实现:

  • 状态序列正确性:状态转换路径应为 DEFAULT_CONFIG → READY → COLDSTART_LISTEN → COLDSTART_COLLISION_RESOLUTION → CONSISTENCY_CHECK → COLDSTART_GAP → COLDSTART_INTEGRATE → NORMAL_ACTIVE,中间可能因未收到外部帧而循环回COLLISION_RESOLUTION继续发送启动帧;
  • 启动帧发送规则:偶数周期发送A帧,奇数周期发送B帧,且启动帧对数量不少于2个;
  • 集成周期数:在COLDSTART_INTEGRATE状态至少完成4个周期的集成后才进入NORMAL_ACTIVE;
  • 同步状态置位:进入NORMAL_ACTIVE后,sync_state变为1,输出“SYNC STATE: SYNCHRONIZED”;
  • 稳定运行:进入NORMAL_ACTIVE后继续运行2个周期,状态保持NORMAL_ACTIVE且同步状态不丢失。

若输出满足以上全部条件,则判定冷启动过程实现正确,节点成功建立同步并进入正常运行状态。

FlexRay同步节点冷启动状态机 DEFAULT_CONFIG READY COLDSTART_LISTEN COLLISION_RESOLUTION CONSISTENCY_CHECK COLDSTART_GAP COLDSTART_INTEGRATE NORMAL_ACTIVE (同步状态) 配置完成 启动命令 总线空闲, 发CAS 未收到外部帧, 继续发送 收到外部帧 等待1周期 集成≥4周期 同步建立 集成中(周期<4) 偶数周期发A帧, 奇数周期发B帧 | 集成周期数≥4后进入NORMAL_ACTIVE