目前SATA硬盘温度读取都是通过SMART协议来读取,当前可利用的开源工具有两个:

1、hddtemp工具:

hddtemp是专门读取sata硬盘温度的工具,如果只需要知道硬盘的温度,此工具足以。

该工具小巧玲珑,而且不需要依赖第三方库,可以直接使用,缺点:如果是自己的的代码需要知道硬盘温度,不能直接调用hddtemp接口。

使用方法:   hddtemp /dev/sdx

Usage: hddtemp [OPTIONS] [TYPE:]DISK1 [[TYPE:]DISK2]...hddtemp displays the temperature of drives supplied in argument.Drives must support S.M.A.R.T.TYPE could be SATA, PATA or SCSI. If omitted hddtemp will try to guess.-b   --drivebase   :  display database file content that allow hddtemp torecognize supported drives.-D   --debug       :  display various S.M.A.R.T. fields and their values.Useful to find a value that seems to match thetemperature and/or to send me a report.(done for every drive supplied).-d   --daemon      :  run hddtemp in TCP/IP daemon mode (port 7634 by default.)-f   --file=FILE   :  specify database file to use.-F   --foreground  :  don't daemonize, stay in foreground.-l   --listen=addr :  listen on a specific interface (in TCP/IP daemon mode).-n   --numeric     :  print only the temperature.-p   --port=#      :  port to listen to (in TCP/IP daemon mode).-s   --separator=C :  separator to use between fields (in TCP/IP daemon mode).-S   --syslog=s    :  log temperature to syslog every s seconds.-u   --unit=[C|F]  :  force output temperature either in Celsius or Fahrenheit.-q   --quiet       :  do not check if the drive is supported.-v   --version     :  display hddtemp version number.-w   --wake-up     :  wake-up the drive if need.-4                 :  listen on IPv4 sockets only.-6                 :  listen on IPv6 sockets only.Report bugs or new drives to <hddtemp@guzu.net>.
hddtemp version 0.3-beta15

2、smartmontools工具:

此工具功能强大,可以读取你所了解的所有硬盘信息,包括硬盘读写时间,读写数据了、温度等等其他一切硬盘信息。

优点:你所有想了解的硬盘信息,此工具皆能获取到,缺点:smartmontools依赖其他第三方库,比如mailx等等。

使用方法: smartctl -a /dev/sdx     smartctl -x /dev/sdx

