CPLD 升级流程介绍说明

openUBMC支持对单板的cpld进行升级,实现在开源组件general_hardware中,本文旨在简单介绍一下升级cpld做了什么,包括支持冷热升级,以及不同链路升级等

概述

CPLD(Complex Programmable Logic Device)升级流程包含四个关键阶段:

  1. Prepare(准备阶段):检查升级条件、解析配置、确定升级模式
  2. Process(执行阶段):解压升级包、烧写固件、保存 valid 文件
  3. Finish(完成阶段):调用生效函数
  4. Valid(生效阶段):执行 valid 文件使固件生效

支持两种升级方式:JTAG 升级I2C 升级。同时支持热升级(无感升级,立即生效)和冷升级(需重启生效)两种模式。

核心文件说明

  • fw_upgrade.lua: 升级入口文件,定义三个阶段的接口
  • process.lua: JTAG 升级具体实现
  • iic_process.lua: I2C 升级具体实现
  • valid.lua: 生效处理模块
  • fw_cfgs.lua: 配置文件解析

CPLD 升级流程顺序图

CPLD 升级包含四个关键阶段:Prepare(准备)→ Process(执行)→ Finish(完成)→ Valid(生效)

支持两种物理链路方式:JTAG 升级I2C 升级

主要区别:

  • JTAG 升级:通过 JTAG 链路烧写,支持单厂家和多厂家模式,支持热升级和冷升级,文件格式为 .vme/.svf
  • I2C 升级:通过 I2C 总线烧写,支持多个厂商,不支持热升级(仅冷升级),文件格式为 .bin

1. JTAG 升级完整流程(Prepare → Process → Finish → Valid)

