Shared Memory von Everest verwenden

  • VB.NET

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von bimbo385.

    Shared Memory von Everest verwenden

    Hallo an alle VB Profis und alle Anderen die in diesem Forum unterwegs sind.

    Da ich hier neu bin, möchte ich kurz was zu mir und meinem Projekt sagen bevor ich zu meinem eigentlichen Problem komme (wen das nicht interessiert, kann ja glich unten weiterlesen).

    Ich bin ausgebildeter Elektroniker (für Geräte und Systeme) und kenne mich allgemein mit Elektronik ziemlich gut aus, was Programmierung angeht bin ich bei hardwarenahen Sachen (Mikrocontroller usw.) auch ziemlich fit. Nur bei objektorientierten Programmiersprachen bin ich noch ein blutiger Anfänger.
    Mit VB 2008 bin ich mittlerweile soweit, dass es reicht um mir ein paar Buttons und so zusammenzuklicken und ne COM-Schnittstelle (RS232/Seriell) anzusprechen.

    Jetzt hab ich folgendes vor und zwar baue ich ein Computergehäuse (mit Wasserkühlung und solchen Spielereien) aus MDF (mitteldichte Faserplatte) in das ein Grafik LCD mit t6963c Controller und 240x64 Pixeln hineinkommt.
    Das Display wird über einen Atmel Mikrocontroller angesteuert (Mega32 oder größer, evtl auch ein XMega). Der Mikrocontroller steuert neben dem Display auch noch die Lüfter (Wärmetauscher der Wasserkühlung, Gehäuse, usw.) und regelt die RGB-LED-Beleuchtung. Außerdem soll auch noch ein Wassertemperatursensor und evtl. ein DFM (Durchflussmesser) angeschlossen werden)

    Jetzt soll das LCD aber nicht nur die paar beschränkten Informationen anzeigen, die dem Mikrocontroller zur Verfügung stehen, sondern auch die Taktraten des Prozessors, der Grafikkarte und deren Temperaturen, also solche Infos wie zum Beispiel SpeedFan, CPUZ, Motherboardmonitor oder eben Everest (was jetzt ja wieder AIDA64 heißt) ausspucken.




    Ich hab die Version 5 von Everest, was auch alle relevanten Infos korrekt anzeigt. Im Optionsmenü gibt es einen Reiter für Externe Applikationen in dem man Shared Memory aktivieren kann. Diese Option gibt irgendwie die Sensordaten frei, sodass man die mit einer anderen Anwendung auslesen und weiterverarbeiten kann.

    Diese Funktion ist auch in der Everest Hilfe dokumentiert (ich hab die relevanten Seiten mal angehangen) und soweit auch verständlich.

    Virustrinity von LCD-Hype hat über diese Funktion auch schon ein Plugin für LCD-Hype realisiert, muss also auch prinzipiell funktionieren.

    Nur wie komme ich jetzt mit VB an diese Daten ran, damit ich die über eine COM-Schnittstelle am meinen Mikrocontroller weiterreichen kann???

    Ich hoffe ihr könnt mir da weiterhelfen und mir am besten ein Codeschnipsel zukommen lassen der mir diesen String ausließt.

    Gegoogelt hab ich schon und habe nichts gefunden, was mir weiterhilft. Was aber auch an meinen beschränkten VB-Kenntnissen liegen kann.


    Vielen Dank, wenn ihr schon mal bis hierhin gelesen habt ;)

    Bimbo385

    * Topic verschoben *
    Bilder
    • Everest Hilfe1.png

      15,33 kB, 794×1.123, 145 mal angesehen
    • Everest Hilfe2.png

      10,95 kB, 794×1.123, 132 mal angesehen
    • Everest Hilfe3.png

      13,42 kB, 794×1.123, 90 mal angesehen
    • Everest Hilfe4.png

      10,51 kB, 794×1.123, 110 mal angesehen
    • Everest Hilfe5.png

      10,41 kB, 794×1.123, 92 mal angesehen
    • Everest Hilfe6.png

      11,42 kB, 794×1.123, 81 mal angesehen
    • Everest Hilfe7.png

      13,48 kB, 794×1.123, 77 mal angesehen
    • Everest Hilfe8.png

      19,97 kB, 794×1.123, 122 mal angesehen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „der_Kurt“ ()

    Hi.

    Du musst zunächst alle Funktionen, die der Codeschnipsel verwendet, deklarieren. Das heißt, dass du deinem VB-Programm folgende Signaturen bekannt machen musst:
    - OpenFileMapping
    - MapViewOfFile
    - UnmapViewOfFile
    - CloseHandle

    Eventuell brauchst du auch noch CopyMemory, falls du den String mit der Marshal-Klasse nicht bekommst. Bei den Deklarationen ist die Webseite pinvoke.net sehr hilfreich.

    Wenn du das hast, kannst du das Delphi-Codefragment in VB übersetzen. Dabei wirst du Konstanten benötigen, wie z.B. FILE_MAP_READ. Deren Werte findest du meistens bei den Funktionen im MSDN. Wenn nicht, stehen sie in der Headerdatei, die unter jeder Funktion angegeben ist.

    Die Übersetzung selbst ist einfach - Variablen deklarieren, Funktionen aufrufen - alles was man sonst auch tut. Du solltest jedoch auf die Datentypen achten - unverwalteter Code lässt dabei keine Abweichungen zu. Wenn die Typisierung nicht passt, hast du verloren. Alles als "String" oder "Object" zu deklarieren ist also definitiv falsch.

    Und nun: Viel Spaß. Interop-Projekte sind lehrreich, aber anspruchsvoll.
    Gruß
    hal2000
    Erstmal Danke für die Hilfe!

    Ich hab die Deklarationen aus pinvoke.net einfach übernommen und mal versucht den Delphi Code zu übersetzen.

    Das ist bis jetzt dabei raus gekommen:

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. Imports System.Runtime.ConstrainedExecution
    3. Public Class Form1
    4. <DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    5. Public Shared Function OpenFileMapping(ByVal dwDesiredAccess As Integer, <MarshalAs(UnmanagedType.Bool)> ByVal bInheritHandle As Boolean, ByVal lpName As String) As IntPtr
    6. End Function
    7. <DllImport("Kernel32", CharSet:=CharSet.Auto, SetLastError:=True)> _
    8. Public Shared Function MapViewOfFile(ByVal hFileMapping As IntPtr, ByVal dwDesiredAccess As Integer, ByVal dwFileOffsetHigh As Integer, ByVal dwFileOffsetLow As Integer, ByVal dwNumberOfBytesToMap As Integer) As IntPtr
    9. End Function
    10. <DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True, ExactSpelling:=True)> _
    11. Public Shared Function CloseHandle(ByVal hObject As IntPtr) As Integer
    12. End Function
    13. <ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), DllImport("Kernel32", CharSet:=CharSet.Auto, SetLastError:=True)> _
    14. Public Shared Function UnmapViewOfFile(ByVal pvBaseAddress As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    15. End Function
    16. Const sharedmem_name = "EVEREST_SensorValues"
    17. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    18. End Sub
    19. Function ExtApp_SharedMem_ReadBuffer(ByVal PChar As Char, ByVal DWord As Integer) As Boolean
    20. Dim mappedData As Char = PChar
    21. Dim th As Integer = THandle
    22. Dim Result As Boolean = False
    23. th = OpenFileMapping(File_Map_Read, False, sharedmem_name)
    24. If th <> INVALID_HANDLE_VALUE Then
    25. mappedData = MapViewOfFile(th, FILE_MAP_READ, 0, 0, 0)
    26. If mappedData <> Nil Then
    27. StrLCopy(bu, mappedData, bu_size)
    28. If UnmapViewOfFile(mappedData) Then Result = True
    29. End If
    30. End If
    31. CloseHandle(th)
    32. End Function
    33. End Class


    Mir ist natürlich klar, dass mit den ganzen undeklarierten Dingern wie THandle, File_Map_Read, INVALID_HANDLE_VALUE, Nil, bu, bu_size und mappedData nicht funktionieren kann. Sind das jetzt Variablen, Konstanten oder was muss ich damit anstellen???

    Kannst du mir evtl. erklären, was die Funktion überhaupt im einzelnen macht? Das würde es für uns beide sicher einfacher machen.

    Außerdem gibt die Funktion ja nur ein Boolean Typ zurück, wie bekomme ich den überhaupt an die Daten (die ja den langen String enthalten) ran?


    Es währe echt nett, wenn ihr mir noch ein bisschen helfen könntet!

    Bimbo385
    Nehmen wir als Beispiel den Aufruf

    VB.NET-Quellcode

    1. th = OpenFileMapping(File_Map_Read, False, sharedmem_name)

    Der Rückgabewert deiner deklarierten Funktion ist IntPtr - also musst du th auch als IntPtr deklarieren.

    Was die Funktion im Einzelnen macht? Sie ruft fünf weitere Funktionen auf. Was diese Funktionen wiederum machen, steht im MSDN, zu welchem ich extra die Links gesetzt habe (siehe oben). Auch wenn du schon weit gekommen bist: Es reicht nicht aus, die Deklarationen von pinvoke einfach zu übernehmen. Du musst schon das MSDN lesen, um die Paramter und die Rückgabewerte zu verstehen.

    Wo du die Konstanten herbekommst, hatte ich auch schon geschrieben - INVALID_HANDLE_VALUE ist z.B. 0 bzw. IntPtr.Zero ("If the function fails, the return value is NULL.").

    Aber: Du bist auf einem guten Weg.
    Gruß
    hal2000
    Hi,

    ich hab mein Problem erstmal auf andere Weise gelöst und zwar über die Regestry Einträge (da kann Everest nämlich auch die Werte reinschreiben).
    Die kann ich einfach mit z.B.:

    VB.NET-Quellcode

    1. readValue = My.Computer.Registry.GetValue("HKEY_CURRENT_USER\Software\Lavalys\EVEREST\SensorValues", "Value.FCPU", Nothing)


    auslesen und weiterverarbeiten.

    Trotzdem vielen Dank für deine Bemühungen!!!

    Beim nächsten Problem (was bestimmt kommt ;) melde ich mich wieder.

    Viele Grüße,
    Bimbo385

    So gehts, nach Jahren für ein ähnliches Projekt gebraucht

    Ist jetzt für AIDA64, dem Nachfolger von Everest.

    Nur für den Fall das es noch jemand braucht.
    Zum testen als Konsolenanwendung. Sollte einfach auf die jeweilige Anwendung umzusetzen sein.


    VB.NET-Quellcode

    1. Imports System.IO
    2. Imports System.IO.MemoryMappedFiles
    3. Module Module1
    4. Structure XmlElement
    5. Dim id As String
    6. Dim label As String
    7. Dim value As String
    8. End Structure
    9. Sub Main()
    10. Dim buffer(10240) As Byte
    11. Dim xmlString As String = "<?xml version=" & Chr(34) & "1.0" & Chr(34) & "?><AIDA>" '<?xml version="1.0"?>
    12. Dim i As Integer
    13. Dim aidaTemperaturen As New List(Of XmlElement) 'Eine Liste von XmlElementen
    14. Dim aidaSystemwerte As New List(Of XmlElement) 'Eine Liste von Systemwerten
    15. Dim xmlTest As XmlElement
    16. Dim mem As MemoryMappedFile
    17. mem = MemoryMappedFile.CreateOrOpen("AIDA64_SensorValues", 10240)
    18. Dim memstream As MemoryMappedViewStream
    19. memstream = mem.CreateViewStream
    20. Console.WriteLine("Lese alle AIDA Werte aus:" + vbCrLf)
    21. memstream.Read(buffer, 0, 10240)
    22. For i = 0 To 10240
    23. If buffer(i) <> 0 Then xmlString = xmlString + Chr(buffer(i))
    24. Next
    25. xmlString = xmlString + "</AIDA>"
    26. 'Console.WriteLine(xmlString) 'Gebe das XML Dokument aus
    27. Dim XmlDok As New Xml.XmlDocument()
    28. XmlDok.LoadXml(xmlString) 'Hier haben wir jetzt ein Xml Dokument von AIDA
    29. 'Alle Temperaturen (/AIDA/temp) auswählen und einzel nach dessen Inhalt abfragen
    30. For Each xmlTempNode As Xml.XmlNode In XmlDok.DocumentElement.SelectNodes("/AIDA/temp")
    31. xmlTest.id = xmlTempNode.SelectSingleNode("id").InnerText
    32. xmlTest.label = xmlTempNode.SelectSingleNode("label").InnerText
    33. xmlTest.value = xmlTempNode.SelectSingleNode("value").InnerText
    34. aidaTemperaturen.Add(xmlTest)
    35. Next
    36. 'Alle Systeminfos (/AIDA/sys) auswählen und einzel nach dessen Inhalt abfragen
    37. For Each xmlTempNode As Xml.XmlNode In XmlDok.DocumentElement.SelectNodes("/AIDA/sys")
    38. xmlTest.id = xmlTempNode.SelectSingleNode("id").InnerText
    39. xmlTest.label = xmlTempNode.SelectSingleNode("label").InnerText
    40. xmlTest.value = xmlTempNode.SelectSingleNode("value").InnerText
    41. aidaSystemwerte.Add(xmlTest)
    42. Next
    43. For Each xmlTest In aidaTemperaturen
    44. Console.WriteLine(xmlTest.id + " " + xmlTest.label + " " + xmlTest.value)
    45. Next
    46. For Each xmlTest In aidaSystemwerte
    47. Console.WriteLine(xmlTest.id + " " + xmlTest.label + " " + xmlTest.value)
    48. Next
    49. Console.Read()
    50. End Sub
    51. End Module



    Mfg Bimbo385