it-swarm.com.de

Wie greife ich auf die Wärmesensoren der CPU zu?

Ich arbeite an einer Software, mit der ich auf die Temperatursensoren in der CPU zugreifen und sie steuern kann.

Ich kenne nicht viele Hardware-Schnittstellen. Ich weiß nur, wie man eine Schnittstelle mit der Maus herstellt. Ich habe viel gegoogelt, aber keine relevanten Informationen oder Codes gefunden.

Ich muss das wirklich in meine Software einfügen. Bitte führen Sie mich durch die Steuerung der Sensoren mit C oder C++ oder ASM.

20
Fahad Uddin

Ohne einen bestimmten Kernel-Treiber ist es schwierig, die Temperatur anders als über WMI abzufragen. Hier ist ein Teil des C-Codes, der dies tut, basierend auf der MSAcpi_ThermalZoneTemperature-Klasse von 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;
}

und ein Testcode:

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);
}
17
Simon Mourier

Ich nehme an, Sie interessieren sich für eine IA-32-CPU (Intel Architecture, 32-Bit) und Microsoft Windows.

Das modellspezifische Register (MSR) IA32_THERM_STATUS enthält 7 Bits, die die "Digital Readout (Bits 22:16, RO) - Digitale Temperaturanzeige in 1 Grad Celsius relativ zur TCC-Aktivierungstemperatur" codieren. (siehe "14.5.5.2 Lesen des digitalen Sensors" in "Intel® 64- und IA-32-Architekturen - Software-Entwicklerhandbuch - Band 3 (3A & 3B): Systemprogrammierungshandbuch" http://www.intel.com/ Assets/PDF/Handbuch/325384.pdf ).

IA32_THERM_STATUS gibt Ihnen also nicht die "CPU-Temperatur", sondern einen Proxy dafür.

Um das IA32_THERM_STATUS-Register zu lesen, verwenden Sie die asm-Anweisung rdmsr. Jetzt kann rdmsr nicht vom Benutzer-Space-Code aus aufgerufen werden. Daher benötigen Sie einen Kernel-Space-Code (möglicherweise einen Gerätetreiber?).

Sie können auch den internen Code __readmsr (siehe http://msdn.Microsoft.com/de-de/library/y55zyfdx(v=VS.100).aspx ) verwenden, der ohnehin die gleiche Einschränkung hat: "Diese Funktion ist nur im Kernelmodus verfügbar ".

Jeder Prozessorkern hat seine eigenen digitalen thermischen Sensoren (Digital Thermal Sensors, DTS). Daher ist mehr Code erforderlich, um alle Temperaturen zu ermitteln (möglicherweise mit der Affinitätsmaske (siehe Win32-API SetThreadAffinityMask).

Ich habe einige Tests durchgeführt und tatsächlich eine Korrelation zwischen den IA32_THERM_STATUS DTS-Ablesungen und dem Prime95-Test "In-Place-Large-FFTs (maximaler Wärme- und Stromverbrauch, einige RAM getestet)" festgestellt. Prime95 ist ftp://mersenne.org/gimps/p95v266.Zip

Ich habe keine Formel gefunden, um die "CPU-Temperatur" (was auch immer das bedeuten mag) aus der DTS -Anzeige zu bekommen.

Bearbeiten:

Zitieren aus einem interessanten Beitrag TJunction Max? #THERMTRIP? #PROCHOT? von "fgw" (Dezember 2007):

es gibt keine Möglichkeit, tjmax eines bestimmten Prozessors in einem beliebigen Register zu finden. . Daher kann keine Software diesen Wert lesen. Was verschiedene Softwareentwickler tun, geht einfach davon aus, dass sie für einen bestimmten - Prozessor eine bestimmte Funktion annehmen und diese Informationen in einer Tabelle innerhalb des Programms halten. Außerdem ist Tjmax nicht Sogar den korrekten Wert, nach dem sie suchen. in suchen sie nach TCC-Aktivierungs-Temperaturschwellen. Diese Temperaturschwelle wird verwendet, um die aktuellen absoluten Korntemperaturen von zu berechnen. Theoretisch kann man sagen: Absolute Kerntemperatur = TCC-Aktivierungstemperaturschwelle - DTS Ich musste theoretisch sagen, weil, wie oben erwähnt, diese TCC-Aktivierungstemperatur Schwelle kann nicht von der Software gelesen werden und muss vom Programmierer angenommen werden. In den meisten Situationen (Coretemp, Everest, ...) nehmen sie je nach Prozessorfamilie und Revision einen Wert von 85C oder 100C an. Da dieser TCC-Aktivierungstemperaturschwellenwert während der Herstellung pro Prozessor individuell kalibriert wird, kann er 83C für einen Prozessor sein, kann jedoch 87C für den anderen sein. Wenn Sie die - Methode berücksichtigen, in der diese Programme die Coretemperaturen berechnen, können Sie selbst herausfinden, wie genau die absoluten Coretemperaturen sind! Weder tjmax noch die "meistgesuchte" TCC-Aktivierungs-Temperaturschwelle kann in öffentlichen Dokumenten gefunden werden. Nach einigen Diskussionen im Intel-Entwicklerforum zeigt Intel kein Zeichen, um diese - Informationen zur Verfügung zu stellen.

15

Sie können es von der MSAcpi_ThermalZoneTemperature in WMI lesen

Die Verwendung von WMI aus C++ ist etwas kompliziert, siehe MSDN-Erklärung und Beispiele

hinweis: Die ursprüngliche nicht hilfreiche Antwort wurde geändert

11
Martin Beckett

Das hängt wahrscheinlich vom Betriebssystem ab. Unter GNU/Linux ist es mit ACPI verwandt. Und manche Hardware besitzt nicht einmal die physischen Geräte, um die Temperatur zu messen.