sysfs 文件命名和数据格式标准

libsensors 库通过 sysfs 接口提供对原始传感器数据的访问。自 lm-sensors 3.0.0 起,libsensors 完全与芯片无关。它假定所有内核驱动都实现了本文档中描述的标准 sysfs 接口。这使得添加或更新对任何给定芯片的支持都非常容易,因为 libsensors 和使用它的应用程序无需修改。与 lm-sensors 2 相比,这是一个重大改进。

请注意,主板上与传感器芯片的连接方式差异很大。没有标准可以确保,例如,第二个温度传感器连接到 CPU,或者第二个风扇位于 CPU 上。此外,芯片报告的一些值需要经过计算才能完全理解。例如,大多数芯片只能测量 0 到 +4V 之间的电压。其他电压则通过外部电阻缩放到该范围。由于这些电阻的值可能因主板而异,因此转换不能硬编码到驱动程序中,必须在用户空间中完成。

因此,即使我们致力于开发一个与芯片无关的 libsensors,它仍然需要一个配置文件(例如 /etc/sensors.conf)来进行正确的值转换、输入标签和隐藏未使用的输入。

一些程序使用的另一种方法是直接访问 sysfs 文件。本文档简要描述了驱动程序遵循的标准,以便应用程序能够以简单一致的方式扫描条目并访问这些数据。尽管如此,此类程序必须实现输入的转换、标签和隐藏。因此,仍然不建议绕过库。

每个芯片在 sysfs /sys/devices 树中都有自己的目录。要查找所有传感器芯片,更简单的方法是遵循 /sys/class/hwmon/hwmon* 中的设备符号链接。

在 lm-sensors 3.0.0 之前,libsensors 在“物理”设备目录中查找硬件监控属性。自 lm-sensors 3.0.1 起,hwmon“类”设备目录中找到的属性也受支持。复杂的驱动程序(例如,多功能芯片的驱动程序)可能希望利用此功能来避免命名空间污染。唯一的缺点是旧版本的 libsensors 不支持该驱动程序。

所有 sysfs 值都是定点数。

每个文件只有一个值,这与旧的 /proc 规范不同。文件命名的通用方案是:<type><number>_<item>。传感器芯片的常见类型有“in”(电压)、“temp”(温度)和“fan”(风扇)。常见项目有“input”(测量值)、“max”(高阈值)、“min”(低阈值)。编号通常从 1 开始,除了电压从 0 开始(因为大多数数据表都使用此编号)。对于可以出现多次的元素,即使给定类型在特定芯片上只有一个元素,也总是使用数字。其他文件不引用特定元素,因此它们只有一个简单的名称,没有数字。

警报是直接从芯片读取的指示。驱动程序不进行读数与阈值的比较。这允许捕获读数之间的违规并发出警报。警报的确切定义(例如,是否必须达到或超过阈值才能触发警报)取决于芯片。

设置 hwmon sysfs 属性的值时,必须写入所需值的字符串表示形式,请注意,非数字的字符串将被解释为 0!有关写入字符串如何解释的更多信息,请参阅此文件末尾的“sysfs 属性写入解释”部分。

属性访问

硬件监控 sysfs 属性由不受限制的用户空间应用程序显示。因此,所有标准 ABI 属性都应为全局可读。可写的标准 ABI 属性应仅对特权用户可写。


[0-*]

表示从 0 开始的任何正数

[1-*]

表示从 1 开始的任何正数

RO

只读值

WO

只写值

RW

读/写值

读/写值对于某些芯片可能是只读的,具体取决于硬件实现。

所有条目(名称除外)都是可选的,并且只有在芯片具有该功能时才应在给定驱动程序中创建。

有关属性的完整描述,请参阅ABI 文件测试/sysfs-class-hwmon

全局属性

name

芯片名称。

label

一个描述性标签,允许在系统中唯一标识设备。

update_interval

芯片更新读数的间隔。

电压

in[0-*]_min

电压最小值。

in[0-*]_lcrit

电压临界最小值。

in[0-*]_max

