Подтвердить что ты не робот

Как получить доступ к датчикам тепла процессора?

Я работаю над программным обеспечением, в котором мне нужно получить доступ к температурным датчикам в ЦП и получить контроль над ними.

Я не знаю много аппаратного интерфейса; Я просто знаю, как взаимодействовать с мышью. Я много рассказывал об этом, но не смог найти какую-либо релевантную информацию или фрагмент кода.

Мне действительно нужно добавить это в свое программное обеспечение. Пожалуйста, расскажите мне, как управлять датчиками с помощью C или С++ или ASM.

4b9b3361

Ответ 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. И у некоторых аппаратов даже нет физических устройств для измерения температуры.