传感器适配指南
更新时间:2025/12/3
在Gitcode上查看源码

openUBMC 的传感器功能严格遵循 IPMI 协议的规范,划分为连续型传感器与离散型传感器两大类。

连续型传感器(Continuous Sensor),也称门限传感器或阈值传感器(Threshold Sensor),用于监测可量化且连续变化的物理量,例如温度、电压、电流、风扇转速等。该类传感器读数通过模拟数值表示,并与预设的阈值(Thresholds)进行比较,以判定被监测参数是否处于正常工作范围。

离散型传感器(Discrete Sensor)则输出离散的二进制信号,例如“在位/不在位”、“正常/故障”等。该类传感器不提供具体量化数值,其功能核心在于状态识别与事件触发,即通过判断被监测对象的状态归属,实现相应的事件告警机制。

传感器的配置分为传感器实体配置、传感器对象配置、传感器事件配置、事件过滤配置以及事件描述配置五个方面,具体配置说明可参考传感器定制与开发

各配置项的关系如下图。

本文将以温度、电压传感器及离散传感器为例,分别详细介绍传感器的适配流程。

加载调试工具

i2c-tools 是一个在 Linux 系统下用于操作和管理 I2C 设备的工具,openUBMC 的 bus_tools 仓库提供了类似 i2c-tools 的功能,用于扫描获取I2C总线挂载的设备地址,并可以读写I2C设备寄存器。具体用法可参考bus_tools

  • 下载 bus_tools 仓库
powershell
git clone https://gitcode.com/openUBMC/bus_tools.git
  • 编译 bus_tools 仓库
powershell
cd bus_tools
bingo build
  • 记录 bus_tools 编译的信息,在manifest.yml中添加对该组件的依赖,debug出包就会带上bus_tools所属工具。
yaml
debug_dependencies:
  - conan: bus_tools/1.0.4@openubmc.dev/dev

温度传感器配置示例

本例中,实际的硬件链路拓扑 I2c_9 总线下挂载有 PCA9545 扩展芯片(0x70),PCA9545 的 Channel 0 下挂载了温感芯片 LM75(0x48)。

  • 如果已加载 bus_tools 仓库,即可使用i2cdetect 9命令查询 I2C 9 总线下挂载的设备情况。
  • PCA9545 控制寄存器低四位分别对应四个 Channel,可以通过i2ctransfer使能指定 Channel,查看指定 Channel 下 I2C 设备是否连接正常。

可参考以下命令独立使能 PCA9545 四个channel,若向 PCA9545 写入0x00,则可禁用所有Channel。

Channel ID命令
Channel 0i2ctransfer <i2cbus> w2@0x70 0x00 0x01
Channel 1i2ctransfer <i2cbus> w2@0x70 0x00 0x02
Channel 2i2ctransfer <i2cbus> w2@0x70 0x00 0x04
Channel 3i2ctransfer <i2cbus> w2@0x70 0x00 0x08

以 board name 为 openUBMC 为例,vpd/vendor/Huawei/Server/Kunpeng/openUBMC/root.sr 中配置如下:

  • "ManagementTopology"-> "Anchor"->"Buses" 内增加 "I2c_9"。
  • "I2c_9" 下增加 "Connectors" 配置 "Connector_DemoCard"。
  • "Objects" 内配置 "Connector_DemoCard","IdentifyMode" 配置为 2 表示下一级组件是非天池组件,非天池组件由BomIdAuxId三项配置决定下一级组件 CSR 名称: Bom_Id_AuxId.csr,本例中下一级组件 CSR 名称为 14100513_DemoCard_0.sr
json
{
    ...
    "ManagementTopology": {
        "Anchor": &#123;
            "Buses": [
                ...
                "I2c_9",
                ...
            ]
        &#125;,
	    "I2c_9": &#123;
            "Connectors": [
                "Connector_DemoCard"
            ]
        &#125;
    },
	"Objects": {
	    "I2c_9": &#123;
            "Id": 9
        &#125;,
        "Connector_DemoCard": &#123;
            "Bom": "14100513",
            "Slot": 2,
            "Position": 4,
            "Presence": 1,
            "Id": "DemoCard",
            "AuxId": "0",
            "Buses": [
                "I2c_9"
            ],
            "SystemId": 1,
            "ManagerId": "1",
            "ChassisId": "1",
            "IdentifyMode": 2
        &#125;
    }
}
  • 在 vpd/vendor/Huawei/Server/Kunpeng/openUBMC/ 目录下增加 14100513_DemoCard_0.sr 文件,配置如下:
