web-dev-qa-db-ja.com

CPUの熱センサーにアクセスする方法は?

私はCPUの温度センサーにアクセスしてそれらを制御する必要があるソフトウェアに取り組んでいます。

ハードウェアのインターフェースについてはよくわかりません。私はマウスとのインターフェース方法を知っています。私はそれについてたくさんグーグルで検索しましたが、関連する情報やコードを見つけることができませんでした。

私は本当にこれを私のソフトウェアに追加する必要があります。 C、C++、またはASMを使用してセンサーを制御する方法を教えてください。

20
fuddin

特定のカーネルドライバーがないと、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);
}
18
Simon Mourier

IA-32(Intelアーキテクチャ、32ビット)CPUとMicrosoftWindowsに興味があると思います。

モデル固有レジスタ(MSR)IA32_THERM_STATUSには、「デジタル読み出し(ビット22:16、RO)—TCCアクティブ化温度に対して摂氏1度でのデ​​ジタル温度読み取り」をエンコードする7ビットがあります。 (「インテル®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を呼び出すことはできないため、カーネルスペースコード(デバイスドライバーなど)が必要です。 ?)。

とにかく持っている組み込みの__readmsrhttp://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? by "fgw" (2007年12月):

どのレジスタでも特定のプロセッサのtjmaxを見つける方法はありません。したがって、ソフトウェアはこの値を読み取ることができません。さまざまなソフトウェア開発者が行っていることは、単に特定のプロセッサに対して特定の接続を想定し、この情報をプログラム内のテーブルに保持することです。それに加えて、tjmaxは彼らが求めている正しい値でさえありません。実際、彼らはTCC活性化温度のしきい値を探しています。この温度しきい値は、から現在の絶対コア温度を計算するために使用されます。理論的には次のように言えます。絶対コア温度= TCCアクティベーション温度しきい値-DTS上記のように、このTCCアクティベーション温度しきい値はソフトウェアで読み取ることができず、プログラマー。ほとんどの状況(coretemp、everestなど)では、プロセッサーファミリーとリビジョンに応じて85Cまたは100Cの値を想定しています。このTCCアクティベーション温度のしきい値は、プロセッサーごとに個別に製造中に調整されるため、1つで83Cになる可能性があります。これらのプログラムがコア温度を計算する方法を考慮に入れると、絶対コア温度がどれほど正確であるかを自分で理解できます!tjmaxも「最も必要な」TCCアクティベーション温度しきい値も次の場所にありません。公開されているIntelドキュメント。Intel開発者フォーラムでの議論の後、intelはこの情報を利用できるようにする兆候を示していません。

15

WMIのMSAcpi_ThermalZoneTemperatureから読み取ることができます

C++からWMIを使用するのは少し複雑です。 MSDNの説明と例 を参照してください。

注:元の役に立たない回答を変更しました

11
Martin Beckett

おそらくオペレーティングシステムに依存します。 GNU/Linuxでは、ACPIに関連しています。また、一部のハードウェアには、温度を測定するための物理デバイスすらありません。