出處:http://blog.csdn.net/Treeyan/archive/2007/05/29/1630029.aspx
其實不算原創,資料幾乎都是通過 google 來自 internet
前段時間買了 hp-dv1702 膝上型電腦, 酷睿單核 cpu, 5400 轉硬碟, 看電影挺不錯的. 酷睿 cpu支援 speedstep 技術, 不忙的時候總是工作在 800MHz 左右,發熱量小,BIOS 設定風扇啟動溫度為 cpu 75度,平常工作中一天下來風扇也幾乎不轉,硬碟的溫度比較高,從網上查到左手邊熱是這款本本的通病。
筆者的想法是讓風扇在硬碟達到48、9度的時候讓風扇轉動起來,到設定的溫度停下,並可以看到主板、cpu、硬碟的溫度。在風扇控制完成以後,檢測系統溫度的問題就顯出來了,一邊用別人的軟體看系統溫度,一邊手工來控制風扇的停和轉動,累。
1、主板溫度的檢測
膝上型電腦的bios和台式機有一些區別,通常本本的bios ACPI 會有一個熱度表述區(ThermalZone) 或其它acpi定義的溫度檢測地區,讀出這個地區的數值,就得到當前主板上溫度感應器的值,xp/2000 支援acpi,所以很方便讀到。但台式機基本沒有ThermalZone,要監測溫度,需要掃描系統匯流排。
如何讀取acpi這個地區的數值呢,windows driver 讀取這些值用於管理,所以通過WMI 能讀到。串連到 WMI 的名字空間,請參考 MSDN 'WMI C++ Application Examples'。這裡不做敘述.
主板溫度在wmi中有兩個名字:1、ROOT\CIMV2\Win32_TemperatureProbe 2、ROOT\WMI\MSAcpi_ThermalZoneTemperature 先檢測 Win32_TemperatureProbe 是否有對象,如沒有再檢測 MSAcpi_ThermalZoneTemperature 然後讀取成員 CurrentTemperature 為當前溫度,CriticalTripPoint 為臨界溫度。此溫度是以絕對 0 度開始並以 1/10 度增加,公式如下
當前攝氏度 = (CurrentTemperature - 2732) / 10
2、硬碟溫度的監測
檢測硬碟溫度的工具或軟體,都是通過 S.M.A.R.T來讀取,對硬碟直接 DeviceIoControl 或者 WMI 都可以得到SMART值.SMART 資料存放區於 WMI 中 ROOT\WMI\MSStorageDriver_ATAPISmartData 命名空間中,其中屬性 'VendorSpecific' 包含有硬碟溫度的資料,這是ATA標準定義的。可能你讀出這些資料來會有些困惑,其實這是一個結構,第一個和第二個位元組代表 SMART 版本資訊,從第三個位元組起定義 SMART 的屬性,每個屬性為12位元組長,每個屬性的第一位元組為當前屬性定義,0x09 定義已經使用的小時數, 0xc2 為溫度屬性,第五位元組表示當前溫度。結構如下
struct SmartAttriubtes
{
char attrib;
char flags;
char worst;
char normal;
char current;
char current1;
char current2;
char current3;
char current4;
char current5;
char current6;
char current7;
}
struct VendorSpecific
{
unsigned short version;
SmartAttriubtes smartattrib [1];
}
如筆者硬碟讀取如下數值,有些就省略了 {0xa, 0x00, 0x09, 0x32, 0, 0x63, 0x63, 0xc2, 0x03, 0, 0, 0, 0, 0, 0xc2, 0x22, 0, 0x2e, 0x3b, 0x2e, 0, 0, 0, 0x05, 0, 0, ...};
排列如下
{
0xa, 0x00 版本資訊
0x09, 0x32, 0, 0x63, 0x63, [0xc2, 0x03], 0, 0, 0, 0, 0 硬碟使用小時數 這裡是 0x3c2 = 962 小時
0xc2, 0x22, 0, 0x2e, 0x3b, [0x2e], 0, 0, 0, 0x05, 0, 0 這是當前溫度 數值為 0x2e = 46 度
}
win2000 不支援此 WMI 屬性,只能通過 DeviceIoControl 得到,如何?請看考附錄 SMART 的OpenSource 串連
3、CPU 的溫度檢測
新的酷瑞CPU和AMD的CPU 內部都整合有溫度感應器DTS (Digital Thermal Sensor),每個核心有一個,以前的移動CPU好像也支援溫度探測,但手頭沒有這樣的CPU沒法做測試.AMD 的溫度值儲存在 NB 寄存器中,酷瑞CPU 的 DTS 值儲存在 MSR 0x19c 中,可以通過 rdmsr 來讀取
這裡只說酷睿CPU的讀取過程
Intel 定義 eax=6 執行 cpuid, 然後測試 eax 第一位是否為1,如果為1表示CPU支援DTS ,當然之前應該以 eax=0 執行 cpuid 檢測 eax 支援的最大命令數,如果小於6就肯定不支援DTS。
讀取DTS:1 以 ecx=0xee 執行 rdmsr 指令, 測試 eax 的第30位是否為 1, 如果為 1 表示溫度計算的初始值為 85 度否則表示從100度開始計算,這個值稱為 Tjunction. 然後以 ecx=0x19c 執行 rdmsr 指令, eax 的 16:23 位為表示當前DTS 值,這個值並不代表當前溫度,而要以下面公式計算.
當前cpu溫度 = Tjunction - DTS
注意 signature 為 0x6f1, 0x6f0的 CPU DTS 值直接代表當前溫度而不用Tjunction 相減. 而 signature 小於等於 0x6f4 的 Tjunction 一直為100, 如果你是雙核的cpu 可以使用 SetProcessAffinityMask API 來指定執行的CPU,以檢測這個核心的溫度。呵呵,我就不用啦,本本是單核的
另 rdmsr 指令需要運行在 0 級的代碼才能執行.所以寫一個簡單的驅動也是必須的.
如果你想看看效果可以到我的共用資源中下載 FAN1702ii.rar 不操作風扇他還是可以工作的
http://download.csdn.net/source/185999
22:40 2007-5-27 Treeyan email:yanjiafu33@163.com QQ: 42412685
呵呵,很少寫文,不通順之處請包含,Enjoy!
附錄參考
S.M.A.R.T 的 OpenSource
http://smartlinux.sourceforge.net/smart/index.php
在 intel 網站上的罵站,可以看到關於 DTS 和 Tjunction 的一些資訊
http://softwarecommunity.intel.com/isn/Community/en-US/forums/thread/30231056.aspx
Core temp 講述她是如何工作的
http://www.thecoolest.zerobrains.com/CoreTemp/howitworks.html
關於 MSStorageDriver_ATAPISmartData
http://www.hardforum.com/showthread.php?t=1162248
測試cpu速度,開源
http://www.diefer.de/speedswitchxp/index.html