sequenceDiagram
    participant Framework as 升级框架<br/>(UpdateService)
    participant FwUpgrade as fw_upgrade.lua<br/>(入口模块)
    participant Process as process.lua<br/>(JTAG升级)
    participant Lock as 锁机制
    participant Valid as valid.lua<br/>(生效模块)
    participant CPLD as CPLD硬件

    Note over Framework,CPLD: ========== 阶段 1: PREPARE(准备阶段)==========
    Framework->>FwUpgrade: PrepareUpgrade(system_id, firmware_type, cfg_path)
    
    FwUpgrade->>FwUpgrade: 检查 UPGRADING_FPGA 标志
    alt FPGA正在升级
        FwUpgrade-->>Framework: 返回 OTHERS_UPGRADING 错误
    end
    
    FwUpgrade->>FwUpgrade: 检查 UPGRADING_CPLD 标志
    alt CPLD正在升级
        FwUpgrade-->>Framework: 返回 IN_UPGRADING 错误
    end
    
    FwUpgrade->>FwUpgrade: 设置 UPGRADING_CPLD = 1
    FwUpgrade->>FwUpgrade: 解析 update.cfg 配置文件
    FwUpgrade->>FwUpgrade: 检查 cpld_valid 标志
    
    alt 多厂家模式
        FwUpgrade->>FwUpgrade: check_hot_upgrade()
        Note over FwUpgrade: 判断热升级/冷升级<br/>生成升级列表
    else 单厂家模式
        FwUpgrade->>FwUpgrade: 设置冷升级模式
    end
    
    FwUpgrade->>CPLD: get_fw_version() 获取当前版本
    CPLD-->>FwUpgrade: 返回版本号
    FwUpgrade-->>Framework: 返回 PrepareReply(version, RET.OK)

    Note over Framework,CPLD: ========== 阶段 2: PROCESS(执行阶段 - JTAG)==========
    Framework->>FwUpgrade: ProcessUpgrade(system_id, firmware_type, file_path)
    FwUpgrade->>Process: upgrade_component_cpld()
    
    Process->>Process: extract_upgrade_file() 解压
    Process->>Process: get_applicable_component_fw() 匹配组件
    Process->>Process: secure_tar_unzip() 解压升级包
    
    Process->>CPLD: switch_to_firmware_route() 切换路由
    Process->>Lock: update_chip_lock(600s) 请求芯片锁
    Lock-->>Process: 锁获取成功
    
    alt 单厂家模式 (supplier_mode <= SINGLE)
        Process->>CPLD: load_cpld_single("cpld.vme")
        CPLD-->>Process: 加载成功
        Process->>Valid: init_valid_file("valid.vme")
    else 多厂家模式
        Process->>CPLD: get_cpld_device_info() 获取设备信息
        CPLD-->>Process: 返回芯片信息
        
        alt 某芯片或混合模式
            Process->>CPLD: SetBypassMode(true) 使能bypass
            loop 遍历升级列表 [1,2,3,4...]
                Process->>CPLD: set_upg_cpld_chip(chip_index)
                Process->>CPLD: load_cpld_single("cpld0X.vme")
                CPLD-->>Process: 加载成功
                Process->>Valid: init_valid_file("valid0X.vme")
                Note over Process: 记录到 success_list
            end
        else 按文件数量升级
            Process->>CPLD: SetBypassMode(false) 去使能bypass
            loop 遍历文件 (cpld01~cpld32)
                Process->>CPLD: load_cpld_single("cpld0X.vme")
                CPLD-->>Process: 加载成功
                Process->>Valid: init_valid_file("valid0X.vme")
            end
        end
    end
    
    Process->>Lock: update_chip_unlock() 释放锁
    Lock-->>Process: 解锁成功
    
    alt 升级成功 && 非热升级
        Process->>Valid: set_validating_flag(db, system_id, 1)
    end
    
    Process->>CPLD: switch_to_default_route() 恢复路由
    Process-->>FwUpgrade: 返回 (RET.OK/ERR, is_need_valid)
    
    alt 升级失败
        FwUpgrade->>FwUpgrade: 清除 UPGRADING_CPLD = 0
    end
    
    FwUpgrade-->>Framework: 返回 ProcessReply(result)

    Note over Framework,CPLD: ========== 阶段 3: FINISH(完成阶段)==========
    Framework->>FwUpgrade: FinishUpgrade(system_id, firmware_type)
    
    alt 热升级模式
        Note over FwUpgrade,Valid: ========== 阶段 4: VALID(热升级生效)==========
        FwUpgrade->>Valid: finish_hot_upgrade()
        Valid->>Valid: get_valid_file_list(system_id, hot=true)
        Note over Valid: 目录: /data/opt/bmc/hot_up_cfg
        loop 遍历 valid 文件
            Valid->>CPLD: make_cpld_upg_valid() 执行valid
            Note over CPLD: 拉低管脚复位CPLD,立即生效
            Valid->>Valid: remove_file() 删除valid文件
        end
        Valid->>Valid: task_update_logic_version() 更新版本
        Valid-->>FwUpgrade: 返回成功 (热升级完成,立即生效)
    else 冷升级模式
        Note over FwUpgrade,Valid: ========== 阶段 4: VALID(冷升级生效)==========
        FwUpgrade->>Valid: cpld_valid_task()
        Valid->>Valid: get_validating_flag() 检查生效标志
        Valid->>Valid: 设置 cpld_valid = true
        Valid->>Valid: lock_power_on(300s) 锁定上电
        Valid->>Valid: get_valid_file_list(system_id, hot=false)
        Note over Valid: 目录: /data/opt/bmc/up_cfg
        loop 遍历 valid 文件
            Valid->>CPLD: make_cpld_upg_valid() 执行valid
            Note over CPLD: 写入CPLD Flash
            Valid->>Valid: remove_file() 删除valid文件
        end
        Valid->>Valid: sleep(2s) 等待生效
        Valid->>Valid: set_validating_flag(0) 清除标志
        Valid->>Valid: set_poweron_strategy_exceptions()
        Valid-->>FwUpgrade: 返回成功 (冷升级完成,需重启生效)
    end
    
    FwUpgrade-->>Framework: 升级完成