电压最大值。

in[0-*]_crit

电压临界最大值。

in[0-*]_input

电压输入值。

in[0-*]_average

平均电压

in[0-*]_lowest

历史最低电压

in[0-*]_highest

历史最高电压

in[0-*]_reset_history

重置 inX_lowest 和 inX_highest

in_reset_history

重置所有传感器的 inX_lowest 和 inX_highest

in[0-*]_label

建议的电压通道标签。

in[0-*]_enable

启用或禁用传感器。

cpu[0-*]_vid

CPU 核心参考电压。

vrm

电压调节模块版本号。

in[0-*]_rated_min

额定最小电压。

in[0-*]_rated_max

额定最大电压。

另请参阅“警报”部分,了解与电压相关的状态标志。

风扇

fan[1-*]_min

风扇最小值

fan[1-*]_max

风扇最大值

fan[1-*]_input

风扇输入值。

fan[1-*]_div

风扇分频器。

fan[1-*]_pulses

每转风扇的转速计脉冲数。

fan[1-*]_target

期望的风扇速度

fan[1-*]_label

建议的风扇通道标签。

fan[1-*]_enable

启用或禁用传感器。

另请参阅“警报”部分,了解与风扇相关的状态标志。

PWM

pwm[1-*]

脉冲宽度调制风扇控制。

pwm[1-*]_enable

风扇速度控制方法。

pwm[1-*]_mode

直流或脉冲宽度调制。

pwm[1-*]_freq

基本 PWM 频率,单位 Hz。

pwm[1-*]_auto_channels_temp

选择在自动模式下哪些温度通道影响此 PWM 输出。

pwm[1-*]_auto_point[1-*]_pwm / pwm[1-*]_auto_point[1-*]_temp / pwm[1-*]_auto_point[1-*]_temp_hyst

定义 PWM 与温度曲线。

temp[1-*]_auto_point[1-*]_pwm / temp[1-*]_auto_point[1-*]_temp / temp[1-*]_auto_point[1-*]_temp_hyst

定义 PWM 与温度曲线。

还有第三种情况,即跳变点与 PWM 输出通道和温度通道都相关联:PWM 值与 PWM 输出通道相关联,而温度值与温度通道相关联。在这种情况下,结果由温度输入和 PWM 输出之间的映射决定。当多个温度输入映射到给定 PWM 输出时,这会导致多个候选 PWM 值。实际结果取决于芯片,但通常最高的候选值(最快的风扇速度)胜出。

温度

temp[1-*]_type

传感器类型选择。

temp[1-*]_max

温度最大值。

temp[1-*]_min

温度最小值。

temp[1-*]_max_hyst

最大限制的温度滞后值。

temp[1-*]_min_hyst

最小限制的温度滞后值。

temp[1-*]_input

温度输入值。

temp[1-*]_crit

温度临界最大值,通常高于相应的 temp_max 值。

temp[1-*]_crit_hyst

临界限制的温度滞后值。

temp[1-*]_emergency

温度紧急最大值,适用于支持两个以上上限温度的芯片。

temp[1-*]_emergency_hyst

紧急限制的温度滞后值。

temp[1-*]_lcrit

温度临界最小值,通常低于相应的 temp_min 值。

temp[1-*]_lcrit_hyst

临界最小值限制的温度滞后值。

temp[1-*]_offset

芯片添加到温度读数中的温度偏移量。

temp[1-*]_label

建议的温度通道标签。

temp[1-*]_lowest

历史最低温度

temp[1-*]_highest

历史最高温度

temp[1-*]_reset_history

重置 temp_lowest 和 temp_highest

temp_reset_history

重置所有传感器的 temp_lowest 和 temp_highest

temp[1-*]_enable

启用或禁用传感器。

temp[1-*]_rated_min

额定最小温度。

temp[1-*]_rated_max

额定最大温度。

