风扇手动模式下,插拔风扇,风扇类型识别错误

问题描述

bmc版本25.09下,先设置风扇手动模式下,插拔风扇,风扇类型识别错误。

先设置风扇自动模式下,插拔风扇,风扇类型识别是正常的。

步骤:

1.先手动设置风扇转速比为百分之50。

2.然后插拔风扇,让风扇重新识别类型,发现识别过程中,风扇设置的转速是百分之50,不是sr文件里面IdentifySpeedLevel的数值(我设置是百分之35),导致转速偏高,没有落在正确的风扇类型识别的转速区间里面。

在代码盘查是local ok, err_msg = pcall(self.set_pwm, self, self.IdentifySpeedLevel)这个代码没有起作用。

然后在filter_type_by_speed()函数里面打印self.HardwarePWM的值发现是手动设置的占空比的值128(百分之50),不是IdentifySpeedLevel的数值。

3.如果是风扇自动模式下,插拔风扇,风扇类型识别是正常的,在filter_type_by_speed()函数里面打印self.HardwarePWM的值发现就是IdentifySpeedLevel对应的数值了。

期望结果

希望风扇手动模式下,插拔风扇,风扇类型识别也是正常的。

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

风扇手动模式下插拔风扇导致类型识别错误的问题分析与解决方案

问题描述

BMC 版本 25.09 下,当风扇处于手动模式时执行插拔操作,会导致风扇类型识别失败。然而,在自动模式下进行相同操作时,识别正常。

具体现象:

  • 手动设置风扇转速为50%(对应 PWM 值 128)。
  • 插拔风扇后,系统尝试重新识别风扇型号。
  • 识别过程中,风扇实际运行速度为50%,而非配置的 IdentifySpeedLevel=35%
  • 由于转速未落在预期的识别区间(IdentifyRangeLow ~ IdentifyRangeHigh),导致识别失败。
  • 日志显示关键代码行 local ok, err_msg = pcall(self.set_pwm, self, self.IdentifySpeedLevel) 未生效。
  • filter_type_by_speed() 函数中打印 self.HardwarePWM 的值仍为 128(即50%),而非识别所需的35%。

相比之下,在自动模式下插拔风扇,识别过程能正确使用 IdentifySpeedLevel 设定值,识别成功。


问题根因分析

根据知识图谱和文档内容,该问题的核心在于:风扇类型识别流程未能覆盖手动模式下的控制逻辑异常情况。

1. 风扇识别基本流程

从文档 1 中可知,风扇型号识别流程如下:

1. **备选池构建**:由 FanType 配置决定可能的风扇型号列表。
2. **设定识别速度**:通过 `IdentifySpeedLevel` 属性设定测试 PWM 值(如 35%)。
3. **检测实际转速**:观察风扇在此 PWM 下的实际转速是否处于 `IdentifyRangeLow` 和 `IdentifyRangeHigh` 区间内。
4. **类型判定**:若转速符合某一 FanType 的范围,则认定为该类型。

:white_check_mark: 配置说明

  • IdentifySpeedLevel:识别时使用的 PWM 百分比,当前设为 35
  • IdentifyRangeLow:识别速度下限,当前为 3230 RPM
  • IdentifyRangeHigh:识别速度上限,当前为 4750 RPM

2. 关键代码分析

fan_object.lua 第437行的代码:

local ok, err_msg = pcall(self.set_pwm, self, self.IdentifySpeedLevel)

这行代码的目的是将风扇 PWM 设置为 IdentifySpeedLevel(35%),以便在标准条件下进行识别。

但实际测试发现:

  • 手动模式下,此设置未生效
  • self.HardwarePWM 的值仍然是手动设置的 128(50%)
  • 表明该 set_pwm 调用失败或被后续逻辑覆盖。

3. 可能原因分析

原因 依据
手动模式优先级高于识别逻辑 手动模式通常绕过自动控制策略,直接通过硬件寄存器设置 PWM(如 Accessor_Fan1_PWM.Value)。即使 set_pwm 被调用,也可能立即被手动模式控制逻辑重写。
风扇识别流程未处理手动模式场景 根据文档流程设计,所有识别都应在特定 PWM(IdentifySpeedLevel)下进行,但未明确排除或接管手动模式下的控制权。
set_pwm 调用被其他任务打断 文档中提到:“需要排查是否在风扇转速识别过程中没正确拦截其余 PWM 设置任务” —— 这正是本场景的情况。
HardwarePWM 来源于寄存器而非期望值 Accessor_Fan1_PWM.Value 是硬件真实值,若手动模式持续写入寄存器,则 self.HardwarePWM 返回的是当前寄存器值,而非识别策略设定值。

问题定位总结

