WriteFile() funktioniert nicht?
-
while(OutBuffer.empty() && isOpen); // WTF? Multithreading ohne Synchronisierung oder was machst du da?
Hier werden nur BOOL abgefragt und soviel ich weiß, sind das atomic instructions bei Windows.
while(XOFF); // ==""==
Auch nur ein BOOL.
c = OutBuffer.front(); OutBuffer.pop();
Nur eine FIFO.
Bis hier kann alles in meinem Programm unterbrochen werden, da es keine Auswirkungen hat. Zudem befindet sich das alles noch in der Entwicklung, demenstprechend sieht es noch etwas komisch aus. Und wie gesagt liegt der Fehler hier nicht, der Teil funktioniert.
DWORD dwWaitResult = WaitForSingleObject(SerialMutex, INFINITE); // WTF? Wieso ne Mutex und keine CRITICAL_SECTION? // Und wieso hier locken, hier bringt's nun auch nix mehr.
1. Weil es mir nicht um Timings geht.
1.1 Zitat:Critical Sections sind empfehlenswert wenn die kritische Codestelle nur selten von anderen Threads genutzt wird, also in der Regel nur selten auf die "Freigabe" eines anderen Threads gewartet werden muss.
2. Das der serielle Port nur 1x verfügbar ist und ich ihn deshalb gegen Mehrfachzugriff sperren muss ist dir nicht klar??
Und... was zum Geier heisst "MC"? Master of Ceremony? Music Cassette? Murks Code? ...?
Microcontroller
Und um es nochmal zusammenzufassen:
Du kannst nicht mal eine Annahme über Variablen treffen.
Kennst keine atomic instructions.
Willst while-Schleifen (die von globalen Variablen abhängig sind) mit einer Crictical section sperren.
Beleidigst Leute die ne Frage stellenEs war noch nie so leicht den Troll des Forums zu erkennen.
mfg
EDIT:
Bevor noch 10 (nutzlose) Antworten über den funktionierenden Teil des Codes kommen:
Die Fifo ist von mir selbst implementiert und Threadsafe. Deshalb funktioniert der Teil des Codes auch einwandfrei. Genau deshalb hab ich auch keine weiteren Infos gepostet. Es geht mir nur um WriteFile(), wo wieso auch immer ein falscher Wert gesendet wird.
-
WSK schrieb:
while(OutBuffer.empty() && isOpen); // WTF? Multithreading ohne Synchronisierung oder was machst du da?
Hier werden nur BOOL abgefragt und soviel ich weiß, sind das atomic instructions bei Windows.
Du Programmierst aber nicht Windows sondern C++.
Wenn dustd::atomic<BOOL>
verwendest ist alles OK. Wenn duvolatile BOOL
verwendest ist es zwar in Standard C++ nicht OK, aber in Kombination mit Visual C++ OK.
Wenn du einfach nurBOOL
verwendest ist es UB ("undefined behavior" aka. falsch).WSK schrieb:
Und wie gesagt liegt der Fehler hier nicht, der Teil funktioniert.
Wenn du meinst...
WSK schrieb:
DWORD dwWaitResult = WaitForSingleObject(SerialMutex, INFINITE); // WTF? Wieso ne Mutex und keine CRITICAL_SECTION? // Und wieso hier locken, hier bringt's nun auch nix mehr.
1. Weil es mir nicht um Timings geht.
Wie, Timings? Es geht um Synchronisation, und genau dafür sind CRITICAL_SECTIONs da. Ne CRITICAL_SECTION ist einfach ne Prozess-lokale Mutex. Der Unterschied zu einer Windows MUTEX ist bloss dass man ne CRITICAL_SECTION nur innerhalb eines Prozesses verwenden kann, und sie um Grössenordnungen (2-3 Zehnerpotenzen) schneller ist.
WSK schrieb:
1.1 Zitat:
Critical Sections sind empfehlenswert wenn die kritische Codestelle nur selten von anderen Threads genutzt wird, also in der Regel nur selten auf die "Freigabe" eines anderen Threads gewartet werden muss.
2. Das der serielle Port nur 1x verfügbar ist und ich ihn deshalb gegen Mehrfachzugriff sperren muss ist dir nicht klar??
Du hast das HANDLE auf den Port doch sowieso schon offen
Dir scheint nicht klar zu sein dass
a) Serielle Ports unter Windows nicht von mehreren Prozessen gleichzeitig geöffnet werden können und
b) Zugriffe über File und Device HANDLEs unter Windows sowieso threadsafe sind.D.h. wenn du das HANDLE auf den Port schon offen hast, dann brauchst du keine Mutex mehr um andere Prozesse daran zu hindern dazwischenzufunken.
Wenn es um anderen Threads im selben Prozess geht, und du nur den WriteFile Call absichern willst, dann brauchst du überhaupt nichts, da der von sich aus safe ist.D.h. die Vermutung lag nahe dass du damit Zugriffe auf irgendwelche Variablen/Datenstrukturen absichern willst, die du in mehreren Threads verwendest. Und dafür würde ne CRITICAL_SECTION reichen.
WSK schrieb:
Und um es nochmal zusammenzufassen:
Du kannst nicht mal eine Annahme über Variablen treffen.Och, ich kann das sogar ziemlich gut, ich kann bloss nicht hellsehen. Und vor allem dann nicht, wenn ich Code von jemandem lese der anscheinend nicht viel Plan hat von dem was er tut.
WSK schrieb:
Kennst keine atomic instructions.
Wieder falsch. Ich bin mir sogar 99.99% sicher dass ich mich damit wesentlich besser auskenne als du.
WSK schrieb:
Willst while-Schleifen (die von globalen Variablen abhängig sind) mit einer Crictical section sperren.
Lol, ja. Was auch wieder nur ein deutlicher Hinweis darauf ist dass ich im Gegensatz zu dir etwas (viel) Plan von Multithreading habe.
WSK schrieb:
Beleidigst Leute die ne Frage stellen
Wo?
WSK schrieb:
Die Fifo ist von mir selbst implementiert und Threadsafe. Deshalb funktioniert der Teil des Codes auch einwandfrei. Genau deshalb hab ich auch keine weiteren Infos gepostet.
Lol
WSK schrieb:
Es geht mir nur um WriteFile(), wo wieso auch immer ein falscher Wert gesendet wird.
Dein
WriteFile
Aufruf ist bloss dummerweise vollkommen OK, an dem kann es also nicht liegen.
Wäre daran etwas nicht OK gewesen, hätte ich dich das schon wissen lassen.
-
ps: Bist du dir sicher dass es ein virtueller COM Port ist? Also dass da nicht ein USB-RS232 Converter dran sitzt, und die Schnittstelle des µC ein echter COM Port ist?
Dann könnte es nämlich einfach an den seriellen Protokoll Parametern (Baudrate, Start-Bits, Stop-Bits etc.) liegen.
240 (0b11110000) vs. 'A' (41 bzw. 0b01000001) sieht zwar nicht nach einem Framing-Error aus, aber ausschliessen würde ich es nicht.
Dass du oft 0 liest ist auch verdächtig. Etliche UARTs ersetzen Bytes mit Framing-Errors halt einfach durch 0.Und nochwas: die FIFO zum Absenden kannst du dir vermutlich sparen. Windows hat selbst bereits Software-FIFOs für die COM Ports - du kannst ohne Probleme mehrere hundert Byte direkt auf den COM Port schreiben ohne dass der Aufruf blockiert. Falls nötig kannst du auch den IO Puffer mit
SetupComm
vergrössern.
-
Du Programmierst aber nicht Windows sondern C++.
Wenn du std::atomic<BOOL> verwendest ist alles OK. Wenn du volatile BOOL verwendest ist es zwar in Standard C++ nicht OK, aber in Kombination mit Visual C++ OK.
Wenn du einfach nur BOOL verwendest ist es UB ("undefined behavior" aka. falsch).Was? Ich bin hier nicht im WinAPI bereich wo es um Windowsprogrammierung geht? Wie konnte mir das nur passieren...
Wie, Timings? Es geht um Synchronisation, und genau dafür sind CRITICAL_SECTIONs
Natürlich geht es hier um Synchronisation. Ich wäre davon ausgegangen, dass dir das klar wäre. Ne CriticalSection wird ausgeführt, sobald möglich, ein Mutex (wenn nicht verfügbar) erst wieder, wenn der Scheduler es will. Deshalb zur Synchronisation zusätzlich das mit dem Timing!
D.h. die Vermutung lag nahe dass du damit Zugriffe auf irgendwelche Variablen/Datenstrukturen absichern willst, die du in mehreren Threads verwendest. Und dafür würde ne CRITICAL_SECTION reichen.
Es gibt nur ein paar bools und die wie bereits erwähnte FIFO (Threadsafe).
Och, ich kann das sogar ziemlich gut, ich kann bloss nicht hellsehen. Und vor allem dann nicht, wenn ich Code von jemandem lese der anscheinend nicht viel Plan hat von dem was er tut.
Hab ich gesagt, du sollst in uninteressantem Code hellsehen??
Wieder falsch. Ich bin mir sogar 99.99% sicher dass ich mich damit wesentlich besser auskenne als du.
Lol, ja. Was auch wieder nur ein deutlicher Hinweis darauf ist dass ich im Gegensatz zu dir etwas (viel) Plan von Multithreading habe.
Was? Haben wir schon wieder den 1. April?
ps: Bist du dir sicher dass es ein virtueller COM Port ist? Also dass da nicht ein USB-RS232 Converter dran sitzt, und die Schnittstelle des µC ein echter COM Port ist?
PC - USB - FTxxx - MCU
Dann könnte es nämlich einfach an den seriellen Protokoll Parametern (Baudrate, Start-Bits, Stop-Bits etc.) liegen.
Ich habe bereits im ersten Beitrag geschrieben, dass der Empfang geht, kann also wohl nicht daran liegen.
-
WSK schrieb:
Bevor noch 10 (nutzlose) Antworten über den funktionierenden Teil des Codes kommen:
Die Fifo ist von mir selbst implementiert und Threadsafe. Deshalb funktioniert der Teil des Codes auch einwandfrei. Genau deshalb hab ich auch keine weiteren Infos gepostet. Es geht mir nur um WriteFile(), wo wieso auch immer ein falscher Wert gesendet wird.Naja, WriteFile() ist halt nicht von Dir implementiert, sondern von Microsoft; was will man da erwarten ...
-
@WSK
Ich hab' zwar über 15 Jahre Erfahrung mit C++ Programmierung unter Windows, schon mehrere Windows-Projekte erfolgreich umgesetzt die über eine serielle Schnittstelle mit allem möglichen kommunizieren (diverse Mikrocontroller & Peripheriegeräte, sowohl über echte als auch virtuelle serielle Schnittstellen)...
Eines der Projekte ist ein Free-Threaded COM-Server der von dutzenden Kunden auf tausenden von Geräten verwendet wird - ohne Probleme...
Aber wenn du meinst dass ich keine Ahnung habe und dich, anstatt mal nachzufragen wenn du was nicht verstehst, lieber über mich lustig machst, dann hab ich verständlicherweise keine Lust mehr dir zu helfen.Also lös dein Problem mal hübsch selbst.
Und auch viel Spass mit den anderen Fehlern auf die ich versucht habe dich hinzuweisen, die sich früher oder später garantiert als echte Probleme im Betrieb manifestieren werden.
-
WSK schrieb:
Du Programmierst aber nicht Windows sondern C++.
Wenn du std::atomic<BOOL> verwendest ist alles OK. Wenn du volatile BOOL verwendest ist es zwar in Standard C++ nicht OK, aber in Kombination mit Visual C++ OK.
Wenn du einfach nur BOOL verwendest ist es UB ("undefined behavior" aka. falsch).Was? Ich bin hier nicht im WinAPI bereich wo es um Windowsprogrammierung geht? Wie konnte mir das nur passieren...
Ja, du bist im WinAPI-Bereich, da geht es um Programmierung mittels der WinAPI (das ist eine Ansammlung verschiedener Funktion und structs um Lowlevel-Zeug unter Windows zu machen). Nur weil du die WinAPI nutzt, heißt das nicht, dass sie dir garantiert dass BOOLs thread safe sind. Es kann durchaus Compiler (auch unter Windows!) geben, wo sie es nicht sind. Und dann läuft dein Programm auf einmal nicht mehr. Deswegen brauchst du bei solchen Sachen den C++ Standard, denn der macht die Garantien, was wie wann funktioniert. Und nur weil du windows.h einbindest, ändert sich daran nichts.
Zum Rest sag ich nichts, da kann ich mich nicht gut genug aus.
-
hustbaer schrieb:
@WSK
Also lös dein Problem mal hübsch selbst.
Und auch viel Spass mit den anderen Fehlern auf die ich versucht habe dich hinzuweisen, die sich früher oder später garantiert als echte Probleme im Betrieb manifestieren werden.Hab ich inzwischen auch
Die bools wurden zu deiner Zufriedenheit auch durch atomic<bool> ersetzt, ändert bei mir aber jetzt nichts.
Die von dir "unnötige" Synchronsierung von "WriteFile()" habe ich auch entfernt, dann passierte aber gar nichts mehr und ich musste sie wieder einfügen.
Die Fifo ist wie gesagt bereits Thread safe, aber wenn der serielle Port eh gepuffert ist, kann ich die wohl verwerfen. Mal sehen...
-
Und, was war jetzt das Problem?
BTW: "zufrieden" wäre ich mit dem Code noch lange nicht. Wenn es dich interessiert kann ich dir gerne die Probleme bzw. vermutlichen Fehler beschreiben. Den Aufwand spar' ich mir aber natürlich wenn du's in Wirklichkeit eh nicht lesen/wissen willst.
Und das mit der Mutex verstehe ich nicht wirklich. Wenn das nen Unterschied macht, dann ist die Chance ziemlich hoch dass der restliche Code, den ich nicht sehe, etwas macht, was er tunlichst nicht machen sollte.
-
WSK schrieb:
hustbaer schrieb:
@WSK
Also lös dein Problem mal hübsch selbst.
Und auch viel Spass mit den anderen Fehlern auf die ich versucht habe dich hinzuweisen, die sich früher oder später garantiert als echte Probleme im Betrieb manifestieren werden.Hab ich inzwischen auch
Dann lass uns Unwissende mal teilhaben an den neuen Erkenntnissen.
Die Bemerkungen von hustbaer sind alle ausnahmslos fachlich richtig.
Hustbaer hätte einiges etwas netter formulieren koennen - Beleidigungen sind m.E. nicht gefallen.Wenn sich ein Fagesteller absolut beratungsresistent und undankbar zeigt, finde ich es erstaunlich,
das es überhaupt Antworten gibt und jemand seine Zeit dafür investiert.Das mindeste wäre ein Danke an die Helfenden - selbst wenn nicht alle Beiträge zur Lösung beigetragen
haben sollten. Damit auch andere Forumnutzer was davon haben, ist auch das Feedback der Lösung wichtig.