=== START OF INFORMATION SECTION ===
Device Model:     LITEON V5G+  128
Serial Number:    P02743137697
LU WWN Device Id: 5 002303 10103438e
Firmware Version: 2870306
User Capacity:    128,035,676,160 bytes [128 GB]
Sector Size:      512 bytes logical/physical
Rotation Rate:    Solid State Device
Form Factor:      M.2
Device is:        Not in smartctl database [for details use: -P showall]
ATA Version is:   ACS-2 (minor revision not indicated)
SATA Version is:  SATA 3.1, 6.0 Gb/s (current: 6.0 Gb/s)
Local Time is:    Mon Jul 16 15:41:47 2018 CST
SMART support is: Available - device has SMART capability.
SMART support is: EnabledDevice Statistics (GP Log 0x04)
Page  Offset Size        Value Flags Description
0x01  =====  =               =  ===  == General Statistics (rev 1) ==
0x01  0x008  4             121  ---  Lifetime Power-On Resets
0x01  0x010  4            1512  ---  Power-on Hours
0x01  0x018  6      2287532613  ---  Logical Sectors Written
0x01  0x020  6        38912385  ---  Number of Write Commands
0x01  0x028  6        78111346  ---  Logical Sectors Read
0x01  0x030  6         2053933  ---  Number of Read Commands
0x04  =====  =               =  ===  == General Errors Statistics (rev 1) ==
0x04  0x008  4               0  ---  Number of Reported Uncorrectable Errors
0x04  0x010  4         8241353  ---  Resets Between Cmd Acceptance and Completion
0x06  =====  =               =  ===  == Transport Statistics (rev 1) ==
0x06  0x008  4             465  ---  Number of Hardware Resets
0x06  0x018  4               0  ---  Number of Interface CRC Errors
0x07  =====  =               =  ===  == Solid State Device Statistics (rev 1) ==
0x07  0x008  1               0  ---  Percentage Used Endurance Indicator|||_ C monitored condition met||__ D supports DSN|___ N normalized valueSATA Phy Event Counters (GP Log 0x11)
ID      Size     Value  Description
0x0001  2            0  Command failed due to ICRC error
0x0002  2            0  R_ERR response for data FIS
0x0003  2            0  R_ERR response for device-to-host data FIS
0x0004  2            0  R_ERR response for host-to-device data FIS
0x0005  2            0  R_ERR response for non-data FIS
0x0006  2            0  R_ERR response for device-to-host non-data FIS
0x0007  2            0  R_ERR response for host-to-device non-data FIS
0x0008  2            0  Device-to-host non-data FIS retries
0x0009  2            0  Transition from drive PhyRdy to drive PhyNRdy
0x000a  2           49  Device-to-host register FISes sent due to a COMRESET
0x000b  2            0  CRC errors within host-to-device FIS
0x000d  2            0  Non-CRC errors within host-to-device FIS
0x000f  2            0  R_ERR response for host-to-device data FIS, CRC
0x0010  2            0  R_ERR response for host-to-device data FIS, non-CRC
0x0012  2            0  R_ERR response for host-to-device non-data FIS, CRC
0x0013  2            0  R_ERR response for host-to-device non-data FIS, non-CRCSMART Attributes Data Structure revision number: 1
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE1 Raw_Read_Error_Rate     0x002f   100   100   000    Pre-fail  Always       -       05 Reallocated_Sector_Ct   0x0003   100   100   000    Pre-fail  Always       -       09 Power_On_Hours          0x0002   100   100   000    Old_age   Always       -       151212 Power_Cycle_Count       0x0003   100   100   000    Pre-fail  Always       -       121
170 Unknown_Attribute       0x0032   100   100   000    Old_age   Always       -       0
171 Unknown_Attribute       0x0003   100   100   000    Pre-fail  Always       -       0
172 Unknown_Attribute       0x0003   100   100   000    Pre-fail  Always       -       0
173 Unknown_Attribute       0x0003   100   100   000    Pre-fail  Always       -       8
174 Unknown_Attribute       0x0003   100   100   000    Pre-fail  Always       -       23
175 Program_Fail_Count_Chip 0x0003   100   100   000    Pre-fail  Always       -       0
176 Erase_Fail_Count_Chip   0x0003   100   100   000    Pre-fail  Always       -       0
178 Used_Rsvd_Blk_Cnt_Chip  0x0003   100   100   000    Pre-fail  Always       -       0
179 Used_Rsvd_Blk_Cnt_Tot   0x0003   100   100   000    Pre-fail  Always       -       0
180 Unused_Rsvd_Blk_Cnt_Tot 0x0033   100   100   005    Pre-fail  Always       -       61
181 Program_Fail_Cnt_Total  0x0003   100   100   000    Pre-fail  Always       -       0
182 Erase_Fail_Count_Total  0x0003   100   100   000    Pre-fail  Always       -       0
183 Runtime_Bad_Block       0x0032   100   100   000    Old_age   Always       -       0
195 Hardware_ECC_Recovered  0x0003   100   100   000    Pre-fail  Always       -       0
199 UDMA_CRC_Error_Count    0x0003   100   100   000    Pre-fail  Always       -       0
232 Available_Reservd_Space 0x0003   100   100   010    Pre-fail  Always       -       100
233 Media_Wearout_Indicator 0x0003   100   100   000    Pre-fail  Always       -       1139
241 Total_LBAs_Written      0x0003   100   100   000    Pre-fail  Always       -       34904
242 Total_LBAs_Read         0x0003   100   100   000    Pre-fail  Always       -       1191

3、再有就是自己提取smart接口来自定义读取温度了。以下是提取hddtemp代码中的接口自己弄得读硬盘温度的代码,好处是可以放入自己的代码当中,直接调用接口就可以读取硬盘温度。aarch64和x64环境通过验证。

