我正在开发软件,我需要访问CPU中的温度传感器并控制它们。
我不太了解硬件接口;我只知道如何与鼠标接口。我搜索了很多关于它但没有找到任何相关信息或一段代码。
我真的需要在我的软件中添加它。请指导我如何使用C或C ++或ASM控制传感器。
答案 0 :(得分:17)
如果没有特定的内核驱动程序,除了通过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);
}
答案 1 :(得分:15)
我假设您对IA-32(英特尔架构,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/Assets/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?(2007年12月)引用一篇有趣的帖子"fgw":
无法在任何寄存器中找到某个处理器的tjmax。 因此,没有软件可以读取此值。各种软件开发人员 他们正在做什么,他们只是假设一定的特定关键 处理器并将此信息保存在程序中的表中。 除此之外,tjmax甚至不是他们追求的正确值。在 事实上,他们正在寻找TCC活动温度阈值。这个 温度阈值用于计算当前绝对值 核心温度来自。理论上你可以说:绝对 coretemperature = TCC激活温度阈值 - DTS我必须 理论上说,因为,如上所述,这个TCC活动 温度阈值不能由软件读取,必须假设 由程序员。在大多数情况下(coretemp,everest,......)他们 假定值为85C或100C,具体取决于处理器系列和 修订。因为该TCC活化温度阈值被校准 在每个处理器单独制造期间,它可能是83C 一个处理器,但另一个可能是87C。考虑到 这些程序正在计算核心温度的方式,你可以想象 在你自己的,绝对核心温度是多么准确!也不 tjmax也不是“最想要的”TCC活动温度阈值 可以在任何公共英特尔文档中找到。经过一些讨论 在英特尔开发者论坛上,英特尔没有显示出这一点 信息。
答案 2 :(得分:11)
您可以从WMI中的MSAcpi_ThermalZoneTemperature
中读取它使用C ++中的WMI有点涉及,请参阅MSDN explanantion and examples
注意:改变了原来无用的答案
答案 3 :(得分:0)
这可能取决于操作系统。在GNU / Linux上,它与ACPI有关。有些硬件甚至没有物理设备来测量温度。