2. I2C 升级完整流程(Prepare → Process → Finish → Valid)

sequenceDiagram
    participant Framework as 升级框架<br/>(UpdateService)
    participant FwUpgrade as fw_upgrade.lua<br/>(入口模块)
    participant IIC as iic_process.lua<br/>(I2C升级)
    participant SMC as SMC接口
    participant Lock as 锁机制
    participant Valid as valid.lua<br/>(生效模块)
    participant CPLD as I2C芯片

    Note over Framework,CPLD: ========== 阶段 1: PREPARE(准备阶段)==========
    Framework->>FwUpgrade: PrepareUpgrade(system_id, firmware_type, cfg_path)
    
    FwUpgrade->>FwUpgrade: 检查 UPGRADING_FPGA 标志
    alt FPGA正在升级
        FwUpgrade-->>Framework: 返回 OTHERS_UPGRADING 错误
    end
    
    FwUpgrade->>FwUpgrade: 检查 UPGRADING_CPLD 标志
    alt CPLD正在升级
        FwUpgrade-->>Framework: 返回 IN_UPGRADING 错误
    end
    
    FwUpgrade->>FwUpgrade: 设置 UPGRADING_CPLD = 1
    FwUpgrade->>FwUpgrade: 解析 update.cfg (update_link='1')
    FwUpgrade->>FwUpgrade: 检查 cpld_valid 标志
    FwUpgrade->>FwUpgrade: 设置升级模式
    
    FwUpgrade->>CPLD: get_fw_version() 获取当前版本
    CPLD-->>FwUpgrade: 返回版本号
    FwUpgrade-->>Framework: 返回 PrepareReply(version, RET.OK)

    Note over Framework,CPLD: ========== 阶段 2: PROCESS(执行阶段 - I2C)==========
    Framework->>FwUpgrade: ProcessUpgrade(system_id, firmware_type, file_path)
    FwUpgrade->>IIC: iic_upgrade_cpld(db, fw_list, upg_cfg_list, file_path)
    
    IIC->>IIC: extract_upgrade_file() 解压
    IIC->>IIC: get_applicable_component_fw() 匹配组件
    IIC->>IIC: secure_tar_unzip() 解压升级包
    
    IIC->>Lock: i2c_update_chip_lock(600s) 请求总线锁
    Lock-->>IIC: 锁获取成功
    
    IIC->>SMC: get_cpld_upgrade_info()
    SMC-->>IIC: 返回 I2C_UPGRADE_MODE (3)
    
    IIC->>SMC: get_cpld_manufature()
    SMC-->>IIC: 返回厂商类型 + SKU_ID
    
    alt  (manufacture=1)
        Note over IIC,CPLD: I2C 升级流程
        IIC->>IIC: 读取 cpld01.bin 文件
        IIC->>CPLD: set_spi_mode(0xF0) 配置SPI模式
        CPLD-->>IIC: 配置成功
        
        alt SKU_ID == EF2
            Note over IIC: 擦除 4 个扇区 (0~3)
        else 其他SKU
            Note over IIC: 擦除 6 个扇区 (0~5)
        end
        
        loop 擦除扇区
            IIC->>CPLD: set_by_pass() 设置bypass
            IIC->>CPLD: erase_sector(index) 擦除扇区
            CPLD-->>IIC: 擦除成功
            Note over IIC: 等待 400ms
        end
        
        IIC->>CPLD: PluginRequest('iic_upgrade_anlu')
        Note over IIC,CPLD: 写入数据 (0x40000~0x60000字节)
        CPLD-->>IIC: 写入成功
        
    else  (manufacture=2)
        Note over IIC,CPLD:  I2C 升级流程
        IIC->>IIC: 读取 cpld02.bin 文件
        IIC->>CPLD: set_bypass(0) 写使能
        IIC->>CPLD: read_state() 查询状态寄存器
        CPLD-->>IIC: 返回 wake/busy 状态
        
        alt wake == 0
            IIC->>CPLD: set_flash_state(1) 唤醒芯片
            CPLD-->>IIC: 唤醒成功
        end
        
        Note over IIC,CPLD: 开始写入数据 (进度40%~95%)
        loop 传输数据 (每次128字节,从0x38800开始)
            IIC->>CPLD: Write(offset, data) 写入数据
            CPLD-->>IIC: 写入成功
            
            alt 进度增加 >= 5%
                IIC->>Framework: UpdateUpgradeStatus(progress)
            end
        end
        
        IIC->>CPLD: set_flash_state(0) 休眠芯片
        IIC->>CPLD: set_bypass(1) 写去使能
    end
    
    IIC->>Lock: i2c_update_chip_unlock() 释放锁
    Lock-->>IIC: 解锁成功
    
    alt 升级成功
        IIC->>Valid: set_validating_flag(db, system_id, 1)
        IIC->>IIC: log:running(RLOG_INFO, '升级成功')
    else 升级失败
        IIC->>IIC: log:running(RLOG_ERROR, '升级失败')
    end
    
    IIC-->>FwUpgrade: 返回 (RET.OK/ERR, is_need_valid)
    
    alt 升级失败
        FwUpgrade->>FwUpgrade: 清除 UPGRADING_CPLD = 0
    end
    
    FwUpgrade-->>Framework: 返回 ProcessReply(result)

    Note over Framework,CPLD: ========== 阶段 3: FINISH(完成阶段)==========
    Framework->>FwUpgrade: FinishUpgrade(system_id, firmware_type)
    
    Note over FwUpgrade,Valid: ========== 阶段 4: VALID(冷升级生效)==========
    Note over FwUpgrade,Valid: I2C 升级不支持热升级(仅冷升级)
    FwUpgrade->>Valid: cpld_valid_task()
    Valid->>Valid: get_validating_flag() 检查生效标志
    Valid->>Valid: 设置 cpld_valid = true
    Valid->>Valid: lock_power_on(300s) 锁定上电
    Valid->>Valid: get_valid_file_list(system_id, hot=false)
    Note over Valid: 目录: /data/opt/bmc/up_cfg
    
    alt 有 valid 文件
        loop 遍历 valid 文件
            Valid->>CPLD: make_cpld_upg_valid() 执行valid
            Note over CPLD: 写入CPLD Flash
            Valid->>Valid: remove_file() 删除valid文件
        end
    end
    
    Valid->>Valid: sleep(2s) 等待生效
    Valid->>Valid: set_validating_flag(0) 清除标志
    Valid->>Valid: set_poweron_strategy_exceptions()
    Valid-->>FwUpgrade: 返回成功 (冷升级完成,需重启生效)
    
    FwUpgrade-->>Framework: 升级完成

