通过代码分析得知每次进行升级都会对写保护状态做关闭操作,但是目前通过示波器显示写保护状态在升级过程中没有变化,始终为高电平。通过手动发送smc命令字关闭写保护可以从示波器上观测到从高电平转变为低电平的现象。
1.代码中实际逻辑也只是简单赋值更新属性,具体调用逻辑是什么?
2.为什么没有在升级过程中观测到写保护从高电平变为低电平?现象是否正常?
通过代码分析得知每次进行升级都会对写保护状态做关闭操作,但是目前通过示波器显示写保护状态在升级过程中没有变化,始终为高电平。通过手动发送smc命令字关闭写保护可以从示波器上观测到从高电平转变为低电平的现象。
1.代码中实际逻辑也只是简单赋值更新属性,具体调用逻辑是什么?
2.为什么没有在升级过程中观测到写保护从高电平变为低电平?现象是否正常?
答案内容由AI生成,仅供参考:
write_protect_proc 的调用流程是标准的:BMC → SRUpgrade 对象 → 设置 WriteProtect 属性 → 通过 Accessor 触发底层控制。根据您提供的信息,关于CSR升级过程中写保护信号(Write Protect)在示波器上始终显示为高电平,但升级依然成功的问题,现从系统架构与代码逻辑两个层面进行详细分析,并解答您的两个核心问题。
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
该函数的完整调用流程如下:
sr_upg_service.lua 是整个CSR升级的服务主控模块,作为单例管理所有升级对象。on_upgrade_process() 阶段,系统会调用目标升级对象(如 SRUpgrade)的 upgrade() 方法。write_protect_proc(false) 关闭写保护;write_protect_proc(true) 重新启用写保护。self.mds_obj.WriteProtect = protect_value 实际上是通过 BMC 的对象模型将值写入一个Accessor对象(如 #/Accessor_BCUWP.Value),而非直接操作硬件引脚。根据系统设计,支持两种写保护方式:
| 控制方式 | 实现类 | 说明 |
|---|---|---|
| 直接控制 | sr_upgrade |
通过 EEPROM 对象自身的 WriteProtect 属性控制 |
| SMBus 控制 | sr_upgrade_with_protect_chip |
通过独立的写保护控制芯片(SMBus协议) |
示例配置(来自KG与DC):
"WriteProtect": "#/Accessor_BCUWP.Value"
这意味着:修改 WriteProtect 属性并不会立即改变物理电平,而是通过中间层(如驱动、SMC服务)转发命令来控制硬件。
尽管代码逻辑中明确执行了 write_protect_proc(false) 来关闭写保护,但示波器显示电平始终为高(默认保护状态),然而升级仍然成功,可能原因如下:
CMD_WRITE_PROTECT_DISABLE)给负责管理该引脚的 MCU。
您提到:“手动发送SMC命令关闭写保护时可看到电平变化” —— 这说明 SMC控制器与WP引脚之间存在可编程控制路径,但默认行为可能是“允许写入”,仅在特殊安全模式下才主动启用保护。
"WriteProtect": "#/Accessor_BCUWP.Value" 表示这是一个间接控制。upgrade_service_mcu 或 SMC 代理)实际处理,则设置此属性不会触发任何硬件动作。[write_protect_proc] get write protect == false 成功返回,但这只是软件层面状态模拟。| 项目 | 分析结果 |
|---|---|
| 升级成功是否合理? | |
| 写保护未变低是否异常? | |
| 当前写保护机制是否有效? | |
| 是否依赖MCU行为? |
确认硬件设计原理图
抓取SMC通信日志
WriteProtect = false 后,是否有对应的SMC命令发出?检查Accessor实现逻辑
Accessor_BCUWP.Value 的后端实现,是否真的触发了 SMC 调用?测试写保护有效性
对比 sr_upgrade 与 sr_upgrade_with_protect_chip 的使用场景
WriteProtectChip 的类?若否,则说明不依赖外部芯片控制写保护。write_protect_proc 的调用流程是标准的:BMC → SRUpgrade 对象 → 设置 WriteProtect 属性 → 通过 Accessor 触发底层控制。如有具体硬件型号或 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没在超时时间等到器件返回数据。
请问有具体的解决方法吗