csr升级过程中 写保护始终为高电平

通过代码分析得知每次进行升级都会对写保护状态做关闭操作,但是目前通过示波器显示写保护状态在升级过程中没有变化,始终为高电平。通过手动发送smc命令字关闭写保护可以从示波器上观测到从高电平转变为低电平的现象。

1.代码中实际逻辑也只是简单赋值更新属性,具体调用逻辑是什么?
2.为什么没有在升级过程中观测到写保护从高电平变为低电平?现象是否正常?

答案内容由AI生成,仅供参考:

总结

  • write_protect_proc 的调用流程是标准的:BMC → SRUpgrade 对象 → 设置 WriteProtect 属性 → 通过 Accessor 触发底层控制。
  • 物理写保护电平未变化但升级成功,在当前架构下是可能且合理的,因为:
    • 写保护的实际控制权可能在 MCU;
    • 默认状态下可能允许写入;
    • “关闭写保护”可能是冗余操作,真正需要的是“打开”。
  • 建议强化写保护机制验证,确保在非升级状态下不可随意写入 EEPROM,防止非法篡改配置。
点击此处查看详细分析解答

CSR升级中写保护状态未变化但升级成功的原因分析

根据您提供的信息,关于CSR升级过程中写保护信号(Write Protect)在示波器上始终显示为高电平,但升级依然成功的问题,现从系统架构与代码逻辑两个层面进行详细分析,并解答您的两个核心问题。


1. 代码中write_protect_proc的实际逻辑及调用流程

方法定义

您提供的函数 sr_upgrade:write_protect_proc(protect_value) 是 CSR 升级过程中的关键安全控制逻辑,定义于 sr_upgrade.lua 脚本中,其主要职责是在执行EEPROM写入前关闭写保护,在写入完成后重新开启写保护

function sr_upgrade:write_protect_proc(protect_value)
    local ok, rsp
    for _ = 1, 3 do
        -- 尝试设置 WriteProtect 属性
        ok, rsp = pcall(function ()
            self.mds_obj.WriteProtect = protect_value
        end)
        if not ok then
            log:error('[write_protect_proc] set write protect is [%s] failed, error: %s', protect_value, rsp)
            goto continue
        end
        cmn.skynet.sleep(10)

        -- 验证属性是否已正确设置
        ok, rsp = pcall(function ()
            return self.mds_obj.WriteProtect == protect_value
        end)
        if ok and rsp then
            log:notice('[write_protect_proc] get write protect == %s', protect_value)
            return true
        end
        ::continue::
        cmn.skynet.sleep(500)
    end
    return false
end

调用逻辑与上下文