json
{
    "FormatVersion": "3.00",
    "DataVersion": "3.00",
    "ManagementTopology": {
      "Anchor": &#123;
            "Buses": [
                "I2c_9"
             ]
      &#125;,
      "I2c_9": &#123;
          "Chips": [
              "Pca9545_i2c9_chip"
        ]
      &#125;,
      "Pca9545_i2c9_chip": &#123;
            "Buses": [
               "I2cMux_Pca9545_i2c9_chan0"
        ]
      &#125;,
      "I2cMux_Pca9545_i2c9_chan0": &#123;
        "Chips": [
              "Lm75_InletTemp"
        ]
      &#125;
    },
    "Objects": {
        "Pca9545_i2c9_chip": &#123;
            "OffsetWidth": 0,
            "AddrWidth": 1,
            "Address": 224,
            "WriteTmout": 0,
            "ReadTmout": 0,
            "HealthStatus": 0
        &#125;,
        "I2cMux_Pca9545_i2c9_chan0": &#123;
            "ChannelId": 0
        &#125;,
        "Lm75_InletTemp": &#123;
            "OffsetWidth": 1,
            "AddrWidth": 1,
            "Address": 144,
            "WriteTmout": 0,
            "ReadTmout": 0,
            "HealthStatus": 0
        &#125;,
        "Scanner_Lm75_Inlet": &#123;         // Scanner配置参考《板卡适配》
            "Chip": "#/Lm75_InletTemp",
            "Size": 1,
            "Offset": 0,
            "Mask": 255,
            "Period": 1000
        &#125;,
        "ThresholdSensor_InletTemp": &#123;
            "AssertMask": 29312,
            "DeassertMask": 29312,
            "ReadingMask": 6168,
            "Linearization": 0,
            "M": 100,
            "RBExp": 224,
            "UpperCritical": 43,
            "UpperNoncritical": 41,
            "PositiveHysteresis": 2,
            "NegativeHysteresis": 2,
            "OwnerId": 32,
            "OwnerLun": 0,
            "EntityId": "<=/Entity_InletTemp.Id",
            "EntityInstance": "<=/Entity_InletTemp.Instance",
            "Initialization": 127,
            "Capabilities": 104,
            "SensorType": 1,
            "ReadingType": 1,
            "SensorName": "Inlet Temp",
            "Unit": 128,
            "BaseUnit": 1,
            "ModifierUnit": 0,
            "Analog": 1,
            "MaximumReading": 127,
            "MinimumReading": 128,
            "Reading": "<=/Scanner_Lm75_Inlet.Value",
            "ReadingStatus": "<=/Scanner_Lm75_Inlet.Status"
        &#125;,
        "Entity_InletTemp": &#123;
            "Id": 55,           // id + instance全局唯一
            "Name": "Inlet_Temp",
            "PowerState": 1,
            "Presence": 1,
            "Instance": 98
        &#125;
    }
}

已知传感器通过以下公式将原始值转换成读值,公式中各个参数说明可参考传感器定制与开发

text
temp = (M * x + B * 10K1) * 10K2
y = L(temp)

本例中,由于 RBExp = 224,可知 K1 = 0,K2 = -2。M = 100,B = 0,x = 25,L = 0x00,计算结果:
y = (100 * x + 0 * 0) * 0.01 = 100 * 25 * 0.01 = 25

  • 因新增了CSR文件,需要在 vpd/vendor/Huawei/Server/Kunpeng/openUBMC/profile.txt 中增加 14100513_DemoCard_0.sr 文件所在路径,使后续编译可链接到该 sr 文件。本例中配置如下:
text
Huawei/Server/Kunpeng/openUBMC/14100513_DemoCard_0.sr

