2011-03-16 59 views
18

私はCPUの温度センサーにアクセスし、それらを制御する必要のあるソフトウェアを開発中です。CPUの熱センサーにアクセスするには?

私はあまりハードウェアインターフェイスを知らない。私はちょうどマウスとのインターフェイス方法を知っています。私はそれについて多くのことを知りましたが、関連する情報やコードを見つけられませんでした。

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

答えて

11

あなたはC++からWMIを使用したWMI

にMSAcpi_ThermalZoneTemperatureからそれを読むことができます少し関与している、MSDN explanantion and examples

ノートを参照してください。

+0

非常に関連するソフトウェアは、しかし、コードは使用できません。 –

+0

申し訳ありません - はい、いくつかの所有権DLLのラッパーです。 –

15

元役に立たない答えを変更し、私はあなたがIAに興味があると仮定-32(Intelアーキテクチャ、32ビット)CPUとMicrosoft Windows。

モデル固有レジスタ(MSR)IA32_THERM_STATUSをコード7ビット持つ「デジタル読み出し(ビット22:16、RO) - TCCの活性化温度まで1℃に相対デジタル温度測定値を」 (「インテル®64およびIA-32アーキテクチャー - ソフトウェア開発者マニュアル - 第3巻(3A & 3B):システム・プログラミング・ガイド」http://www.intel.com/Assets/PDF/manual/325384.pdf)の「14.5.5.2デジタル・センサーの読み取り」を参照してください。

だからIA32_THERM_STATUSはあなたに「CPU温度」を与えるわけではありませんが、そのためのプロキシです。 IA32_THERM_STATUSは今rdmsrは、ユーザ空間のコードから呼び出すことはできませんので、あなたには、いくつかのカーネル空間コード必要があります(多分デバイスドライバを?)、あなたはASM命令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温度」(何かを意味するもの)を得る式が見つかりませんでした。

編集:

は(2007年12月)"fgw"で興味深い記事TJunction Max? #THERMTRIP? #PROCHOT?からの引用:

どのレジスタに特定のプロセッサのTJMAXを見つける方法はありません。 このように、ソフトウェアはこの値を読み取ることができません。さまざまなソフトウェア開発者が何をしているのか、彼らは特定の プロセッサの特定のtjunctionを仮定し、この情報をプログラム内のテーブルに保持していますか?それ以外には、tjmaxは正しい値でもありません。 という事実で、彼らはTCC活性化温度閾値を探しているという事実があります。この 温度スレッショルドは、現在の絶対値を計算するために使用されます。 コア温度。理論的に言うことができます:絶対 コア温度= TCC活性温度閾値 - DTS私は を理論的に言っていたので、上記のように、このTCC活性化温度閾値はソフトウェアで読むことができず、プログラマによって と仮定されなければならない。ほとんどの状況(coretemp、everest、...)では、 はプロセッサフ​​ァミリに応じて85Cまたは100Cの値をとり、 リビジョンになります。このTCC活性化温度閾値は、プロセッサごとに個別に製造中に を較正するので、 プロセッサで83Cであるが、他方では87Cである可能性がある。それらのプログラムがコア温度を計算している方法を考慮に入れて、 を自分で計算すると、正確な絶対コア温度はどれくらいですか? tjmaxも「最も望まれる」TCC活性化温度しきい値も はすべての公開Intelドキュメントで見つけることができません。いくつかの議論の後で、インテルの開発者フォーラムで をオーバーして、インテルは 情報を利用できるようにする兆候を示していません。

+0

何とか値を変更できますか? –

+0

@AkitoあなたはIA32_THERM_STATUSレジスタに書いているのですか?目的は何ですか? –

+0

私はハードウェアセキュリティの脆弱性に関する調査をしようとしていますので、コンピュータがオフになるように温度測定値に変更することができるかどうかを調べることを検討していました。 –

0

おそらくオペレーティングシステムによって異なります。 GNU/Linuxでは、これはACPIに関連しています。そして、ハードウェアの中には、温度を測定するための物理的な装置がないものもあります。

+0

だからこそ私はWindowsについて言及している。 –

17

特定のカーネルドライバがないと、WMI以外の温度を問い合わせることは困難です。

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; 
} 

といくつかのテストコード:ここではWMIのMSAcpi_ThermalZoneTemperatureクラスに基づいてそれをしないCコードの一部であり、

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); 
} 
+0

答えをありがとう。 –

+0

ほとんどのシステムドライバがこのWMIクラスを実装していないというのは本当に残念です。これは、ほとんどの場合、独自のカーネルモードドライバを作成する必要があるためです。 –

+0

2つの問題:(1)何らかの理由で、私が(非昇格プロセスから)このWMIメソッドを呼び出すと、 'IEnumWbemClassObject :: Next()'は常に '80041003'を返します。そして、(2)このプロセスを呼び出す場合でも、WMI呼び出しは成功しますが、返される値は決して変更されません。それを '((double)temp/10 - 273.15)'として出力します。 '27.85 'が間違っています。どんな考え? – c00000fd

関連する問題