獲取cpu溫度


要獲取cpu的溫度可以通過匯編指令來讀取,這里以intel cpu為例,用rdmsr指令讀取 IA32_THERM_STATUS_MSR(0x019C)的值,然后用TjunctionMax 減去這個值就是當前cpu的溫度,對於一般的intel cpu 的TjunctionMax值是固定的,比如我的cpu是Intel Core 2 (45nm),在官網上可以查到其值是100攝氏度,到后面的intel cpu專門有個寄存器IA32_TEMPERATURE_TARGET(0x01A2)保存TjunctionMax的值,可以通過rdmsr指令讀取。但是rdmsr指令只能在Ring0層運行,在運用層是執行不了的,必須通過驅動的方式才能執行,在驅動層專門有個函數__readmsr負責讀取類似IA32_THERM_STATUS_MSR(0x019C)

IA32_TEMPERATURE_TARGET特殊寄存器的值,所以只要在驅動層寫好調用程序后在上層用DeviceIoControl函數就可讀取這些特殊寄存器的值,信號別人已經寫好了現有的驅動(驅動名 WinRing0.sys),你只要在你的程序里面加載這個驅動然后就可讀取這些寄存器的值,獲得intel cpu的溫度。

其中在上層讀取這些寄存器的主要代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 
BOOL WINAPI Rdmsr(DWORD index, PDWORD eax, PDWORD edx)
{
    if(gHandle == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }
    if(eax == NULL || edx == NULL || gIsMsr == FALSE)
    {
        return FALSE;
    }
    DWORD   returnedLength = 0;
    BOOL    result = FALSE;
    BYTE    outBuf[8] = {0};
    result = DeviceIoControl(
        gHandle,
        IOCTL_OLS_READ_MSR,
        &index,
        sizeof(index),
        &outBuf,
        sizeof(outBuf),
        &returnedLength,
        NULL
        );
    if(result)
    {
        memcpy(eax, outBuf, 4);
        memcpy(edx, outBuf + 4, 4);
    }
    if(result)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}


如果是多核cpu可以通過 SetThreadAffinityMask函數切換cpu來獲取每個核的溫度代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
void   CCPUTemperatureDlg :: OnTimer ( UINT_PTR   nIDEvent )
{
    
CEdit   * edit =( CEdit *) GetDlgItem ( IDC_EDIT1 );
    
CEdit   * edit1 =( CEdit *) GetDlgItem ( IDC_EDIT2 );
    
DWORD   eax = 0 , edx = 0 ;
    
ULONG   result ;
    
char   s [ 20 ];
    
result = SetThreadAffinityMask ( GetCurrentThread (), 1 );
    
Rdmsr ( 0x19c ,& eax ,& edx ); //read Temperature
     SetThreadAffinityMask ( GetCurrentThread (), result );
    
sprintf ( s , "%d" , 100 -(( eax & 0x007f0000 )>> 16 ));
    
edit -> SetWindowText ( s );
    
result = SetThreadAffinityMask ( GetCurrentThread (), 2 );
    
Rdmsr ( 0x19c ,& eax ,& edx ); //read Temperature
     SetThreadAffinityMask ( GetCurrentThread (), result );
    
sprintf ( s , "%d" , 100 -(( eax & 0x007f0000 )>> 16 ));
    
edit1 -> SetWindowText ( s );
    
CDialog :: OnTimer ( nIDEvent );
}

下面是讀取結果圖:


 

程序的下載地址 http://download.csdn.net/detail/xiaibiancheng/5491513


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM