Linux嵌入式软件开发,记录自己的成长历程。
文章目录
前言
在Linux嵌入式软件开发过程中,部分场景下需要获取硬盘的温度,根据温度数据进行定制化的处理。
例如,当硬盘温度高于阈值时,开启风扇;低于阈值时,关闭风扇。
在Linux环境下,可以使用smartctl实现这一功能。
一、smartctl简介
smartctl是一个命令行工具,用于监控和诊断与S.M.A.R.T(Self-Monitoring, Analysis and Reporting Technology)兼容的硬盘驱动器。它允许用户获取硬盘驱动器的S.M.A.R.T信息,并执行诊断测试以检测硬盘的健康状态。
一种常见的用法和选项是,显示硬盘SMART属性信息:
smartctl -a /dev/sdX
这将显示指定硬盘设备的所有SMART属性信息,包括当前值、阈值、最差值等。
在上述命令中,/dev/sdX 应替换为你要检测的硬盘设备路径。
二、实现步骤
1.获取硬盘的温度属性
通过上述用法,可以获取硬盘设备的所有SMART属性信息,如下图所示:
关注190和194这2个属性。
RAW_VALUE是原始值,表示与该属性相关的原始数据,通常是一个数字。这个原始值可以用来进行更深入的分析,但通常需要根据硬盘的制造商文档或其他资料进行解释。
190 Airflow_Temperature_Cel 气流温度
该项表示硬盘内部盘片表面的气流温度,可用于衡量硬盘周围的环境温度。
在希捷公司的某些硬盘中,当前值(VALUE)=(100-当前温度),因此气流温度越高,当前值就越低,最差值(WORST)则是当前值(VALUE)曾经到达过的最低点,临界值(THRESH)由制造商定义的最高允许温度来确定。
RAW_VALUE表示以摄氏度为单位的当前气流温度值。
194 Temperature_Celsius 温度
该项表示硬盘内部的当前实际温度。
硬盘运行时最好不要超过45℃,温度过高虽不会导致数据丢失,但引起的机械变形会导致寻道与读写错误率上升,降低硬盘性能。硬盘的最高允许运行温度可查看硬盘厂商给出的数据,一般不会超过60℃。
不同厂家对温度参数的当前值(VALUE)、最差值(WORST)和临界值(THRESH)有不同的表示方法:希捷公司某些硬盘的当前值就是实际温度(摄氏)值,最差值则是曾经达到过的最高温度,临界值不具意义;而西部数据公司一些硬盘的最差值是温度上升到某值后的时间函数,每次升温后的持续时间都将导致最差值逐渐下降,当前值则与当前温度成反比,即当前温度越高,当前值越低,随实际温度波动。
上面是一些对温度属性的基本介绍,获取温度只需要提取出RAW_VALUE即可。
2.代码实现
通过grep从smartctl的属性信息中提取出RAW_VALUE,实现如下:
/mnt/app/smartctl -a /dev/sda | grep Temperature_Celsius | awk '{print $10}'
其中grep提取出温度属性所在的行,awk提取出该行的第10列(根据属性信息的实际结果调整),即RAW_VALUE,结果如下:
于是,实现获取硬盘温度的接口如下:
int get_hdd_temp()
{
FILE *fp;
char buf[512] = {0};
int temp = 0;
pip_system("/mnt/app/smartctl -a /dev/sda | grep Temperature_Celsius | awk '{print $10}' > /mnt/tmp/hdd_temp_value");
fp = fopen("/mnt/tmp/hdd_temp_value", "r");
if(NULL == fp)
{
perror("open error");
return -1;
}
memset(buf,0,sizeof(buf));
if(fgets(buf, sizeof(buf) - 1, fp) == NULL)
{
fclose(fp);
return -1;
}
temp = atoi(buf);
fclose(fp);
return temp;
}
在实际使用过程中,发现smartctl无法获取到部分机械硬盘的温度属性(194),只能获取到气流温度属性(190),此时,可以认为气流温度就是硬盘当前温度,于是实现如下:
int get_hdd_temp()
{
FILE *fp;
char buf[512] = {0};
int temp = 0;
pip_system("/mnt/app/smartctl -a /dev/sda | grep Temperature_Celsius | awk '{print $10}' > /mnt/tmp/hdd_temp_value");
pip_system("/mnt/app/smartctl -a /dev/sda | grep Airflow_Temperature_Cel | awk '{print $10}' >> /mnt/tmp/hdd_temp_value");
fp = fopen("/mnt/tmp/hdd_temp_value", "r");
if(NULL == fp)
{
perror("open error");
return -1;
}
memset(buf,0,sizeof(buf));
if(fgets(buf, sizeof(buf) - 1, fp) == NULL)
{
fclose(fp);
return -1;
}
temp = atoi(buf);
fclose(fp);
return temp;
}
总结
本文关于smartctl的信息参考如下:
1、https://www.cnblogs.com/xqzt/p/5512075.html
2、EasyChat
欢迎指正^_^~~~