JTAG vs I2C 升级方式对比

对比项 JTAG 升级 I2C 升级
物理链路 JTAG 链路 I2C 总线
配置标识 update_link = ‘0’ update_link = ‘1’
升级模块 process.lua iic_process.lua
厂商支持 单厂家/多厂家/混合模式 多厂家
文件格式 .vme/.svf 文件 .bin 文件
文件命名 单厂家:cpld.vme(valid.vme)/ cpld.svf(valid.svf);
多厂家:cpld01.vme(valid01.vme)/ cpld01.svf(valid01.svf)
cpld.bin
升级模式 热升级 / 冷升级 仅冷升级
Valid文件目录(热) /data/opt/bmc/hot_up_cfg 不涉及
Valid文件目录(冷) /data/opt/bmc/up_cfg 不涉及
生效方式(热) 拉低管脚复位,立即生效 不涉及
生效方式(冷) 写入Flash,需重启生效 写入Flash,需重启生效
锁机制 总线锁 (update_chip_lock) 总线锁 (i2c_update_chip_lock)
Bypass模式 需要 需要
特殊处理 某芯片按chip_id升级 某芯片擦除扇区
唤醒/休眠

四个关键阶段详解

1. Prepare 阶段 (prepare_upgrade)

主要功能

  • 检查升级条件(FPGA、CPLD 是否正在升级)
  • 解析升级配置文件
  • 确定升级模式(热升级/冷升级)
  • 生成升级列表
  • 获取并返回当前版本号

