To obtain the CPU temperature, you can use the Assembly command. Here, we use the Intel CPU as an example to use the rdmsr command to read the value of ia32_therm_status_msr (0x019c, then tjunctionmax is used to subtract this value from the current CPU temperature. The tjunctionmax value for general Intel CPU is fixed. For example, my CPU is Intel Core 2 (45nm ), on the official website, we can find that the value is 100 degrees Celsius. The Intel CPU has a register named ia32_temperature_target (0x01a2) to save the value of tjunctionmax, which can be read through the rdmsr command. However, rdmsr commands can only be run at the ring0 layer, but cannot be executed at the application layer. They can only be executed in the driver mode, in the driver layer, a special function _ readmsr is used to read data similar to ia32_therm_status_msr (0x019c) and
The value of the ia32_temperature_target special register. Therefore, you only need to write the calling program on the driver layer and use the deviceiocontrol function on the upper layer to read the values of these special registers, the signal has already been written to an existing driver (the driver name is winring0.sys). You just need to load the driver in your program and then you can read the value of these registers to get the Intel CPU temperature.
The main code for reading these registers at the upper layer is as follows:
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; } } |
If it is a multi-core CPU, you can use the setthreadaffinitymask function to switch the CPU to get the temperature code for each core:
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 );
} |
The following figure shows the read result:
Program http://download.csdn.net/detail/xiaibiancheng/5491513