Forum: PC-Programmierung Integer zusammensetzen


von Moritz E. (familienvater)


Lesenswert?

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

von Achim M. (minifloat)


Lesenswert?

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
uint32_t ergebnis =
2
(((uint32_t)0x02)      ) |
3
(((uint32_t)0xCA) <<  8) |
4
(((uint32_t)0x9A) << 16) |
5
(((uint32_t)0x38) << 24)  ;

mfg mf

von Moritz E. (familienvater)


Lesenswert?

Angst nicht, nur Unwissenheit ;-)

Bin nicht so Hochsprachen-affin und habe mich gefragt, ob es hier noch 
andere Optionen gibt.

Danke!

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

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.

von S. R. (svenska)


Lesenswert?

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.

von Ozvald K. (Gast)


Lesenswert?

Hier noch ein Beispiel:

Byte[] bytes1 = { 0xEC, 0x00, 0x00, 0x00 };
Int32 value =  BitConverter.ToInt32(bytes1, 0));

von schlaubischlumpf (Gast)


Lesenswert?

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.

von fop (Gast)


Lesenswert?

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[]).

von c-hater (Gast)


Lesenswert?

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...

von S. R. (svenska)


Lesenswert?

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?

von c-hater (Gast)


Lesenswert?

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.

von S. R. (svenska)


Lesenswert?

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.

von Florian S. (sevenacids)


Lesenswert?

Auch in C# gibt es sowas wie Unions:
1
using System;
2
using System.Runtime.InteropServices;
3
4
[StructLayout(LayoutKind.Explicit)]
5
public struct Union
6
{
7
    // Vier Bytes
8
    [FieldOffset(0)] public Byte b1;
9
    [FieldOffset(1)] public Byte b2;
10
    [FieldOffset(2)] public Byte b3;
11
    [FieldOffset(3)] public Byte b4;
12
    // Oder ein Int32
13
    [FieldOffset(0)] public Int32 i;
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.

: Bearbeitet durch User
von Moritz E. (familienvater)


Lesenswert?

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

von fop (Gast)


Lesenswert?

Moritz E. schrieb:
> Schön, dass es noch funktionierende Foren ohne Trolls gibt!

ROTFL
Echt. Wie heisst das ?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.