3. 配置UniPro链路层参数

配置UniPro链路层参数 学习卡片

任务目标

编写代码配置UniPro链路层参数(数据速率、通道数、扰码使能),并回读当前配置以确认参数已正确生效。本案例聚焦于链路层参数的结构定义、写入与读取验证,不涉及PHY层或DME底层寄存器操作的具体时序。

核心实现

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

/* UniPro链路层参数结构 */
typedef struct {
    uint32_t data_rate;        /* 单位: Mbps, 例如 2400 表示 2.4Gbps */
    uint8_t  lane_count;       /* 通道数: 1/2/4 */
    uint8_t  scrambling_en;    /* 扰码使能: 0-关闭, 1-开启 */
    uint8_t  tx_gear;          /* TX 速率档位 (Gear) */
    uint8_t  rx_gear;          /* RX 速率档位 (Gear) */
} unipro_link_cfg_t;

/* 模拟寄存器映射 (实际项目中映射到DME寄存器) */
static unipro_link_cfg_t g_link_regs = {0};

/* 写入链路层配置 */
int unipro_link_config(const unipro_link_cfg_t *cfg)
{
    if (!cfg) return -1;
    if (cfg->lane_count != 1 && cfg->lane_count != 2 && cfg->lane_count != 4) {
        printf("Error: invalid lane count %u\n", cfg->lane_count);
        return -1;
    }
    if (cfg->scrambling_en > 1) {
        printf("Error: invalid scrambling setting %u\n", cfg->scrambling_en);
        return -1;
    }
    /* 实际项目中此处通过DME Set()命令写入PHYAdapter寄存器 */
    g_link_regs = *cfg;
    return 0;
}

/* 读取当前链路层配置 */
int unipro_link_get_config(unipro_link_cfg_t *out)
{
    if (!out) return -1;
    /* 实际项目中此处通过DME Get()命令读取 */
    *out = g_link_regs;
    return 0;
}

/* 打印配置 */
static void print_cfg(const char *tag, const unipro_link_cfg_t *cfg)
{
    printf("%s: rate=%uMbps lanes=%u scrambling=%s tx_gear=%u rx_gear=%u\n",
           tag, cfg->data_rate, cfg->lane_count,
           cfg->scrambling_en ? "ON" : "OFF",
           cfg->tx_gear, cfg->rx_gear);
}

int main(void)
{
    unipro_link_cfg_t cfg = {
        .data_rate = 2400,      /* 2.4Gbps */
        .lane_count = 2,        /* 双通道 */
        .scrambling_en = 1,     /* 开启扰码 */
        .tx_gear = 3,           /* Gear 3 */
        .rx_gear = 3
    };

    printf("=== UniPro Link Layer Config Test ===\n");

    /* 1. 写入配置 */
    if (unipro_link_config(&cfg) != 0) {
        printf("Config failed\n");
        return 1;
    }
    print_cfg("Written", &cfg);

    /* 2. 回读验证 */
    unipro_link_cfg_t readback;
    if (unipro_link_get_config(&readback) != 0) {
        printf("Readback failed\n");
        return 1;
    }
    print_cfg("Readback", &readback);

    /* 3. 逐字段比对 */
    int ok = 1;
    if (readback.data_rate != cfg.data_rate) {
        printf("Mismatch: data_rate\n");
        ok = 0;
    }
    if (readback.lane_count != cfg.lane_count) {
        printf("Mismatch: lane_count\n");
        ok = 0;
    }
    if (readback.scrambling_en != cfg.scrambling_en) {
        printf("Mismatch: scrambling_en\n");
        ok = 0;
    }
    if (readback.tx_gear != cfg.tx_gear || readback.rx_gear != cfg.rx_gear) {
        printf("Mismatch: gear\n");
        ok = 0;
    }

    if (ok) {
        printf("PASS: All parameters verified\n");
        return 0;
    } else {
        printf("FAIL: Parameter mismatch detected\n");
        return 1;
    }
}

编译与运行

gcc -o unipro_link_test unipro_link_test.c
./unipro_link_test

验证方法

程序执行后,观察输出中Written与Readback两行配置是否完全一致,并以PASS作为最终判定。若出现FAIL或字段不匹配提示,说明配置写入或读取链路存在问题。

预期输出

=== UniPro Link Layer Config Test ===
Written: rate=2400Mbps lanes=2 scrambling=ON tx_gear=3 rx_gear=3
Readback: rate=2400Mbps lanes=2 scrambling=ON tx_gear=3 rx_gear=3
PASS: All parameters verified

关键说明

  • 本示例使用内存结构体模拟DME寄存器读写。实际项目中,unipro_link_config()内部应通过DME Set()命令将参数写入PHYAdapter寄存器(如PA_ActiveTxDataRate、PA_ActiveRxDataRate、PA_LaneCount等),unipro_link_get_config()则通过DME Get()命令读取。
  • 数据速率与Gear档位的映射关系由具体UniPro版本决定,本示例仅做参数传递与校验,不涉及速率-档位换算逻辑。
  • 参数校验仅覆盖通道数和扰码使能的基本合法性,实际驱动中还需增加速率范围、Gear组合等更完整的边界检查。