Aber wie bekomme ich das ganze in eine union, sodass ich auch leds.byte schreiben kann? Es war ganz einfach, oder kann ich das Bitfeld auch direkt in der union amlegebn? wenn ja, wie geht das noch, sodass ich es als Datentyp wie ein int einsetzen kann?
Genau das habe ich gesucht, wollte mir alle "Zwischenamen" sparen, wusste aber nicht mehr, wie ich das ideal verschachteln kann, klasse, läuft schon, vielen Dank.
Ich mache das mit dem struct allerdings so:
struct
{
uint8_t led1 :1,
led2 :1,
led3 :1,
led4 :1,
led5 :1,
led6 :1,
led7 :1,
led8 :1;
};
Warum tut Ihr Euch das an? Findet Ihr das geil, solche Konstrukte, nur um ein Bit zu adressieren? Dass man sowas überhaupt fragen muss, unglaublich! Nur weil Euer lustiges C "Standard" ist...
Bit-Adressierung in mikroBasic:
1
PORTB.5 = 0
Und in Oshonsoft-Basic:
1
TRISA.1 = 0
Low-Byte und High-Byte:
1
i = x.LB
2
j = x.HW
Während Ihr Euch mit der Syntax abmüht, kann man sich in anderen Programmiersprachen auf die Aufgabe konzentrieren!
Während Ihr Euch mit der Syntax abmüht, kann man sich in anderen
Programmiersprachen auf die Aufgabe konzentrieren!
"Kein ernsthafter Programmierer über 12 Jahre arbeitet mit Basic." - Spruch eines Profs aus dem Studium.
Basic ist was für alte Leute, die das vor zig Jahren mal gelernt haben (in der DDR war es wohl noch ziemlich verbreitet) oder was zum Einstieg.
Statt Basic nimmt man inzwischen doch eher python.
Es geht nicht darum, was wir geil finden. Wir können uns die Programmiersprache nicht einfach frei aussuchen.
Nur weil Microbasic hier und da eleganter ist, kann es noch lange nicht C ersetzen. Das closed-source Modell ist für viele Firmen schon ein Blocker. Dazu kommen zahlreiche bewährte Bibliotheken, die man nicht ohne wichtigen Grund neu schreibt. Die performance wäre auch noch ein Punkt.
"Kein ernsthafter Programmierer über 12 Jahre arbeitet mit Basic." -
Spruch eines Profs aus dem Studium.
komisch in meinem E-Technik Studium zum Diplomingenieur war Basic am Terminal vom Großrechner Standard. Wir waren ALLE über 12 Jahre.
OK, ernsthaft programmieren wollten die meisten wohl nicht machen deswegen ja E-Technik und nicht Informatik.
komisch in meinem E-Technik Studium zum Diplomingenieur war Basic am
Terminal vom Großrechner Standard.
Vermutlich weil die Konstrukteure des Großrechners das so wollten.
Großrechner != Mikrocontroller
Wir waren ALLE über 12 Jahre.
Ja, und zu dem Spruch sollte man sich noch das Grinsen des Profs denken.
Im Bildverarbeitungslabor haben wir mit VisualBasic programmiert.
Einerseits gab es das damals (Anfang der 2000er) schon kostenlos von MS, andererseits hatten wir eine großen Anteil Kommilitonen, die gerade mal ihren PC zum Schreiben der Hausaufgaben einschalten konnten.
OK, ernsthaft programmieren wollten die meisten wohl machen deswegen ja
E-Technik und nicht Informatik.
Informatik hat eigentlich nur zweitrangig was mit der Verwendung von Programmiersprachen zu tun. Das ist (an der Uni) ziemlich theoretischer Kram, weswegen viele lieber an die FH gegangen sind (andere haben eine Ausbildung angefangen...).
Das würde mich mal aus der Praxis interessieren: Der Beruf des Fachinformatiker für Anwendungsentwicklung: Wie viele davon entwickeln tatsächlich Anwendungen?
In meinem Berufsleben habe ich überwiegend Elektroingenieure kennen gelernt, die als Quereinsteiger programmieren.
Informatik hat eigentlich nur zweitrangig was mit der Verwendung von
Programmiersprachen zu tun.
und trotzdem hatten wir in der Industrie eine studentische Hilfskraft die "unseren Ing. Code" sauber in Libs umsetzte damit sie für alle nutzbar wurde, stellenweise sogar in ASM weil der Prüfrechner PC zu wenig Speicher hatte.
In meinem Berufsleben habe ich überwiegend Elektroingenieure kennen
gelernt, die als Quereinsteiger programmieren.
wie alle bei "uns" in der Prüfmittelentwicklung.
Der Abteilungsleiter war sogar verwundert warum unser Werkstudent die größte teuerste Maschine ein 486er mit 19" Monitor für 25.000,- DM bekam und nicht der Projekt führende Ingenieur. Wir mustem dem Abteilungsleiter erklären das alle Prüfingnieure davon provitieren wenn die studentische Hilfskraft mehr Compilerläufe pro Tag schafft, während wir auf dem blinkenden Cursor schauend über den nächsten Programmteil nachdachten, top down Entwicklung.
Basic spielt heute im E-Technik Studium keine Rolle mehr. C, C++, Java, C# und geringfügig Assembler. Zusätzlich noch ein wenig VHDL und mehr brauchts auch nicht im Berufsleben als E-Techniker. Und wenn doch, dann kann man es auch da noch lernen. Die Alten sehen das vllt anders.
Das mit dem Struct, union und Zuweisung mit Doppelpunkt ist jedenfalls sehr interessant und werde ich bei mir in C Projekten definitiv mal anwenden. Bisher hatte ich mir enumerationen erstellt und einzelne Bits über Bitoperatoren verändert.
uint8_t var
enum{
Bit0 = 1,
Bit1 = 2
}
Bit setzen: var |= (1<<Bit0)
Bit löschen dann var &= ~(1<<Bit0)
Ist auch ok und funktioniert halt auch genau so in C#. Werde jetzt kein Projekt umschreiben, aber bei einem neuen das mit den Struct mal ausprobieren
Wenn man es testet und es funktioniert, dann funktioniert es. Oh Wunder.
Es funktioniert DIESES Mal. Auf DIESER Architektur und mit DIESEM Compiler auf DIESEM Release-Stand.
Das mag für's Hobby oftmals genug sein.
Aber ernsthaft darauf verlassen solltest du dich besser nicht.
Es funktioniert DIESES Mal. Auf DIESER Architektur und mit DIESEM
Compiler auf DIESEM Release-Stand.
Wir verwenden es auch in der Firma.
Liegt wohl daran, dass wir da nur Controller mit dem selben Endian verwenden (STM32 und AVR).
Der arm-Compiler ist inzwischen ein neues Release, und der "alte Kram" funktioniert trotzdem (wäre auch dämlich von Hitex, das einfach mal zu ändern)-
In C sind unions nur Container für verschiedene Datentypen, aber nicht zur Wandlung.
Es kommt zudem mit so vielen Unbekannten (Alignment, Reihenfolge, interne Darstellung von z.B. Pointern oder Float), dass es keinen Sinn macht, dafür "allgemeingültige" Regeln aufzustellen.
die einzige "erlaubte" Umwandlung ist von einen Datentyp in Bytes und vice versa. Deshalb funktioniert z.B. memcpy.
Das es von den meisten trotzdem zuverlässig angewendet wird, geschenkt. Dass andere auf irgendwelche Serialisierungen bestehen, auch.
Für Beispiele des TOs nutze ich praktisch nur noch Funktionen/Makros, die z.B. den LED-Typ in BYTE konvertieren. Plus ein paar Compile-Time-Asserts, die zumindest Allignment und Size überwachen.
Da stimme ich dir zu, hatte ich allerdings als Voraussetzung angenommen.
Dann jedoch geht der Alte und es kommt der nächste Entwickler. Und verlässt sich auf saubere Programmierung in den zig-tausend Zeilen Code.
Nicht auf verborgene Tretminen.
Dann jedoch geht der Alte und es kommt der nächste Entwickler. Und
verlässt sich auf saubere Programmierung in den zig-tausend Zeilen Code.
Nicht auf verborgene Tretminen.
Gibt's bei uns nicht in der Form. Dann müssten gleich alle Softies hinschmeißen, und dafür ist unser Betriebsklima zu gut. (Und ich verlassen den Betrieb entweder als Rentner oder auf ner Bare).
Das ist nun hohles Geschwätz, wenn man dein ursprüngliches Statement
auch nur halbwegs ernst nimmt.
Nein, nicht unbedingt. Zb eine MCU als Schnittstelle zwischen Elektronik und SPS. In einer Statusvariablen werden per Interrupt Bits gesetzt oder gelöscht. Der MCU ist hier der Datentyp egal. Die Statusvariable kann zb ein 16 Bit Short sein oder ein Struct. Wenn der Struct im Speicher die Größe einer Short hat, dann kann er auch als solcher gecastet und an die SPS weitergeleitet werden. Mir geht es primär um die Lesbarkeit von Code. Dies wäre bei einem Struct besser als mit Bitoperatoren
Mir geht es primär um die Lesbarkeit von
Code. Dies wäre bei einem Struct besser als mit Bitoperatoren
Eigentlich ist schon alles gesagt, daher vielleicht nur noch folgender (ganz allgemein geltender) Gedanke:
Wer mit Bitoperationen und einfacher boolescher Algebra in ›C‹ nicht klarkommt, der sollte besser erneut lesen und lernen. Oder eine einfachere Programmiersprache (vielleicht mit BA beginnend…) benutzen.
Die üblichen AND, OR, XOR und NOT Operationen lesen sich jedenfalls praktisch von allein und brauchen keinen syntaktischen Gehgips.
Welchen Wert hätte in Deinem /enum/ der Wert "Bit7"?
War ein Beispiel und keine Stackoverflow Lösungsfunktion. Kanns du aber dennoch gerne per copy paste verwenden und dich danach wundern warum es nicht geht.
Basic spielt heute im E-Technik Studium keine Rolle mehr. C, C++, Java,
C# und geringfügig Assembler. Zusätzlich noch ein wenig VHDL und mehr
brauchts auch nicht im Berufsleben als E-Techniker.
Stand heute würde ich da mindestens eine Scriptsprache (aktuell wohl Python) und evtl. noch Rust ergänzen. Bin jetzt Mitte 40, mit ASM und C "groß" geworden und würde mir nicht zutrauen zu sagen das das in der Zeit gelernte C++, Perl und Python für das verbleibende Berufsleben reicht. Programmiersprachen kommen und gehen. Für die reine Anwendungsentwicklung übernimmt die KI gerade jede Menge Programmiersprachengefummel. Und auch im maschinennahen Bereich wird das erschreckenderweise immer besser.
Auf dem ESP32 habe ich die Structs in der richtigen Bytefolge aber mit
absteigender Bitfolge anlegen müssen.
i.d.R. kann man die Bit-Reihenfolge mit einem Compilerschalter ändern.
Bei einer Big-Endian-Maschine, gibt es das Problem, dass man unterschiedliche Anordnungen braucht, je nachdem ob man Byteweise darauf zugreifen möchte oder mit breiteren Werten (unsigned short, int oder long).
Bool ist an der Stelle nur 1 Bit breit, dank des :1
Nach meinem Verständnis beschreibt Bool den Typ, von dem die struct abgeleitet ist. Bool ist eh meist nur eine Makroname, der durch einen anderen ersetzt wird (z.B. int).
Solange der Prozessor keine Möglichkeit der 1-Bit-Adressierung (wie 8051) hat, wird der Compiler daraus immer Bitschubscherei machen.
Byte bitweise und als ganzes zugreifen als Datentyp in c
Die Frage sehe ich noch nicht gelöst, das geht wohl nur sicher mit Bitmasken.
Oder man nutzt predefined Macros (Gnu oder Posix?) sofern für Bitfolge etwas derartiges vorhanden. Aus der Byte Endianess ableiten reicht in der Praxis vermutlich.
Der Wunsch nach "Portabilität" findet irgendwo sein Ende.
Alles findet irgenwo ein Ende, selbst unser Leben, selbst die Sonne,
also ist dieser Satz eine Nullinformation und überflüssig.
Nein er hat recht. Sie findet ihr Ende in einer gut gemachten HAL oder in HW-unabhängigen Modulen.
Hat man sowas, macht es also richtig, kann man über die Methode WIE man letztlich einen Pin setzt nur lächeln. Es hat keine Bedeutung mehr und es lohnt nicht sich damit zu verkünsteln. Weil es dann nur noch an ganz wenigen Stellen im Programm vorkommt. Und das ist mal nicht die Applikationslogik.
Bis dahin kann man (oder ich) auf zu kleine Speicher eben diesen
sparsamer nutzen wenn es benötigt wird.
Weil man oder du einfach keine Ahnung von guter SW-Entwicklung haben und gute und sinnvolle Abstraktion nicht verstehen geschweige denn implementieren können.
Speicher ist heute sicher nicht dein Problem. Es ist wenn dann eine Ausrede für fehlende Skills.
Ich mache jetzt mal den Erbsenzähler: der C Standard legt die Reihenfolge der Bitfields innerhalb eines Bytes nicht fest. Theoretisch könnten verschiedene Compiler für die gleiche Plattform das unterschiedlich handhaben. Und das ist streng genommen unabhängig von Endianess.
In der Praxis fällt beides zusammen, man hat also nur die beiden Fälle.
Das führt dazu, dass der wichtigere der beiden Anwendungsfälle von Bitfields nicht sicher funktioniert. Es bleibt nur der Aspekt "Platz sparen".
komisch in meinem E-Technik Studium zum Diplomingenieur war Basic am
Terminal vom Großrechner Standard.
Basic als Standard auf einem Großrechner und das an einer Uni?
Mich würde ernsthaft interessieren, wann und wo das gewesen sein soll.
1985 an der TU Berlin hat man E-Technikstudenten im ersten Semester Programmieren mit Pascal näherzubringen versucht. Das lief auch auf den Terminals eines Großrechners.
Die Struktur benötigt wie erwartet in Summe 4 Bytes. "all" nutze ich um alles auf null zu setzen, die bytes meistens in den Verarbeitungsroutinen und die Bitzugriffe dann in den Menüs oder im höheren code. Passt ganz gut für meine Zwecke. Klar gibt es viele Wege nach Rom in C, aber das hier gefällt mir momentan ganz gut, habe eine Zeit lang auch vieles mit Makros gemacht...
Wie gesagt das ist Glück wenn es bei Dir so funktionieren sollte (Bitfolge getestet?) Ebenso Deine byte Zugriffe sind von Endianness abhängig und nicht portabel. Hinzu kommt Padding compilerabhängig fürs Alignment.
Wie gesagt das ist Glück wenn es bei Dir so funktionieren sollte
Manchmal muss man auch mal einen Nagel in die Wand schlagen. Sprich: Ausprobieren ob es klappt. Oder die Implementierungsspezifischen Eigenschaften des Compilers studieren und es für das eigene System zum Laufen bringen ohne den Anspruch, dass alles so wunderbar kompatibel ist.
Eine Mathe-Lib oder ein Protokoll-Konverter sollte sich nicht auf ein Padding verlassen, geschenkt.
Aber die Vorstellung, dass jeder HW-Zugriff auch für 9Bit-Chars, beide Endians und Einer-Komplement funktionieren muss, ist weltfremd.
Die meisten Entwickler haben schon Probleme mit Format-Specifiern in einem konkreten System. Der "richtige" Weg für alle Int-Größen macht das nicht zuverlässiger sondern fragiler.
Für das Padding kann man eine Instruktion vor das Struct setzen, sodass es ohne Padding kompiliert wird.
Bei der Endianess muss man halt wissen für welches System. Ich hatte bisher immer little endian. Bei den ganzen STM32 MCUs ist es little endian, bei C# unter .Net auf x86 ist es little endian, bei Beckhoff Twincat ist es little endian. Aber wenn man ein solches Programm schreibt, dann muss man halt im falle einer Portierung sicherstellen dass es mit der neuen Architektur funktioniert. Bei Kommunikation unterschiedlicher Architekturen kommt man ohnehin nicht drum herum sicherzustellen, dass es untereinander kompatibel ist und sich gegebenfalls an den Standart der Protokolle halten, zb Ethernet mit big endian. Jaja, wenn beide Endpunkte little endian haben ist es wieder wurst was das Protokoll dazwischen macht.