关键逻辑

-- 检查互斥条件
if defs.UPGRADING_FPGA == 1 then
    return RET.OTHERS_UPGRADING  -- FPGA正在升级
end
if defs.UPGRADING_CPLD == 1 then
    return RET.IN_UPGRADING  -- CPLD正在升级
end

-- 设置升级标志
defs.UPGRADING_CPLD = 1

-- 判断热升级或冷升级
if #cfg_list[index].cold_valid_list ~= 0 then
    -- 冷升级,使用 cold_valid_list
elseif #cfg_list[index].hot_valid_list ~= 0 then
    -- 热升级,使用 hot_valid_list
else
    -- 默认冷升级,生成全部 CPLD 列表
end

2. Process 阶段 (process_upgrade)

主要功能

  • 解压升级包
  • 根据链路类型(update_link)选择升级方式(I2C 或 JTAG)
  • 执行实际的固件烧写
  • 保存 valid 文件到指定目录供生效阶段使用

两种升级方式

2.1 JTAG 升级流程

-- 单厂家模式
load_cpld_single(fw, "cpld.vme")  -- 加载单个文件

-- 多厂家模式
if 某芯片 or 混合模式 then
    -- 按芯片 ID 升级
    for chip in upgrade_list do
        设置 bypass 模式
        选择芯片
        加载 cpld{id}.vme
        保存 valid{id}.vme
    end
else
    -- 按文件数量升级
    遍历所有文件加载
end

2.2 I2C 升级流程

-- 获取厂商信息
manufacture = get_cpld_manufature() 

if manufacture == xxx then
    设置 SPI 模式
    擦除 Flash 扇区
    写入升级数据
elseif manufacture == yyy then
    唤醒芯片
    传输数据(分块写入)
    休眠芯片
end

3. Finish 阶段 (finish_upgrade)

主要功能

  • 判断升级模式(热升级/冷升级)
  • 调用对应的生效函数

4. Valid 阶段(生效阶段)

主要功能

  • 执行 valid 文件使固件生效
  • 更新版本信息
  • 清理升级状态

两种生效方式

4.1 热升级生效(无感升级)

-- 拉低管脚复位 CPLD
遍历 valid 文件执行生效
更新逻辑版本号
立即生效,无需重启

函数调用finish_hot_upgrade()cpld_hot_valid()make_cpld_upg_valid()

Valid 文件目录/data/opt/bmc/hot_up_cfg

4.2 冷升级生效(需重启)

-- 设置生效标志,禁止其他 CPLD 升级
cpld_valid = true

-- 锁定上电,禁止上电操作
lock_power_on(300s)

-- 遍历执行 valid 文件
for valid_file in valid_files do
    切换到固件路由
    使能 bypass 模式
    选择对应芯片
    执行 valid 操作
    恢复默认路由
end

-- 需要重启才能生效

函数调用cpld_valid_task()make_cpld_upg_valid()valid_cpld()

Valid 文件目录/data/opt/bmc/up_cfg

状态标志说明

标志 说明
UPGRADING_CPLD CPLD 正在升级标志(全局)
UPGRADING_FPGA FPGA 正在升级标志(全局)
cpld_valid CPLD 正在生效标志(模块级)
ValidatingCpldFlag 数据库中的生效标志(持久化)
cpld_validating 板卡级别的生效标志

升级模式对比

特性 热升级(Hot Upgrade) 冷升级(Cold Upgrade)
生效方式 拉低管脚复位 需要重启系统
业务中断 无感知,立即生效 需要重启才能生效
适用场景 支持热升级的 CPLD 普通 CPLD
Valid 文件目录 /data/opt/bmc/hot_up_cfg /data/opt/bmc/up_cfg
生效函数 finish_hot_upgrade() cpld_valid_task()
上电锁定 不需要 需要锁定上电(300s)
版本更新 task_update_logic_version() 重启后自动更新

