Как получить доступ к датчикам тепла процессора?
Я работаю над программным обеспечением, в котором мне нужно получить доступ к температурным датчикам в ЦП и получить контроль над ними.
Я не знаю много аппаратного интерфейса; Я просто знаю, как взаимодействовать с мышью. Я много рассказывал об этом, но не смог найти какую-либо релевантную информацию или фрагмент кода.
Мне действительно нужно добавить это в свое программное обеспечение. Пожалуйста, расскажите мне, как управлять датчиками с помощью C или С++ или ASM.
Ответы
Ответ 1
Без конкретного драйвера ядра сложно запросить температуру, кроме как через WMI. Ниже приведен фрагмент кода C, основанный на классе WMI MSAcpi_ThermalZoneTemperature:
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);
}
Ответ 2
Я предполагаю, что вас интересует процессор IA-32 (Intel Architecture, 32-bit) и Microsoft Windows.
Специфический регистр модели (MSR) IA32_THERM_STATUS
имеет 7 бит, кодирующих "Цифровое считывание (биты 22:16, RO)) - цифровое считывание температуры в градусах по Цельсию относительно температуры активации TCC". (см. "14.5.5.2 Чтение цифрового датчика" в "Архитектурах Intel® 64 и IA-32" - Руководство для разработчиков программного обеспечения - Том 3 (3A и 3B): Руководство по системному программированию " http://www.intel.com/Assets/PDF/manual/325384.pdf).
Итак, IA32_THERM_STATUS
не даст вам "температуру процессора", но прокси-сервер.
Чтобы прочитать регистр IA32_THERM_STATUS
, вы используете инструкцию asm rdmsr
, теперь rdmsr
нельзя вызывать из кода пространства пользователя и поэтому вам нужен код ядра (возможно, драйвер устройства?).
Вы также можете использовать встроенный __readmsr
(см. http://msdn.microsoft.com/en-us/library/y55zyfdx(v=VS.100).aspx), который имеет одинаковое ограничение: "Эта функция доступна только в режиме ядра".
Каждый процессорный сердечник имеет свои собственные цифровые термодатчики (DTS), поэтому для получения всех температур требуется (например, с помощью маски аффинности) Win32 API SetThreadAffinityMask
).
Я провела несколько тестов и фактически обнаружила корреляцию между показаниями IA32_THERM_STATUS
DTS и Prime95 "Тест на наличие больших БПФ на месте (максимальная температура, энергопотребление, некоторый RAM)". Prime95 ftp://mersenne.org/gimps/p95v266.zip
Я не нашел формулу для получения "температуры процессора" (что бы это ни значило) из показания DTS.
Edit:
Цитата из интересного сообщения TJunction Max? #THERMTRIP? #PROCHOT? "fgw" (декабрь 2007):
нет способа найти tjmax некоторого процессора в любом регистре. таким образом, никакое программное обеспечение не может прочитать это значение. что различные разработчики программного обеспечения делают, они просто предполагают некоторый tjunction для некоторого процессор и удерживать эту информацию в таблице внутри программы. кроме того, tjmax даже не правильное значение, которое они имеют после. в факт, что они ищут температурный порог активации TCC. это температурный порог используется для расчета абсолютного значения тока coretemperatures из. теоретически вы можете сказать: абсолютный coretemperature = порог температуры активации TCC - DTS я пришлось теоретически, поскольку, как указано выше, эта деятельность TCC температурный порог не может быть прочитан программным обеспечением и должен быть принят программистом. в большинстве ситуаций (coretemp, everest,...) они принять значение 85C или 100C в зависимости от семейства процессоров и пересмотр. поскольку этот порог температуры активации TCC калибруется при производстве отдельно для каждого процессора это может быть 83C для один процессор, но может быть 87C для другого. с учетом как эти программы вычисляют коэффициенты, вы можете вне зависимости от того, насколько точны абсолютные кортетуры! ни tjmax или "наиболее желаемый" температурный порог TCC может можно найти в любых общедоступных документах. после нескольких дискуссий на форуме разработчиков Intel, Intel не показывает никаких признаков, чтобы сделать это доступная информация.
Ответ 3
Вы можете прочитать его из MSAcpi_ThermalZoneTemperature в WMI
Использование WMI из С++ немного связано, см. объяснение и примеры MSDN
Примечание: измененный исходный бесполезный ответ
Ответ 4
Вероятно, это зависит от операционной системы. В GNU/Linux это связано с ACPI. И у некоторых аппаратов даже нет физических устройств для измерения температуры.