有些芯片使用外部热敏电阻和 ADC 测量温度,并将温度测量结果报告为电压。将此电压转换回温度(或反向用于限制)需要内核中不可用的数学函数,因此转换必须在用户空间中进行。对于这些芯片,上述所有 temp* 文件应包含以毫伏而不是毫摄氏度表示的值。换句话说,这些温度通道由驱动程序作为电压通道处理。

另请参阅“警报”部分,了解与温度相关的状态标志。

电流

curr[1-*]_max

电流最大值。

curr[1-*]_min

电流最小值。

curr[1-*]_lcrit

电流临界低值

curr[1-*]_crit

电流临界高值。

curr[1-*]_input

电流输入值。

curr[1-*]_average

平均电流使用量。

curr[1-*]_lowest

历史最低电流。

curr[1-*]_highest

历史最高电流。

curr[1-*]_reset_history

重置 currX_lowest 和 currX_highest

WO

curr_reset_history

重置所有传感器的 currX_lowest 和 currX_highest。

curr[1-*]_enable

启用或禁用传感器。

curr[1-*]_rated_min

额定最小电流。

curr[1-*]_rated_max

额定最大电流。

另请参阅“警报”部分,了解与电流相关的状态标志。

功率

power[1-*]_average

平均功率使用量。

power[1-*]_average_interval

功率使用平均间隔。

power[1-*]_average_interval_max

最大功率使用平均间隔。

power[1-*]_average_interval_min

最小功率使用平均间隔。

power[1-*]_average_highest

历史平均最大功率使用量

power[1-*]_average_lowest

历史平均最小功率使用量

power[1-*]_average_max

当功率使用量上升到此值以上时,会向 power[1-*]_average 发送轮询通知。

power[1-*]_average_min

当功率使用量下降到此值以下时,会向 power[1-*]_average 发送轮询通知。

power[1-*]_input

瞬时功率使用量。

power[1-*]_input_highest

历史最大功率使用量

power[1-*]_input_lowest

历史最小功率使用量。

power[1-*]_reset_history

重置 input_highest、input_lowest、average_highest 和 average_lowest。

power[1-*]_accuracy

功率计的准确度。

power[1-*]_cap

如果功率使用量上升到此限制以上,系统应采取措施降低功率使用量。

power[1-*]_cap_hyst

围绕功率限制和通知构建的滞后裕度。

power[1-*]_cap_max

可设置的最大功率限制。

power[1-*]_cap_min

可设置的最小功率限制。

power[1-*]_max

最大功率。

power[1-*]_crit

临界最大功率。

如果功率上升到或超过此限制,系统应采取剧烈措施降低功耗,例如系统关机或强制某些设备断电。

单位:微瓦 (microWatt)

RW

power[1-*]_enable

启用或禁用传感器。

禁用时,传感器读取将返回 -ENODATA。

  • 1:启用

  • 0:禁用

RW

power[1-*]_rated_min

额定最小功率。

单位:微瓦 (microWatt)

RO

power[1-*]_rated_max

额定最大功率。

单位:微瓦 (microWatt)

RO

另请参阅“警报”部分,了解与功率读数相关的状态标志。

能量

energy[1-*]_input

累计能量使用量

单位:微焦耳 (microJoule)

RO

energy[1-*]_enable

启用或禁用传感器。

禁用时,传感器读取将返回 -ENODATA。

  • 1:启用

  • 0:禁用

RW

湿度

humidity[1-*]_input

湿度。

humidity[1-*]_enable

启用或禁用传感器。

humidity[1-*]_rated_min

额定最小湿度。

humidity[1-*]_rated_max

额定最大湿度。

警报

每个通道或限制可能有一个关联的警报文件,其中包含一个布尔值。1 表示存在警报条件,0 表示没有警报。

通常,给定芯片会使用通道相关警报或限制相关警报,而不会同时使用两者。驱动程序应仅反映硬件实现。

`in[0-*]_alarm`、`curr[1-*]_alarm`、`power[1-*]_alarm`、`fan[1-*]_alarm`、`temp[1-*]_alarm`

通道警报

  • 0:无警报

  • 1:有警报

RO

或者