使用方法:

Usage:
                   satatemp  [-d]  /dev/sda
                   -d print debug  info

源代码如下:

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <getopt.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <linux/hdreg.h>
#include <scsi/scsi.h>
#include <scsi/sg.h>
#include <scsi/scsi_ioctl.h>
#include <fcntl.h>  #define   DEF(X)   1
int debug = 0;#if DEF(ATA)
typedef unsigned short  u16;
#define swapb(x) \
({ \u16 __x = (x); \(x) = ((u16)( \(((u16)(__x) & (u16)0x00ffU) << 8) | \(((u16)(__x) & (u16)0xff00U) >> 8) )); \
})
#define GBUF_SIZE 65535
#define DEFAULT_ATTRIBUTE_ID   194
#define DEFAULT_ATTRIBUTE_ID2  190
#define SBUFF_SIZE 512
static char sbuff[SBUFF_SIZE];static int ata_probe(int device) {if(device == -1 || ioctl(device, HDIO_GET_IDENTITY, sbuff))return 0;elsereturn 1;
}int ata_enable_smart(int device) {unsigned char cmd[4] = { WIN_SMART, 0, SMART_ENABLE, 0 };return ioctl(device, HDIO_DRIVE_CMD, cmd);
}int ata_get_smart_values(int device, unsigned char* buff) {unsigned char  cmd[516] = { WIN_SMART, 0, SMART_READ_VALUES, 1 };int            ret;ret = ioctl(device, HDIO_DRIVE_CMD, cmd);if(ret)return ret;memcpy(buff, cmd+4, 512);return 0;
}static char *ata_model (int device) {if(device == -1 || ioctl(device, HDIO_GET_IDENTITY, sbuff))return strdup("unknown");elsereturn strdup((char*) ((u16*)sbuff + 27));
}unsigned char* ata_search_temperature(const unsigned char* smart_data, int attribute_id) {int i, n;n = 3;i = 0;if(debug)printf("============ ata ============\n");while((debug || *(smart_data + n) != attribute_id) && i < 30) {if(debug && *(smart_data + n))printf("field(%d)\t = %d\t(0x%02x)\n",(int)*(smart_data + n),(int)*(smart_data + n + 3),*(smart_data + n + 3));n += 12;i++;}if(i >= 30)return NULL;elsereturn (unsigned char*)(smart_data + n);
}int ata_get_temperature(int fd)
{ unsigned char    values[512]/*, thresholds[512]*/;unsigned char  *field;int              i;unsigned short  *p;if(ata_enable_smart(fd) != 0) {printf("ATA S.M.A.R.T. not available!\n");return -1;}if(ata_get_smart_values(fd, values)) {printf("ATA Enable S.M.A.R.T. err!\n");return -1;}p = (u16*)values;for(i = 0; i < 256; i++) {swapb(*(p+i));}/* get SMART threshold values *//*if(get_smart_threshold_values(fd, thresholds)) {perror("ioctl");exit(3);}p = (u16*)thresholds;for(i = 0; i < 256; i++) {swapb(*(p+i));}*//* temperature */field = ata_search_temperature(values, DEFAULT_ATTRIBUTE_ID);if(!field)field = ata_search_temperature(values, DEFAULT_ATTRIBUTE_ID2);if(field)return *(field+3);elsereturn -1;
}#endif#if DEF(SCSI)
#define TEMPERATURE_PAGE                0x0d
#define CDB_12_HDR_SIZE 14
#define CDB_12_MAX_DATA_SIZE        0xffffffff
#define CDB_6_HDR_SIZE          14
#define CDB_6_MAX_DATA_SIZE     0xff#define DEXCPT_DISABLE  0xf7
#define DEXCPT_ENABLE   0x08
#define EWASC_ENABLE    0x10
#define EWASC_DISABLE   0xef
#define GBUF_SIZE 65535
#define MODE_DATA_HDR_SIZE  12
#define SMART_SUPPORT   0x00struct cdb10hdr {unsigned int inbufsize;unsigned int outbufsize;unsigned int cdb [10];
} ;struct cdb6hdr{unsigned int inbufsize;unsigned int outbufsize;unsigned char cdb [6];
};static void scsi_fixstring(unsigned char *s, int bytecount)
{unsigned char *p;unsigned char *end;p = s;end = s + bytecount;/* strip leading blanks */while (s != end && *s == ' ')++s;/* compress internal blanks and strip trailing blanks */while (s != end && *s) {if (*s++ != ' ' || (s != end && *s && *s != ' '))*p++ = *(s-1);}/* wipe out trailing garbage */while (p != end)*p++ = '\0';
}int scsi_SG_IO(int device, unsigned char *cdb, int cdb_len, unsigned char *buffer, int buffer_len, unsigned char *sense, unsigned char sense_len, int dxfer_direction) {struct sg_io_hdr io_hdr;memset(&io_hdr, 0, sizeof(struct sg_io_hdr));io_hdr.interface_id = 'S';io_hdr.cmdp = cdb;io_hdr.cmd_len = cdb_len;io_hdr.dxfer_len = buffer_len;io_hdr.dxferp = buffer;io_hdr.mx_sb_len = sense_len;io_hdr.sbp = sense;io_hdr.dxfer_direction = dxfer_direction;io_hdr.timeout = 3000; /* 3 seconds should be ample */return ioctl(device, SG_IO, &io_hdr);
}int scsi_SEND_COMMAND(int device, unsigned char *cdb, int cdb_len, unsigned char *buffer, int buffer_len, int dxfer_direction)
{unsigned char buf[2048];unsigned int inbufsize, outbufsize, ret;switch(dxfer_direction) {case SG_DXFER_FROM_DEV: inbufsize = 0;outbufsize = buffer_len;break;case SG_DXFER_TO_DEV:inbufsize = buffer_len;outbufsize = 0;break;default:inbufsize = 0;outbufsize = 0;break;}memcpy(buf, &inbufsize , sizeof(inbufsize));memcpy(buf + sizeof(inbufsize), &outbufsize , sizeof(outbufsize));memcpy(buf + sizeof(inbufsize) + sizeof(outbufsize), cdb, cdb_len);memcpy(buf + sizeof(inbufsize) + sizeof(outbufsize) + cdb_len, buffer, buffer_len);ret = ioctl(device, SCSI_IOCTL_SEND_COMMAND, buf);memcpy(buffer, buf + sizeof(inbufsize) + sizeof(outbufsize), buffer_len);return ret;
}int scsi_command(int device, unsigned char *cdb, int cdb_len, unsigned char *buffer, int buffer_len, int dxfer_direction)
{static int SG_IO_supported = -1;int ret;if (SG_IO_supported == 1)return scsi_SG_IO(device, cdb, cdb_len, buffer, buffer_len, NULL, 0, dxfer_direction);else if (SG_IO_supported == 0)return scsi_SEND_COMMAND(device, cdb, cdb_len, buffer, buffer_len, dxfer_direction);else {ret = scsi_SG_IO(device, cdb, cdb_len, buffer, buffer_len, NULL, 0, dxfer_direction);if (ret == 0) {SG_IO_supported = 1;return ret;} else {SG_IO_supported = 0;return scsi_SEND_COMMAND(device, cdb, cdb_len, buffer, buffer_len, dxfer_direction);}}
}int scsi_inquiry(int device, unsigned char *buffer)
{unsigned char cdb[6];memset(cdb, 0, sizeof(cdb));cdb[0] = INQUIRY;cdb[4] = 36;  /* should be 36 for unsafe devices (like USB mass storage stuff)*      otherwise they can lock up! SPC sections 7.4 and 8.6 */if (scsi_command(device, cdb, sizeof(cdb), buffer, cdb[4], SG_DXFER_FROM_DEV) != 0)return 1;else {scsi_fixstring(buffer + 8, 24);return 0;}
}unsigned char modesense (int device,  unsigned char pagenum, unsigned char *pBuf)
{unsigned char tBuf[CDB_6_MAX_DATA_SIZE + CDB_6_HDR_SIZE ];struct cdb6hdr *ioctlhdr;unsigned char status;memset ( &tBuf, 0, CDB_6_MAX_DATA_SIZE + CDB_6_HDR_SIZE );ioctlhdr = (struct cdb6hdr *) &tBuf;ioctlhdr->inbufsize = 0;ioctlhdr->outbufsize = 0xff;ioctlhdr->cdb[0] = MODE_SENSE;ioctlhdr->cdb[1] = 0x00;ioctlhdr->cdb[2] = pagenum;ioctlhdr->cdb[3] = 0x00;ioctlhdr->cdb[4] = CDB_6_MAX_DATA_SIZE;ioctlhdr->cdb[5] = 0x00;status =  ioctl( device, 1 , &tBuf);memcpy ( pBuf, &tBuf[8], 256); return status;}unsigned char modeselect (int device,  unsigned char pagenum, unsigned char *pBuf)
{struct cdb6hdr *ioctlhdr;unsigned char tBuf[CDB_6_MAX_DATA_SIZE + CDB_6_HDR_SIZE ];unsigned char status;memset ( &tBuf, 0, CDB_6_MAX_DATA_SIZE + CDB_6_HDR_SIZE );ioctlhdr = (struct cdb6hdr *) &tBuf;ioctlhdr->inbufsize = pBuf[0] + 1;ioctlhdr->outbufsize = 0;ioctlhdr->cdb[0] = MODE_SELECT;ioctlhdr->cdb[1] = 0x11;ioctlhdr->cdb[2] = 0x00;ioctlhdr->cdb[3] = 0x00;ioctlhdr->cdb[4] = pBuf[0] + 1;ioctlhdr->cdb[5] = 0x00;tBuf[CDB_6_HDR_SIZE + 3]  = 0x08;tBuf[CDB_6_HDR_SIZE + 10] = 0x02;memcpy ( &tBuf[ CDB_6_HDR_SIZE + MODE_DATA_HDR_SIZE],pBuf +  MODE_DATA_HDR_SIZE,pBuf[0] - MODE_DATA_HDR_SIZE + 1);tBuf[26] &= 0x3f;      status = ioctl( device, 1 , &tBuf);return status;}unsigned char scsi_smart_mode_page1c_handler(int device, unsigned char setting, unsigned char *retval)
{char tBuf[CDB_6_MAX_DATA_SIZE];if (modesense ( device, 0x1c, (unsigned char *) &tBuf) != 0){return 1;}switch (setting){case DEXCPT_DISABLE:tBuf[14] &= 0xf7;tBuf[15] = 0x04;break;case DEXCPT_ENABLE:tBuf[14] |= 0x08;break;case EWASC_ENABLE:tBuf[14] |= 0x10;break;case EWASC_DISABLE:tBuf[14] &= 0xef;break;case SMART_SUPPORT:*retval = tBuf[14] & 0x08;return 0;break;default:return 1;}if (modeselect ( device, 0x1c, (unsigned char *) &tBuf ) != 0){return 1;}return 0;
}unsigned char log_sense (int device, unsigned char pagenum, unsigned char *pBuf)
{struct cdb10hdr *ioctlhdr;unsigned char tBuf[1024 + CDB_12_HDR_SIZE];unsigned char status;memset ( &tBuf, 0, 255);ioctlhdr = (struct cdb10hdr *) tBuf;ioctlhdr->inbufsize = 0;ioctlhdr->outbufsize = 1024;ioctlhdr->cdb[0] = LOG_SENSE;ioctlhdr->cdb[1] = 0x00;ioctlhdr->cdb[2] = 0x40 | pagenum;ioctlhdr->cdb[3] = 0x00;ioctlhdr->cdb[4] = 0x00;ioctlhdr->cdb[5] = 0x00;ioctlhdr->cdb[6] = 0x00;ioctlhdr->cdb[7] = 0x04;ioctlhdr->cdb[8] = 0x00;ioctlhdr->cdb[9] = 0x00;status =  ioctl( device, 1 , &tBuf);memcpy ( pBuf, &tBuf[8], 1024); return status;}static int scsi_probe(int device) {int bus_num;if(ioctl(device, SCSI_IOCTL_GET_BUS_NUMBER, &bus_num))return 0;elsereturn 1;
}static char *scsi_model (int device) {unsigned char buf[36];if (scsi_inquiry(device, buf) != 0)return strdup("unknown");else {return strdup(buf + 8);}
}int scsi_get_temperature(int fd)
{unsigned char buf[1024];unsigned char smartsupport;char gBuf[GBUF_SIZE];if(0 != scsi_smart_mode_page1c_handler( fd, SMART_SUPPORT, &smartsupport)){printf("SCSI S.M.A.R.T. not available!\n");return -1;}if(0 != scsi_smart_mode_page1c_handler(fd, DEXCPT_DISABLE, NULL)){printf("SCSI Enable S.M.A.R.T. err!\n");return -1;}if (log_sense(fd , TEMPERATURE_PAGE, buf) != 0){printf("SCSI read err!\n");return -1;}return buf[9];
}#endif#if DEF(SATA)
#ifndef ATA_16
/* Values for T10/04-262r7 */
#define     ATA_16          0x85      /* 16-byte pass-thru */
#endifint sata_pass_thru(int device, unsigned char *cmd, unsigned char *buffer) {unsigned char cdb[16];unsigned char sense[32];int dxfer_direction;int ret;memset(cdb, 0, sizeof(cdb));cdb[0] = ATA_16;if (cmd[3]) {cdb[1] = (4 << 1); /* PIO Data-in */cdb[2] = 0x2e;     /* no off.line, cc, read from dev, lock count in sector count field */dxfer_direction = SG_DXFER_FROM_DEV;} else {cdb[1] = (3 << 1); /* Non-data */   cdb[2] = 0x20;     /* cc */dxfer_direction = SG_DXFER_NONE;}cdb[4] = cmd[2];if (cmd[0] == WIN_SMART) {cdb[6] = cmd[3];cdb[8] = cmd[1];cdb[10] = 0x4f;cdb[12] = 0xc2;}elsecdb[6] = cmd[1];cdb[14] = cmd[0];ret = scsi_SG_IO(device, cdb, sizeof(cdb), buffer, cmd[3] * 512, sense, sizeof(sense), dxfer_direction);/* Verify SATA magics */if (sense[0] != 0x72)return 1;       else return ret;
}void sata_fixstring(unsigned char *s, int bytecount)
{unsigned char *p;unsigned char *end;p = s;end = &s[bytecount & ~1]; /* bytecount must be even *//* convert from big-endian to host byte order */for (p = end ; p != s;) {unsigned short *pp = (unsigned short *) (p -= 2);*pp = ntohs(*pp);}/* strip leading blanks */while (s != end && *s == ' ')++s;/* compress internal blanks and strip trailing blanks */while (s != end && *s) {if (*s++ != ' ' || (s != end && *s && *s != ' '))*p++ = *(s-1);}/* wipe out trailing garbage */while (p != end)*p++ = '\0';
}static int sata_probe(int device) {int bus_num;unsigned char cmd[4] = { WIN_IDENTIFY, 0, 0, 1 };unsigned char identify[512];char buf[36]; /* should be 36 for unsafe devices (like USB mass storage stuff)otherwise they can lock up! SPC sections 7.4 and 8.6 *//* SATA disks are difficult to detect as they answer to both ATA and SCSI commands *//* First check that the device is accessible through SCSI */if(ioctl(device, SCSI_IOCTL_GET_BUS_NUMBER, &bus_num))return 0;/* Get SCSI name and verify it starts with "ATA " */if (scsi_inquiry(device, buf))return 0;else if (strncmp(buf + 8, "ATA ", 4))return 0;/* Verify that it supports ATA pass thru */if (sata_pass_thru(device, cmd, identify) != 0)return 0;elsereturn 1;
}int sata_enable_smart(int device) {unsigned char cmd[4] = { WIN_SMART, 0, SMART_ENABLE, 0 };return sata_pass_thru(device, cmd, NULL);
}int sata_get_smart_values(int device, unsigned char* buff) {unsigned char cmd[4] = { WIN_SMART, 0, SMART_READ_VALUES, 1 };return sata_pass_thru(device, cmd, buff);
}static char *sata_model (int device) {unsigned char cmd[4] = { WIN_IDENTIFY, 0, 0, 1 };unsigned char identify[512];if(device == -1 || sata_pass_thru(device, cmd, identify))return strdup("unknown");else{sata_fixstring(identify + 54, 40);return strdup(identify + 54);}
}static unsigned char* sata_search_temperature(const unsigned char* smart_data, int attribute_id) {int i, n;n = 3;i = 0;if(debug)printf("============ sata ============\n");while((debug || *(smart_data + n) != attribute_id) && i < 30) {if(debug && *(smart_data + n))printf("field(%d)\t = %d\t(0x%02x)\n", *(smart_data + n), *(smart_data + n + 3), *(smart_data + n + 3));n += 12;i++;}if(i >= 30)return NULL;elsereturn (unsigned char*)(smart_data + n);
}int sata_get_temperature(int fd)
{unsigned char    values[512];unsigned char  *field;int              i;u16 *            p;/* get SMART values */if(sata_enable_smart(fd) != 0) {printf("SATA S.M.A.R.T. not available!\n");return -1;}if(sata_get_smart_values(fd, values)) {printf("SATA Enable S.M.A.R.T. err!\n");return -1;}p = (u16*)values;for(i = 0; i < 256; i++) {swapb(*(p+i));}/* temperature */field = sata_search_temperature(values, DEFAULT_ATTRIBUTE_ID);if(!field)field = sata_search_temperature(values, DEFAULT_ATTRIBUTE_ID2);if(field)return  *(field+3);elsereturn -1;
}#endifint print_usage()
{printf("Usage:\n");printf("          satatemp  [-d]  /dev/sda\n");printf("          -d print debug  info\n");return 0;
}int main(int argc, char* argv[])
{int fd = 0;int value = -1;char type[16] = "";char *mode = NULL;char *device = NULL;if(3 == argc){if(0 != strncmp(argv[1], "-d", strlen("-d"))){print_usage();return 0;}  device = argv[2];debug = 1;}else if(argc == 2){if(0 != strncmp(argv[1], "/dev/", strlen("/dev/"))){print_usage();return 0;}    device = argv[1];debug = 0;}else{print_usage();return 0;}fd = open(device, O_RDONLY | O_NONBLOCK);if (fd < 0){printf("open err!\n");return (-1);}if(sata_probe(fd)){value = sata_get_temperature(fd);memset(type, 0 ,sizeof(type));strcpy(type,"SATA mode");mode = sata_model(fd);}else if(ata_probe(fd)){value = ata_get_temperature(fd);memset(type, 0 ,sizeof(type));strcpy(type,"ATA mode");mode = ata_model(fd);}else if(scsi_probe(fd)){value = scsi_get_temperature(fd);memset(type, 0 ,sizeof(type));strcpy(type,"SCSI mode");mode = scsi_model(fd);}if(value > 0)printf("%s: %s, temperature: %d C\n", type, mode, value);else if(mode)printf("%s: %s:  no sensor\n", device, mode);elseprintf("get temperature failed!\n");close(fd);free(mode);return 0;
}