错误处理

升级过程中的错误处理机制:

  1. 互斥检查:确保同时只有一个升级任务
  2. 锁机制
    • 芯片锁(600s 超时)
    • 总线锁(I2C 升级)
    • 上电锁(生效阶段)
  3. 失败回滚:升级失败时清除标志,允许重试
  4. 文件校验:检查文件可访问性和大小限制

升级包结构

JTAG 升级包

Firmware1/
├── cpld.vme / cpld.svf   # 单厂家模式
├── valid.vme / valid.svf
或
├── cpld01.vme / cpld01.svf    # 多厂家模式
├── valid01.vme / valid01.svf
├── cpld02.vme / cpld02.svf
├── valid02.vme / valid02.svf
...

I2C 升级包

Firmware1/
├── cpld01.bin
├── cpld02.bin

具体解析涉及解析属性如下:

调用时序

框架 (UpdateService)
    ↓
【阶段 1: PREPARE】
fw_upgrade.prepare_upgrade()
    - 检查 UPGRADING_FPGA、UPGRADING_CPLD 标志
    - 解析 update.cfg 配置
    - check_hot_upgrade() 确定升级模式
    - get_fw_version() 获取版本号
    ↓ 返回 PrepareReply(version, RET.OK)
框架
    ↓
【阶段 2: PROCESS】
fw_upgrade.process_upgrade()
    ↓ 根据 update_link 选择
    ├→ iic_process.iic_upgrade_cpld()      [I2C升级]
    │   - 获取厂商信息
    │   - 烧写固件
    │   - set_validating_flag(1)
    └→ process.upgrade_component_cpld()    [JTAG升级]
        - 加载 cpld 文件到 Flash
        - init_valid_file() 保存 valid 文件
        - set_validating_flag(1)
    ↓ 返回 ProcessReply(result)
框架
    ↓
【阶段 3: FINISH】
fw_upgrade.finish_upgrade()
    ↓ 根据 hot_upgrade 选择
    ├→ finish_hot_upgrade()                [热升级]
    │   ↓
    │  【阶段 4: VALID - 热升级】
    │   - cpld_hot_valid()
    │   - get_valid_file_list(hot=true)
    │   - 目录: /data/opt/bmc/hot_up_cfg
    │   - make_cpld_upg_valid() 执行 valid
    │   - task_update_logic_version()
    │   ↓ 立即生效
    └→ cpld_valid_task()                   [冷升级]
        ↓
       【阶段 4: VALID - 冷升级】
        - get_validating_flag() 检查
        - lock_power_on(300s) 锁定上电
        - get_valid_file_list(hot=false)
        - 目录: /data/opt/bmc/up_cfg
        - make_cpld_upg_valid() 执行 valid
        - set_validating_flag(0) 清除
        ↓ 需重启生效
框架

关键函数调用链

Prepare 阶段

prepare_upgrade()
├── check_hot_upgrade()              # 检查热/冷升级
│   ├── 检查 cold_valid_list
│   ├── 检查 hot_valid_list
│   └── generate_upgrade_list()      # 生成默认列表
└── get_prepare_upgrade_version()    # 获取版本号
    └── get_hot_ver() / get_fw_version()

Process 阶段(JTAG)

process_upgrade()
└── upgrade_component_cpld()
    ├── extract_upgrade_file()       # 解压文件
    ├── get_applicable_component_fw() # 匹配组件
    └── load_cpld_with_lock()
        ├── update_chip_lock()       # 获取锁
        ├── load_cpld()
        │   ├── load_cpld_single()  # 单厂家
        │   └── load_cpld_multi_supplier_mode()
        │       ├── get_cpld_device_info()
        │       ├── load_cpld_with_chip_id()
        │       └── load_cpld_with_file_nums()
        └── update_chip_unlock()     # 释放锁