`in[0-*]_min_alarm`、`in[0-*]_max_alarm`、`in[0-*]_lcrit_alarm`、`in[0-*]_crit_alarm`、`curr[1-*]_min_alarm`、`curr[1-*]_max_alarm`、`curr[1-*]_lcrit_alarm`、`curr[1-*]_crit_alarm`、`power[1-*]_cap_alarm`、`power[1-*]_max_alarm`、`power[1-*]_crit_alarm`、`fan[1-*]_min_alarm`、`fan[1-*]_max_alarm`、`temp[1-*]_min_alarm`、`temp[1-*]_max_alarm`、`temp[1-*]_lcrit_alarm`、`temp[1-*]_crit_alarm`、`temp[1-*]_emergency_alarm`

限制警报

  • 0:无警报

  • 1:有警报

RO

每个输入通道可能有一个关联的故障文件。这可用于通知开路二极管、未连接的风扇等(如果硬件支持)。当此布尔值为 1 时,该通道的测量值不应被信任。

fan[1-*]_fault / temp[1-*]_fault

输入故障条件。

一些芯片还提供在发生警报时发出蜂鸣声的可能性

beep_enable

主蜂鸣启用。

in[0-*]_beepcurr[1-*]_beepfan[1-*]_beeptemp[1-*]_beep

通道蜂鸣。

理论上,芯片可以提供每个限制的蜂鸣屏蔽,但到目前为止尚未见到此类芯片。

旧驱动程序为警报和蜂鸣提供了不同的、非标准接口。这些接口文件已被弃用,但将保留以保持兼容性

alarms

警报位掩码。

beep_mask

蜂鸣位掩码。

入侵检测

intrusion[0-*]_alarm

机箱入侵检测。

intrusion[0-*]_beep

机箱入侵蜂鸣。

平均采样配置

允许读取 {in,power,curr,temp}_average 值的设备可能会导出属性来控制用于计算平均值的样本数。

samples

设置所有测量类型的平均样本数。

RW

in_samples power_samples curr_samples temp_samples

设置特定测量类型的平均样本数。

请注意,在某些设备上,无法将所有这些值设置为不同的值,因此更改其中一个也可能会更改其他一些值。

RW

sysfs 属性写入解释

hwmon sysfs 属性始终包含数字,因此首先要做的是将输入转换为数字,根据数字是否可以是负数有两种方法

unsigned long u = simple_strtoul(buf, NULL, 10);
long s = simple_strtol(buf, NULL, 10);

其中 buf 是内核传递的用户输入缓冲区。请注意,我们不使用 strto[u]l 的第二个参数,因此无法判断何时返回 0,是确实为 0 还是由无效输入引起。这是有意为之的,因为在所有地方检查这会给内核增加大量代码。

请注意,将转换后的值始终存储在 unsigned long 或 long 中非常重要,这样在进行任何进一步检查之前就不会发生回绕。

在将输入字符串转换为 (unsigned) long 后,应检查其值是否可接受。在检查值有效性之前,请注意对值进行进一步转换,因为这些转换仍可能在检查之前导致回绕。例如,不要将结果相乘,并且只有在加/减之前已进行除法运算时才进行加/减。

如果发现某个值无效,如何处理取决于要设置的 sysfs 属性的类型。如果它是连续设置,例如 tempX_max 或 inX_max 属性,则应使用 clamp_val(value, min_limit, max_limit) 将值钳位到其限制。如果它不是连续的,例如 tempX_type,则当写入无效值时,应返回 -EINVAL。

示例1,temp1_max,寄存器是带符号的 8 位值(-128 - 127 摄氏度)

long v = simple_strtol(buf, NULL, 10) / 1000;
v = clamp_val(v, -128, 127);
/* write v to register */

示例2,风扇分频器设置,有效值为 2、4 和 8

unsigned long v = simple_strtoul(buf, NULL, 10);

switch (v) {
case 2: v = 1; break;
case 4: v = 2; break;
case 8: v = 3; break;
default:
        return -EINVAL;
}
/* write v to register */