如何访问CPU的热传感器?

我正在使用需要访问CPU中的温度传感器并控制它们的软件。

我不太了解硬件接口; 我只知道如何与鼠标接口。 我已经search了很多关于它,但没有find任何相关的信息或代码段。

我真的需要在我的软件中添加这个。 请指导我如何控制使用C或C ++或ASM的传感器。

如果没有特定的内核驱动程序,除了通过WMI之外,很难查询温度。 下面是一段基于WMI的MSAcpi_ThermalZoneTemperature类的C代码:

HRESULT GetCpuTemperature(LPLONG pTemperature) { if (pTemperature == NULL) return E_INVALIDARG; *pTemperature = -1; HRESULT ci = CoInitialize(NULL); // needs comdef.h HRESULT hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); if (SUCCEEDED(hr)) { IWbemLocator *pLocator; // needs Wbemidl.h & Wbemuuid.lib hr = CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLocator); if (SUCCEEDED(hr)) { IWbemServices *pServices; BSTR ns = SysAllocString(L"root\\WMI"); hr = pLocator->Connectserver(ns, NULL, NULL, NULL, 0, NULL, NULL, &pServices); pLocator->Release(); SysFreeString(ns); if (SUCCEEDED(hr)) { BSTR query = SysAllocString(L"SELECT * FROM MSAcpi_ThermalZoneTemperature"); BSTR wql = SysAllocString(L"WQL"); IEnumWbemClassObject *pEnum; hr = pServices->ExecQuery(wql, query, WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &pEnum); SysFreeString(wql); SysFreeString(query); pServices->Release(); if (SUCCEEDED(hr)) { IWbemClassObject *pObject; ULONG returned; hr = pEnum->Next(WBEM_INFINITE, 1, &pObject, &returned); pEnum->Release(); if (SUCCEEDED(hr)) { BSTR temp = SysAllocString(L"CurrentTemperature"); VARIANT v; VariantInit(&v); hr = pObject->Get(temp, 0, &v, NULL, NULL); pObject->Release(); SysFreeString(temp); if (SUCCEEDED(hr)) { *pTemperature = V_I4(&v); } VariantClear(&v); } } } if (ci == S_OK) { CoUninitialize(); } } } return hr; } 

和一些测试代码:

 HRESULT GetCpuTemperature(LPLONG pTemperature); int _tmain(int argc, _TCHAR* argv[]) { LONG temp; HRESULT hr = GetCpuTemperature(&temp); printf("hr=0x%08x temp=%i\n", hr, temp); } 

我假设你对IA-32(Intel架构,32位)CPU和Microsoft Windows感兴趣。

型号特定寄存器(MSR) IA32_THERM_STATUS具有7位编码“数字读数(位22:16,RO) – 相对于TCC激活温度1摄氏度的数字温度读数”。 (请参阅“英特尔®64和IA-32架构 – 软件开发人员手册 – 第3卷(3A和3B):系统编程指南”中的“14.5.5.2读取数字传感器” http://www.intel.com/资源/ PDF / manual / 325384.pdf )。

所以IA32_THERM_STATUS不会给你“CPU温度”,但它的一些代理。

为了读取IA32_THERM_STATUS寄存器,您使用asm指令rdmsr ,现在rdmsr不能从用户空间代码中调用,因此您需要一些内核空间代码(也许是设备驱动程序?)。

您也可以使用内部的__readmsr (请参阅http://msdn.microsoft.com/en-us/library/y55zyfdx(v=VS.100).aspx ),它具有相同的限制:“此功能只适用于内核模式“。

每个CPU内核都有自己的数字热传感器(DTS),所以需要更多的代码来获得所有的温度(也许使用亲和性掩码?参见Win32 API SetThreadAffinityMask )。

我做了一些测试,实际上发现了IA32_THERM_STATUS DTS读数与Prime95“就地大FFT(最大热量,功耗,一些RAM测试)”测试之间的相关性。 Prime95是ftp://mersenne.org/gimps/p95v266.zip

我没有找到从DTS读数中获得“CPU温度”(无论如何可能意味着什么)的公式。

编辑:

引用一个有趣的帖子TJunction Max? #THERMTRIP? #PROCHOT? 通过“fgw” (2007年12月):

没有办法在任何寄存器中找到某个处理器的tjmax。 因此没有软件可以读取这个值。 各种软件开发人员正在做什么,他们只是为某个处理器假设一个特定的连接,并将这些信息保存在程序的一个表中。 除此之外,tjmax甚至不是他们之后的正确值。 事实上他们正在寻找TCC活化温度的门槛。 这个温度阈值被用来计算当前的绝对核心温度。 理论上你可以说:绝对核心温度= TCC激活温度阈值 – DTS我不得不说,理论上,因为如上所述,这个TCC激活温度阈值不能被软件读取,并且必须由程序员承担。 在大多数情况下(coretemp,everest,…),取决于处理器族和修订版,它们的值为85C或100C。 因为这个TCC激活温度阈值在每个处理器单独制造期间被校准,所以一个处理器可以是83℃,而另一个可以是87℃。 考虑到这些程序正在计算核心温度的方式,你可以自己弄清楚绝对核心温度有多精确! 在任何公共的英特尔文档中,tjmax和“最需要的”TCC激活温度阈值都不能找到。 在intel开发者论坛上进行了一些讨论之后,intel并没有显示出提供这些信息的迹象。

您可以从WMI中的MSAcpi_ThermalZoneTemperature中读取它

从C ++使用WMI有一点涉及,请参阅MSDN解释和示例

注意:改变了原来无益的答案

这可能取决于操作系统。 在GNU / Linux上,它与ACPI有关。 而有些硬件甚至没有物理设备来测量温度。