该函数的完整调用流程如下:

  1. 入口服务sr_upg_service.lua 是整个CSR升级的服务主控模块,作为单例管理所有升级对象。
  2. 升级阶段调用
    • on_upgrade_process() 阶段,系统会调用目标升级对象(如 SRUpgrade)的 upgrade() 方法。
    • 在写入前,先调用 write_protect_proc(false) 关闭写保护;
    • 执行数据写入操作;
    • 写入完成后,调用 write_protect_proc(true) 重新启用写保护。
  3. 属性赋值机制
    • self.mds_obj.WriteProtect = protect_value 实际上是通过 BMC 的对象模型将值写入一个Accessor对象(如 #/Accessor_BCUWP.Value),而非直接操作硬件引脚。
    • 该 Accessor 可能关联一个 SMC/SMBus 控制的写保护芯片,或直接映射到 MCU 控制的 GPIO。

写保护控制的两种方式(来自文档与知识图谱)

根据系统设计,支持两种写保护方式:

控制方式 实现类 说明
直接控制 sr_upgrade 通过 EEPROM 对象自身的 WriteProtect 属性控制
SMBus 控制 sr_upgrade_with_protect_chip 通过独立的写保护控制芯片(SMBus协议)

示例配置(来自KG与DC):

"WriteProtect": "#/Accessor_BCUWP.Value"

这意味着:修改 WriteProtect 属性并不会立即改变物理电平,而是通过中间层(如驱动、SMC服务)转发命令来控制硬件。


2. 为什么未观测到写保护电平变化?现象是否正常?

原因分析

尽管代码逻辑中明确执行了 write_protect_proc(false) 来关闭写保护,但示波器显示电平始终为高(默认保护状态),然而升级仍然成功,可能原因如下:

:white_check_mark: 结论先行:该现象在特定硬件架构下是正常的,关键在于“写保护实际由MCU/SMBus间接控制”而非直接GPIO驱动。

可能原因一:写保护由MCU通过SMC命令间接控制,且“关闭”是默认空操作

  • 在某些硬件设计中,EEPROM 的写保护引脚(WP)默认上拉为高电平(开启保护)。
  • 写保护的“关闭”操作需要发送一条 SMC 命令字(例如 CMD_WRITE_PROTECT_DISABLE)给负责管理该引脚的 MCU。
  • 然而,在实际设计中,系统可能设计为“仅在升级后主动上锁”,而默认状态下写保护是“不激活”的 —— 即 MCU 内部并未开启保护锁存机制。
  • 因此:
    • 即使未发送“disable”命令,EEPROM 实际仍可写入;
    • 只有发送“enable”命令时,MCU 才会真正拉低 WP 引脚或通过内部锁存禁止写入;
    • 所以即使示波器看到 WP 一直为高,只要 MCU 没有执行禁止操作,写入依然成功。

:white_check_mark: 您提到:“手动发送SMC命令关闭写保护时可看到电平变化” —— 这说明 SMC控制器与WP引脚之间存在可编程控制路径,但默认行为可能是“允许写入”,仅在特殊安全模式下才主动启用保护。

可能原因二:Accessor绑定的对象未真实影响硬件电平,仅为软件标记

  • 配置中 "WriteProtect": "#/Accessor_BCUWP.Value" 表示这是一个间接控制。
  • 若 Accessor 的写入操作未被下游服务(如 upgrade_service_mcu 或 SMC 代理)实际处理,则设置此属性不会触发任何硬件动作。
  • 日志中可能出现 [write_protect_proc] get write protect == false 成功返回,但这只是软件层面状态模拟。

可能原因三:EEPROM本身无硬件写保护机制,或写保护功能被屏蔽

  • 某些 EEPROM 芯片虽然有 WP 引脚,但在板级设计中将其接地或悬空,意味着始终允许写入。
  • 或者 WP 引脚受另一个控制器(如 CPLD)控制,且该控制器逻辑未启用写保护。

综合判断与建议

项目 分析结果
升级成功是否合理? :white_check_mark: 合理。只要最终能写入 EEPROM,说明写权限是开放的。物理电平不一定反映真实访问能力。
写保护未变低是否异常? :cross_mark: 不一定异常。取决于硬件设计:若默认开放写入,则无需拉低电平。
当前写保护机制是否有效? :warning: 存在风险。若系统从未真正启用过写保护,则在非升级场景也可能被非法修改。
是否依赖MCU行为? :white_check_mark: 是。多数情况下,WP 引脚由 MCU 通过 SMC 协议控制,BMC 仅下发逻辑指令。

建议排查步骤

  1. 确认硬件设计原理图

    • 查看 EEPROM 的 WP 引脚连接方式:是否接上拉电阻?是否连接到 MCU GPIO?是否经由专用写保护芯片?
    • 确认 WP 引脚有效电平(高有效 or 低有效)。
  2. 抓取SMC通信日志

    • 检查在调用 WriteProtect = false 后,是否有对应的SMC命令发出?
    • 命令是否被目标MCU正确响应?
  3. 检查Accessor实现逻辑

    • 查看 Accessor_BCUWP.Value 的后端实现,是否真的触发了 SMC 调用?
    • 是否存在缓存、过滤或条件判断导致赋值被忽略?
  4. 测试写保护有效性

    • 手动将 WP 引脚拉高(或拉低,依有效电平),尝试写入 EEPROM,验证是否真的被阻止。
    • 若无法阻止写入,则说明写保护机制形同虚设。
  5. 对比 sr_upgradesr_upgrade_with_protect_chip 的使用场景

    • 当前系统是否使用了带 WriteProtectChip 的类?若否,则说明不依赖外部芯片控制写保护。

总结

  • write_protect_proc 的调用流程是标准的:BMC → SRUpgrade 对象 → 设置 WriteProtect 属性 → 通过 Accessor 触发底层控制。
  • 物理写保护电平未变化但升级成功,在当前架构下是可能且合理的,因为:
    • 写保护的实际控制权可能在 MCU;
    • 默认状态下可能允许写入;
    • “关闭写保护”可能是冗余操作,真正需要的是“打开”。
  • 建议强化写保护机制验证,确保在非升级状态下不可随意写入 EEPROM,防止非法篡改配置。

如有具体硬件型号或 Accessor 实现代码,可进一步深入分析。

此处赋值操作赋值的是CSR中配置的SRUpgrade对象的WriteProtect属性。正常配置时,WriteProtect这个属性会关联一个Accessor,例如下面这样:

"SRUpgrade_1": {
    ...
    "WriteProtect": "#/Accessor_xxx.Value",
    ...
}

此时,在代码中给WriteProtect赋值,实际上就会操作此处关联的Accessor,发送该Accessor对象配置的命令字。

对于升级过程中没有观测到电平变化的情况,首先请检查CSR配置中是否配置了WriteProtect属性,且该属性关联的Accessor是否符合预期。如果配置是符合预期的,请再使用mdbctl命令手动向该Accessor中写入Value为1,检查是否能观察到电平变化。

目前认为是问题排查过程中Accessor_CLUWP的偏移量错误改写为11520导致的,已修改回原来的配置11776。

现在还有一个问题,在访问cpld写保护状态时使用了命令:
call Smc_FanBoardSMC_010106 bmc.kepler.Chip.BlockIO Read 0 0x2d00 1
会出现以下两种报错:

可以看到有时候可以正常返回值,有时候出现两种不同报错。这种错误是csr配置错误导致的还是其他原因导致的呢?

两个都是异常吧,一种是未在超时时间等到smc返回的数据;一种是smc返回硬件内部错误,我记得smc返回这个表示smc没在超时时间等到器件返回数据。

请问有具体的解决方法吗