Hallo Mikrocontroller-Gemeinde, wer kann mir mit seinem C#-Wissen weiterhelfen? Ein PC-Programm empfängt über die serielle Schnittstelle (UART vom µC) mehrere Bytes, diese werden im jetzigen Entwurf in ein char Array geladen. Die empfangenen Bytes 2-5 sollen nun zu einem 32bit - unsigned Integer zusammengesetzt werden. Beispiel: Empfangenes Byte 2 = 0x02 Empfangenes Byte 3 = 0xCA Empfangenes Byte 4 = 0x9A Empfangenes Byte 5 = 0x38 Die Bytes sollen zu 0x389ACA02 (dezimal 1.000.000.002) zusammengesetzt werden und in eine uint32 - Variable gespeichert werden, mit der dann im Programm weiter gearbeitet werden kann. Muss hierfür auch in C# mit Schiebeoperatoren gearbeitet werden? Danke für Eure Hilfe. Grüße
Moritz E. schrieb: > Muss hierfür auch in C# mit Schiebeoperatoren gearbeitet werden? Wäre eine saubere und portable Lösung. Hast du denn Angst vor den Schiebeoperationen?
1 | |
2 | |
3 | |
4 | |
5 | |
mfg mf
Angst nicht, nur Unwissenheit ;-) Bin nicht so Hochsprachen-affin und habe mich gefragt, ob es hier noch andere Optionen gibt. Danke!
Gast
#6534396
Moritz E. schrieb: > Bin nicht so Hochsprachen-affin und habe mich gefragt, ob es hier noch > andere Optionen gibt. Du könntest mit 256, 65535 und 16777216 multiplizieren. Wenn der Compiler schlecht ist, wird das allerdings weniger effizient ausgeführt. In C gäbe da noch Unions. C# hat das nicht.
Moritz E. schrieb: > Bin nicht so Hochsprachen-affin und habe mich gefragt, > ob es hier noch andere Optionen gibt. Du darfst dem Compiler aber unterstellen, dass er mit solchen Konstrukten gut umgehen kann.
Gast
#6534406
Hier noch ein Beispiel:
Byte[] bytes1 = { 0xEC, 0x00, 0x00, 0x00 };
Int32 value = BitConverter.ToInt32(bytes1, 0));
Gast
#6534460
Wenn man es maximal unportabel, aber schnell haben will, kann man sowas auch als Daten in ein Assemblerfile legen, statt einer Union in C. Damit hat man auch die maximale Kontrolle ueber die Endianness des Resultats. Das schliesst ein, dass man es auch maximal falsch machen kann. Schieben und Odern koennen Compiler aber eigentlich auch ganz gut. Wie gut, dass man in VHDL sowas auch direkt hinschreiben kann.
Gast
#6534523
Moritz E. schrieb: > mehrere Bytes, diese werden im jetzigen Entwurf in ein char Array > geladen Das würde ich in C# lieber nicht so machen. Das nutzt nämlich ein Encoding, um von Bytes auf Zeichen zu kommen. Empfange lieber direkt in ein Array von Bytes (byte[]).
Gast
#6536749
Stefan ⛄ F. schrieb: > In C gäbe da noch Unions. C# hat das nicht. Aber etwas, womit sich das analog bauen läßt. Die Grundlage ist (wie in C) die Struktur, aber die Zugriffssteuerung erfolgt teilweise über Attribute. Die dazu nötigen Attribute findet man im Namespace System.Runtime.InteropServices. Allerdings, wie in mehreren Postings bereits angemerkt: man sollte solche Sachen aus Gründen der Portabilität besser nicht verwenden, oder nur dann, wenn man genau weiss, was man tut. Sonst knallt es z.B. mit Mono auf einem ARM gar fürchterlich, obwohl der Code derselbe ist und die Quelle nach wie vor dieselben Daten liefert... Mit dem, was der genannte Namespace liefert, ist es aber durchaus möglich, solche Konverterstrukturen auch portabel hinzubekommen. Wenn man halt weiss, was man tut...
c-hater schrieb: > Sonst knallt es z.B. mit Mono auf einem ARM gar fürchterlich, > obwohl der Code derselbe ist und die Quelle nach wie vor > dieselben Daten liefert... In C mit Unions liegt der Stolperstein in der Endianness des Systems, aber meines Wissens laufen Windows, Dotnet, Mono und die dazugehörigen Infrastrukturen aber nur auf little-endian-Systemen. Wo liegt denn das Problem mit "Mono auf ARM" hier?
Gast
#6537093
S. R. schrieb: > In C mit Unions liegt der Stolperstein in der Endianness des Systems, Das ist nur einer der möglichen Stolpersteine. Es gibt da auch noch das Alignment-Problem.
c-hater schrieb: >> In C mit Unions liegt der Stolperstein in der Endianness des Systems, > Das ist nur einer der möglichen Stolpersteine. > Es gibt da auch noch das Alignment-Problem. Stimmt, das habe ich verdrängt.
Auch in C# gibt es sowas wie Unions:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
Allerdings geht die Diskussion schon völlig über das Problem hinaus. Hier reicht als Lösung der Schiebeoperator oder die BitConverter-Klasse aus. Char sollte wie schon erwähnt nicht verwendet werden, weil in C# Zeichen UTF-16 kodiert sind (also 16-bit breit). Byte ist die richtige Wahl. Sofern .NET Core/.NET 5 zum Einsatz kommt, kann man auch über die Verwendung von Span<T> nachdenken wenn es um Performance geht.
Hallo nochmal an alle, ich habe es zwischenzeitlich entsprechend euren Hinweisen umgesetzt, die Bytes werden jetzt in ein "echtes" Bytearray gespeichert und durch Schieben wieder zu einzelnen Variablen zusammengesetzt. Zu Beginn war es noch ein Char Array, mit der Umstellung des Encodings (vgl. https://docs.microsoft.com/en-us/archive/blogs/bclteam/serialport-encoding-ryan-byington) lief das auch. Fande die Lösung mit dem Bytearray am Ende aber die "sauberere". An der Stelle somit nochmal danke an Alle für den konstruktiven Input. Schön, dass es noch funktionierende Foren ohne Trolls gibt! Schönes Wochenende
Gast
#6550273
Moritz E. schrieb: > Schön, dass es noch funktionierende Foren ohne Trolls gibt! ROTFL Echt. Wie heisst das ?
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.