Process 阶段(I2C)

process_upgrade()
└── iic_upgrade_cpld()
    ├── extract_upgrade_file()
    ├── get_applicable_component_fw()
    └── check_and_upgrade()
        ├── i2c_update_chip_lock()
        ├── i2c_load_cpld()
        │   ├── get_cpld_upgrade_info()
        │   ├── get_cpld_manufature()
        │   ├── upgrade_cpld_anlu()
        │   └── upgrade_cpld_pango()
        └── i2c_update_chip_unlock()

Finish 阶段

finish_upgrade()
├── [热升级] finish_hot_upgrade()
│   └── 调用 Valid 阶段(热升级)
└── [冷升级] cpld_valid_task()
    └── 调用 Valid 阶段(冷升级)

Valid 阶段(热升级)

finish_hot_upgrade()
└── cpld_hot_valid(system_id, signal)
    ├── get_valid_file_list(system_id, hot=true)
    │   └── 目录: /data/opt/bmc/hot_up_cfg
    ├── make_cpld_upg_valid(system_id, fw_list, file)
    │   ├── switch_to_firmware_route()
    │   ├── get_cpld_device_info()
    │   ├── SetBypassMode(true)
    │   ├── set_upg_cpld_chip()
    │   ├── set_cpld_validating_flag(true)
    │   ├── valid_cpld() - 拉低管脚复位
    │   ├── set_cpld_validating_flag(false)
    │   └── switch_to_default_route()
    ├── remove_file() - 删除 valid 文件
    └── task_update_logic_version() - 更新版本

Valid 阶段(冷升级)

cpld_valid_task(signal, system_id)
├── get_validating_flag(db, system_id)
├── 设置 cpld_valid = true
├── lock_power_on(300s) - 锁定上电
├── get_valid_file_list(system_id, hot=false)
│   └── 目录: /data/opt/bmc/up_cfg
├── make_cpld_upg_valid(system_id, fw_list, file)
│   ├── switch_to_firmware_route()
│   ├── get_cpld_device_info()
│   ├── SetBypassMode(true)
│   ├── set_upg_cpld_chip(chip_index-1)
│   ├── set_cpld_validating_flag(true)
│   ├── valid_cpld() - 写入 Flash
│   ├── set_cpld_validating_flag(false)
│   └── switch_to_default_route()
├── remove_file() - 删除 valid 文件
├── sleep(2s) - 等待生效
├── set_validating_flag(0) - 清除标志
└── set_poweron_strategy_exceptions()

注意事项

  1. 升级互斥: 升级互斥,同 链路只能有一个在升级
  2. 生效互斥:冷升级生效期间,禁止其他 CPLD 升级
  3. 上电保护:冷升级生效时锁定上电,防止意外上电
  4. 文件管理:生效后删除 valid 文件,避免重复生效
  5. 超时保护:各种锁都有超时机制,防止死锁
  6. 厂商兼容:支持多厂商 CPLD
  7. 版本管理:升级前获取版本,升级后更新版本信息

总结

CPLD 升级是一个完整的四阶段流程:Prepare → Process → Finish → Valid,涉及多种升级方式和生效模式。

关键点

  1. 四个关键阶段

    • Prepare:检查条件、解析配置、确定模式、获取版本
    • Process:解压升级包、烧写固件、保存 valid 文件
    • Finish:判断升级模式、调用生效函数
    • Valid:执行 valid 文件、更新版本、清理状态
  2. 两种升级方式

    • JTAG 升级:update_link=‘0’,文件格式 .vme/.svf
    • I2C 升级:update_link=‘1’,文件格式 .bin
  3. 两种生效模式

    • 热升级:立即生效,无需重启,目录 /data/opt/bmc/hot_up_cfg
    • 冷升级:需重启生效,目录 /data/opt/bmc/up_cfg
  4. 关键机制

    • 多厂商支持(单厂家、多厂家、混合模式)
    • 锁机制(总线锁、上电锁)
6 个赞