22

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

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

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

4

4 に答える 4

20

特定のカーネル ドライバーがないと、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);
}
于 2011-10-26T21:04:09.940 に答える
18

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

モデル固有レジスタ (MSR)IA32_THERM_STATUSには、「デジタル読み出し (ビット 22:16、RO) — TCC 起動温度に対する摂氏 1 度でのデジタル温度読み取り」をエンコードする 7 ビットがあります。(「Intel® 64 and IA-32 Architectures - Software Developer's Manual - Volume 3 (3A & 3B): System Programming Guide」の「14.5.5.2 Reading the Digital Sensor」を参照してください http://www.intel.com/Assets/ PDF/マニュアル/325384.pdf )。

したがってIA32_THERM_STATUS、「CPU温度」は表示されませんが、その代わりのプロキシが表示されます。

asm 命令をIA32_THERM_STATUS使用してレジスタを読み取るには、ユーザー空間コードから呼び出すことができないため、カーネル空間コード (おそらくデバイス ドライバー?) が必要です。rdmsrrdmsr

組み込み関数__readmsr( http://msdn.microsoft.com/en-us/library/y55zyfdx(v=VS.100).aspxを参照) を使用することもできますが、いずれにしても同じ制限があります:「この関数はカーネルでのみ使用できます。モード"。

すべての CPU コアには独自のデジタル サーマル センサー (DTS) があるため、すべての温度を取得するにはさらにコードが必要です (おそらくアフィニティ マスクを使用しますか? Win32 API を参照してくださいSetThreadAffinityMask)。

いくつかのテストを行ったところ、実際にIA32_THERM_STATUSDTS の読み取り値と Prime95 の「インプレースの大きな FFT (最大の熱、電力消費、一部の RAM のテスト)」テストとの間に相関関係があることがわかりました。Prime95 はftp://mersenne.org/gimps/p95v266.zipです。

DTSの読み取り値から「CPU温度」(それが何を意味するか)を取得する式が見つかりませんでした。

編集:

興味深い投稿TJunction Max からの引用? #サームトリップ? #PROCHOT? 「fgw」による(2007 年 12 月):

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

于 2011-07-24T09:02:22.733 に答える
11

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

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

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

于 2011-03-16T15:10:10.240 に答える
0

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

于 2011-10-24T18:56:29.847 に答える