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 规范不同。文件命名的常用方案是:<类型><数字>_<项目>。传感器芯片的常用类型是“in”(电压)、“temp”(温度)和“fan”(风扇)。常用项目是“input”(测量值)、“max”(高阈值)和“min”(低阈值)。编号通常从 1 开始,但电压从 0 开始(因为大多数数据表都使用此编号)。数字始终用于可以多次出现的元素,即使特定芯片上只有一个给定类型的元素。其他文件不引用特定元素,因此它们具有简单的名称,没有数字。

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

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

属性访问

硬件监控 sysfs 属性由无限制的用户空间应用程序显示。因此,所有标准 ABI 属性都应是世界可读的。可写的标准 ABI 属性只能由特权用户写入。


[0-*]

表示从 0 开始的任何正数

[1-*]

表示从 1 开始的任何正数

只读

只读值

只写

只写值

读/写

读/写值

根据硬件实现,对于某些芯片,读/写值可能是只读的。

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

有关属性的完整描述,请参阅 Documentation/ABI/testing/sysfs-class-hwmon。

全局属性

名称

芯片名称。

标签

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

更新间隔

芯片更新读数的间隔。

电压

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

只写

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

临界最大功率。

如果功率上升到此限制或以上,系统应采取紧急措施来降低功耗,例如系统关机或强制关闭某些设备的电源。

单位:微瓦

读/写

power[1-*]_enable

启用或禁用传感器。

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

  • 1:启用

  • 0:禁用

读/写

power[1-*]_rated_min

最小额定功率。

单位:微瓦

只读

power[1-*]_rated_max

最大额定功率。

单位:微瓦

只读

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

能量

energy[1-*]_input

累积能量使用

单位:微焦耳

只读

energy[1-*]_enable

启用或禁用传感器。

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

  • 1:启用

  • 0:禁用

读/写

湿度

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:报警

只读

`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:报警

只读

每个输入通道可能都有一个关联的故障文件。如果硬件支持,则可用于通知开路二极管、未连接的风扇等。当此布尔值为 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

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

读/写

in_samples power_samples curr_samples temp_samples

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

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

读/写

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 */