OpenBMC:GPIO 控制与状态建模
1. GPIO 在 OpenBMC 中的作用
BMC 通过 GPIO 获取硬件状态或控制外部设备。常见信号包括:
- 电源按键和复位按键
- Power Good
- 电源模块、风扇和扩展板在位状态
- 主机启动状态
- 故障告警
- 机箱入侵
- LED 控制
- 芯片复位和使能
完整链路为:
硬件 GPIO 信号 ↓ GPIO 控制器 ↓ Linux gpiolib ↓ GPIO 使用者或监控服务 ↓ D-Bus 状态对象 ↓ Redfish / IPMI / WebUI2. Linux GPIO 模型
Linux 使用 GPIO Controller 和 GPIO Line 描述 GPIO。
GPIO Controller ├── GPIO Line 0 ├── GPIO Line 1 ├── GPIO Line 2 └── GPIO Line NGPIO 驱动向内核注册gpiochip,其他驱动通过 GPIO Descriptor 使用具体信号。
新代码通常使用 Descriptor 接口:
gpiod_get() gpiod_set_value() gpiod_get_value()用户空间推荐通过libgpiod使用 GPIO。旧版 sysfs GPIO 接口已不适合作为新平台的首选方案。
3. 设备树中的 GPIO 描述
设备树需要描述 GPIO 控制器、引脚编号和有效电平。
power-controller { compatible = "example,power-controller"; power-button-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; reset-button-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; power-good-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; };其中:
&gpio0 GPIO 控制器 10、11、12 GPIO Line 编号 GPIO_ACTIVE_LOW 低电平有效 GPIO_ACTIVE_HIGH 高电平有效驱动按照逻辑值使用 GPIO,不需要再次硬编码有效电平。
GPIO 还可以通过gpio-line-names定义具有硬件含义的名称:
&gpio0 { gpio-line-names = "POWER_BUTTON", "RESET_BUTTON", "POWER_GOOD", "FAN0_PRESENT"; };4. 输入和输出控制
GPIO 输入
输入 GPIO 用于读取硬件状态:
Power Good 风扇在位 电源模块在位 故障告警 机箱入侵状态变化可以通过轮询或中断检测:
GPIO 电平变化 ↓ GPIO 中断 ↓ 内核或用户空间服务接收事件 ↓ 更新 D-Bus 属性GPIO 输出
输出 GPIO用于:
模拟电源按键 触发主机复位 控制设备复位 使能电源 控制 LED控制链路如下:
Redfish / IPMI 请求 ↓ OpenBMC 控制服务 ↓ GPIO Descriptor ↓ GPIO 控制器 ↓ 硬件信号变化对于脉冲信号,还需要定义有效时间和释放顺序。
5. GPIO 状态建模
OpenBMC 通常不会把 GPIO 编号直接暴露给 Redfish,而是将其转换为带有业务含义的 D-Bus 状态。
例如:
GPIO FAN0_PRESENT = 有效 ↓ Inventory.Present = true ↓ Redfish State = Enabled其他常见映射包括:
| GPIO 含义 | D-Bus 建模 |
|---|---|
| Power Good | Chassis PowerState |
| 风扇在位 | Inventory Item Present |
| 故障信号 | OperationalStatus Functional |
| 机箱入侵 | Chassis Intrusion Status |
| 电源模块在位 | PSU Inventory Present |
不同平台可能由 GPIO 监控服务、电源控制服务、风扇服务或平台定制服务完成状态转换。
6. GPIO 事件处理
输入信号可能发生抖动,不能在首次电平变化时立即认定状态已经改变。
常见处理流程:
检测 GPIO 边沿 ↓ 启动防抖定时器 ↓ 再次读取 GPIO ↓ 确认稳定状态 ↓ 更新 D-Bus ↓ 按需生成事件日志GPIO 状态建模还需要明确:
- 上升沿或下降沿触发
- 有效电平
- 防抖时间
- BMC 启动时的初始值
- 主机关机后是否仍然有效
- 信号丢失时的默认状态
7. 总结
OpenBMC GPIO 适配包含三个层次:
设备树:描述 GPIO 连接和有效电平 内核驱动:提供统一 GPIO 接口 用户空间:将 GPIO 转换为设备状态和控制动作GPIO 编号属于底层实现,D-Bus 和 Redfish 应使用电源、在位、故障等业务语义描述硬件状态。