调试方法

  • 登录 BMC 环境,输入mdbctl命令进入在线调试终端。

  • 输入attach hwproxy链接hwproxy组件。

  • 根据要跟踪的 chip 对象名,使用tracechip命令跟踪器件读写的数据,本例使用tracechip Lm75_InletTemp_0101 start开始跟踪,使用tracechip Lm75_InletTemp_0101 stop结束跟踪。

    根据返回 read_result:19 70, 可知从 LM75 芯片读取的原始数据为 0x1970。
    lm75_temp = (int16_t)原始数据 / 256
    计算后可知当前 lm75_temp 为 25°C。

  • 使用 busctl 命令可以查看传感器是否已挂载到资源协作接口。

powershell
busctl --user tree bmc.kepler.sensor
busctl --user introspect bmc.kepler.sensor /bmc/kepler/Systems/1/ThresholdSensors/ThresholdSensor_InletTemp_0101

  • 查看页面显示。

ADC 配置示例

ADC 作为一类 bus,需要在 root.sr 中进行声明。在 root.sr 添加对象 Adc_xxx,本例为Adc_1,Adc 类定义如下:

proptypedescription
ScanRateU32ADC采样频率,默认32768
VoltRefSrcU32参考电压类型:0 外部参考电压;1 内部参考电压;默认1
VoltRefValU32参考电压值,单位毫伏

注意:具体对应的 ADC 链路在 Scanner_Adc_x内进行配置,即 Offset:0、1、2、3 分别对应链路 ADC0、ADC1、ADC2、ADC3。

json
{
    ...
    "ManagementTopology": {
        "Anchor": &#123;
            "Buses": [
                ...
                "Adc_1",
                ...
            ]
        &#125;,  
        ...   
        "Adc_1": &#123;
            "Chips": [
                "Chip_Adc_1"
            ]
        &#125;,
        ...
    }, 
    "Objects": {
        ...
        "Adc_1": &#123;
            "ScanRate": 32768,
            "VoltRefSrc": 1,
            "VoltRefVal": 1200
        &#125;,
        "Chip_Adc_1": &#123;
            "Address": 0,
            "AddrWidth": 4,
            "OffsetWidth": 4
        &#125;,
        "Entity_AdcSensor": &#123;
            "Id": 98,
            "Name": "Adc voltage Sensor",
            "PowerState": 1,
            "Presence": 1,
            "Instance": 96
        &#125;,
        "Scanner_Adc_0": &#123;
            "Chip": "#/Chip_Adc_1",
            "Offset": 0,
            "Size": 1,
            "Period": 1000
        &#125;,
        "Scanner_Adc_1": &#123;
            "Chip": "#/Chip_Adc_1",
            "Offset": 1,
            "Size": 1,
            "Period": 1000
        &#125;,
        "Scanner_Adc_2": &#123;
            "Chip": "#/Chip_Adc_1",
            "Offset": 2,
            "Size": 1,
            "Period": 1000
        &#125;,
        "Scanner_Adc_3": &#123;
            "Chip": "#/Chip_Adc_1",
            "Offset": 3,
            "Size": 1,
            "Period": 1000
        &#125;, 
        "ThresholdSensor_AdcSensor": &#123;
            "OwnerId": 32,
            "OwnerLun": 0,
            "EntityId": "<=/Entity_AdcSensor.Id",
            "EntityInstance": "<=/Entity_AdcSensor.Instance",
            "Initialization": 127,
            "Capabilities": 232,
            "SensorType": 2,
            "ReadingType": 1,
            "SensorName": "P1V2",
            "Unit": 0,
            "BaseUnit": 4,
            "ModifierUnit": 0,
            "Analog": 1,
            "NominalReading": 90,
            "NormalMaximum": 0,
            "NormalMinimum": 0,
            "MaximumReading": 127,
            "MinimumReading": 0,
            "Reading": "<=/Scanner_Adc_0.Value |> expr($1 / 5)",
            "AssertMask": 516,
            "DeassertMask": 516,
            "ReadingMask": 4626,
            "Linearization": 0,
            "M": 5,
            "RBExp": 208,
            "UpperCritical": 176,
            "LowerCritical": 144,
            "PositiveHysteresis": 4,
            "NegativeHysteresis": 4
        &#125;,
        ...
    }
}