:warning: 根本原因
手动模式下,风扇控制直接作用于硬件寄存器(如 Accessor_Fan1_PWM.Value),而风扇型号识别流程中的 set_pwm(self.IdentifySpeedLevel) 调用未能抢占控制权或被立即覆盖,导致识别阶段风扇仍运行在手动设定的50% PWM 状态,偏离了识别所需的标准工作点(35%),从而造成速度超出 IdentifyRangeLow ~ IdentifyRangeHigh 范围,最终导致识别失败。


解决方案建议

:white_check_mark: 方案一:【推荐】识别前强制临时进入“识别专用模式”

修改 fan_identify 流程,在开始识别前 临时退出手动模式,切换至内部识别控制模式。

function fan_obj_manager:fan_identify(identify_cnt)
    -- 记录原始模式
    local original_mode = self.current_mode
    
    -- 1. 强制切换至识别模式(禁用手动干预)
    self:enter_identify_mode()  -- 新增方法:暂停手动控制,允许 set_pwm 生效

    -- 2. 将所有可能的型号加入备选池
    self.model_pool = c_fan_type.collection:fetch_by_position(self:get_position())

    -- 3. 设置识别速度
    local ok, err_msg = pcall(self.set_pwm, self, self.IdentifySpeedLevel)
    if not ok then
        log:error('Set the pwm of %s failed, err_msg:%s', self.ObjectName, err_msg)
        self:restore_mode(original_mode)  -- 还原原始模式
        return false
    end

:light_bulb: 实现要点:

  • enter_identify_mode() 应暂停所有来自 IPMI 或用户的手动控制任务。
  • 可通过锁定 HardwarePWM 控制权或设置内部标志位实现。

:white_check_mark: 方案二:增强 set_pwm 的优先级与同步机制

确保 set_pwm 具备更高优先级,能够覆盖当前手动设置。

建议改进点:

  1. 在调用 set_pwm发送信号暂停其它 PWM 控制线程
  2. 使用底层函数 SetFanHardwarePWM 直接设置硬件 PWM,绕过策略层限制。
  3. 添加延时等待硬件稳定后再读取实际值验证。
-- 使用硬件级写入确保生效
local ok, err = pcall(SetFanHardwarePWM, self.FanId, self.IdentifySpeedLevel)
if not ok then
    log:error("Failed to force set HardwarePWM for identification")
    return false
end

-- 延时等待风扇响应
sys.wait(500)  -- ms

-- 验证是否已设置成功
if self.HardwarePWM ~= expected_pwm then
    log:warning("HardwarePWM mismatch after set: expected=%d, actual=%d",
                expected_pwm, self.HardwarePWM)
end

:white_check_mark: 方案三:日志与诊断增强(辅助定位)

在识别流程中增加关键字段的日志输出:

log:info("Fan identification start: FanId=%d, IdentifySpeedLevel=%d%%, CurrentMode=%s, HardwarePWM=%d",
         self.FanId, self.IdentifySpeedLevel, self.current_mode, self.HardwarePWM)

便于快速判断是设置失败还是读取异常。


验证方法

步骤 预期行为
1. 设置风扇手动 50%,重启识别 HardwarePWM 初始为 128
2. 进入 fan_identify 流程 日志显示调用 set_pwm(35)
3. 执行 filter_type_by_speed() HardwarePWM 应为 89(≈35% × MaxSupportedPWM)
4. 转速落入 3230~4750 RPM 区间 成功匹配目标 FanType
5. 最终识别结果 输出 identify fan%d model successfully

结论

:end_arrow: 结论
本问题是由 手动模式与风扇识别流程间的控制权冲突 引发的典型设计缺陷。尽管识别逻辑要求固定 PWM(35%)以保证准确性,但在手动模式下该设定无法覆盖用户级别的硬件 PWM 写入,导致识别条件不满足。

:white_check_mark: 建议解决路径

  1. 修改识别流程,在识别开始前临时接管控制权
  2. 使用 SetFanHardwarePWM 强制设定 PWM
  3. 增强日志输出,便于后续问题追踪;
  4. 考虑在 SR 配置中增加对“识别期间禁止手动模式干预”的约束说明。

:pushpin: 最终目标:无论风扇当前处于何种模式,只要触发识别流程,系统必须保证其运行在 IdentifySpeedLevel 指定的 PWM 条件下,以确保识别的准确性与一致性。

相关链接:

  1. 风扇适配指导
  2. 风扇型号信息是否有明确的定义标准或文档支撑信息查询和校验
  3. 风扇智能调速概率性失效的问题
  4. 添加一条IPMI命令实操分享——设置所需的风扇速度

麻烦提供下问题的一键收集日志

方便提供一下您的邮箱吗?我将完整日志打包发送给您。

日志发送给PAE