SATA 硬盘/SSD温度读取相关推荐

  1. 测试硬盘,ssd,优盘读取速度

    首先安装sudo apt install fio 输入指令 测试写入 sudo fio -filename=/dev/sdb1 -direct=1 -iodepth 1 -thread -rw=wri ...

  2. SATA SAS SSD 硬盘介绍和评测

    SATA SATA的全称是Serial Advanced Technology Attachment,是由Intel.IBM.Dell.APT.Maxtor和Seagate公司共同提出的硬盘接口规范. ...

  3. IDE ,SAS,SATA,SCSI,SSD硬盘的主要区别

    IDE  (Integrated Drive Electronics) 电子集成驱动器      它的本意是指把"硬盘控制器"与"盘体"集成在一起的硬盘驱动器. ...

  4. SATA硬盘和SSD硬盘性能测试对比

    测试工具: fio 测试对象: SATA硬盘, SSD硬盘 测试项目:顺序读.随机读.顺序写.随机写 1. 顺序读 测试命令:fio -name iops -rw=read -bs=4k -runti ...

  5. 2011 imac 固态_iMac 更换 SATA 接口 SSD 固态硬盘拆机详解

    1. 本文是拆卸机械硬盘换上 SATA 接口 SSD(约450MB/s): 2. 想读写速度更快请换主板上 M.2 接口 SSD(约3000MB/s),教程:点击查看 拆机须知1. 请认真阅读本帖,拆 ...

  6. SATA硬盘性能测试软件,SATA硬盘和SSD硬盘性能测试对比

    测试工具:fio 测试对象: SATA硬盘, SSD硬盘 测试项目:顺序读.随机读.顺序写.随机写 1. 顺序读 测试命令:fio -name iops -rw=read -bs=4k -runtim ...

  7. windows c语言 sata 序列号,在windows x64系统下读取sata硬盘序列号

    在上一篇文章中我们提到如何使用jni在windows环境中读取硬盘序列号.然而,原有的代码,并不能有效地读取sata硬盘信息,并且在x64环境下也不能工作.所以,我们需要一种新的读取硬盘序列号的方法. ...

  8. 三个sata硬盘只能读取两个_电脑装了两个硬盘有一个读不出来是SATA接口的

    满意答案 chenl631353 2013.12.31 采纳率:57%    等级:12 已帮助:6570人 个人分析:如果自己识别不出来, 一数据线和电源线可能有问题, 二说明硬盘有问题 三CMOS ...

  9. SATA硬盘检测修复及MHDD的一些使用详解

    关于PATA硬盘的测试和修复工具,可能很多人会选择效率源软件,因为它易用,直观,检测出硬盘有坏道的时候,能显示出坏道的位置,并能进行修复.但是如果是SATA硬盘,由于在启动效率源工具的过程中无法加载S ...