离散传感器配置示例

离散传感器配置关键点

  • 离散传感器类型SensorType建议按照 IPMI 规范Table 42-, Sensor Type Codes所列举的表格配置。
  • 离散传感器的读值类型ReadingType分为两种:02h~0Ch、6Fh,需要根据离散事件的配置场景相应配置该属性,可参考 IPMI 规范中Table 42, Event/Reading Type Code Ranges
  • 离散传感器的配置需与其所关联的离散事件保持一致,二者应协同配合。尤其应注意Mask相关配置需与离散事件的设置相匹配。

电源状态离散传感器配置示例如下。

json
"DiscreteSensor_PsStatus": {
    "OwnerId": 32,
    "OwnerLun": 0,
    "EntityId": "<=/Entity_PowerSupply.Id",
    "EntityInstance": "<=/Entity_PowerSupply.Instance",
    "Initialization": 99,
    "Capabilities": 192,
    "SensorType": 8,
    "ReadingType": 111,
    "SensorName": "PS${Slot} Status",
    "DiscreteType": 0,
    "Unit": 192,
    "BaseUnit": 0,
    "ModifierUnit": 0,
    "RecordSharing": 1,
    "Reading": 0
}

相关属性取值范围:

  • Capabilities:

离散事件配置关键点

若离散传感器未配置对应的离散事件,则该离散传感器将无法纳入 BMC 的管理范畴。离散事件通常配置于 *_soft.sr 文件中。

  • ListenType 表示离散事件监听方式:

    0:组合监听,表征 SEL 的三个数据和方向均来自于 Property 属性。
    1:独立监听,表征 SEL 的三个数据和方向来自于本对象属性。

  • EventData1、EventData2、EventData3 的应用场景为监听方式是独立监听,配置可参考 IPMI 规范Table 29-, Event Request Message Event Data Field Contents

  • SensorObject 表示离散事件关联的离散传感器,当IPMI SEL产生或者恢复时体现在当前传感器的健康状态以及 SEL 上。

以下为电源状态离散传感器对应的离散事件配置示例。

json
"DiscreteEvent_PsListen0": &#123;
    "Property": 0,
    "ListenType": 1,
    "EventData1": 0,
    "EventData2": 255,
    "EventData3": 255,
    "EventDir": 1,
    "Conversion": 0,
    "SensorObject": "#/DiscreteSensor_PsStatus"
&#125;,
"DiscreteEvent_PsListen1": &#123;
    "Property": 0,
    "ListenType": 1,
    "EventData1": 1,
    "EventData2": 255,
    "EventData3": 255,
    "EventDir": "<=/OnePower_0.Failure",
    "Conversion": 0,
    "SensorObject": "#/DiscreteSensor_PsStatus"
&#125;,
"DiscreteEvent_PsListen2": &#123;
    "Property": 0,
    "ListenType": 1,
    "EventData1": 3,
    "EventData2": 255,
    "EventData3": 255,
    "EventDir": "<=/OnePower_0.LossOfInput",
    "InvalidReadingIgnore": 1,
    "InvalidReading": 255,
    "Conversion": 0,
    "SensorObject": "#/DiscreteSensor_PsStatus"
&#125;

进行如上配置后,电源状态离散传感器即支持以下电源离散事件。

离散传感器页面参数说明

参数描述
序号当前传感器的序号
传感器离散传感器名称
传感器状态离散传感器扫描状态:
Disabled: 表示当前传感器被禁用。
0xXXXX:表示当前传感器状态,是一个16进制数值,具体含义参考IPMI规范中表Table 42-, Sensor Type Codes中字段Sensor specific Offset的解释。例如:
0x8000: 表示当前传感器状态正常,无离散事件触发。
0x8001: 表示当前传感器有事件触发

离散传感器示例实验

将 PSU1 的电源线拔出后,离散传感器 PS1 Status 传感器状态值为 0x8009。

0x8009 的 bit3 的值为1,当前触发离散事件 Power Supply input lost。bit3 即对应 Sensor specific Offset 的 03h。

重新将 PSU1 的电源线插上,离散传感器 PS1 Status 传感器状态值为 0x8001。

传感器事件页面可查询对应事件