最新文章

  1. Redis设计与实现 第一部分
  2. 【Hibernate步步为营】--(一对多映射)之单向关联
  3. IE浏览器打不开解决的方法
  4. 杭州/北京内推 | 蚂蚁集团智能决策团队招聘运筹优化算法工程师/实习生
  5. Class类 获取Class对象
  6. 中心城镇问题(长链剖分优化树形dp)
  7. PHP+jQuery+MySql实现红蓝投票功能
  8. 国庆节前梳理一下需要自己干的工作
  9. matlab三次多样式对函数拟合,Matlab regress函数拟合多个变量分析
  10. window10保存文件时提示联系管理员_东芝2000AC扫描文件到远程域共享服务器
  11. ATM系统之问题描述与词汇表
  12. Winform获取本地IP和外网IP
  13. 小车故障灯亮显示大全_原创案例丨17款迈锐宝XL缺缸故障
  14. Python接口自动化之使用requests库发送http请求
  15. 人性的弱点【了解鱼的需求】
  16. CAD图纸打印出来后很多CAD文字消失了怎么办?
  17. HDR到底是干什么的?建模的时候有什么用处?
  18. leetCode 318 最大单词长度乘积(位掩码,位运算,二进制)
  19. PDF怎么拆分?有哪些免费的PDF拆分软件
  20. 征集国内操作系统项目列表 zz

热门文章

  1. Thiol-PEG-SH,巯基聚乙二醇巯基,Thiol-PEG-Thiol
  2. iPhone 13系列电池信息曝光,续航稳了
  3. 程序员的职业生涯个人规划(附上学习资料)
  4. 小米智能家居技术分析
  5. 拉卡拉智能POS新功能预览
  6. 拉卡拉支付:推出支付产业互联网新大门
  7. java 安卓application_Android中Application类用法
  8. mysql和asp.net_asp.net core 使用Mysql和Dapper
  9. 基于S32K144 CAN总线功能开发详解
  10. unable to find java_SQL Developer报错:Unable to find a Java Virtual Machine解决办法