Hallo, ja ich denke die Frage ist eindeutig ? Ich muss in meinem MCU ca. 4x70 Bit abspeichern. Wenn ich dafür Char[x] verwende, dann ist das doch Speicherplatzverschwendung. Also Bit Varname [70] wäre super, geht nur bei meinem HI-TECH C (PIC) nicht. Wie sieht es in der AVR Welt aus ? Gruß Dirk
Gast
#3196802
Dirk F. schrieb: > Hallo, > ja ich denke die Frage ist eindeutig ? > Ich muss in meinem MCU ca. 4x70 Bit abspeichern. > Wenn ich dafür Char[x] verwende, dann ist das doch > Speicherplatzverschwendung. > Also Bit Varname [70] wäre super, geht nur bei meinem HI-TECH C (PIC) > nicht. > Wie sieht es in der AVR Welt aus ? > Gruß Dirk Warum? Weil C keine ernstzunehmende Programmiersprache ist und auch nicht als solche konzipiert wurde. Nichts weiter als ein Treppenwitz der EDV-Geschichte. Verwende Assembler, dann musst Du Dich nicht mehr mit den Unzulänglichkeiten und Fehlern der sog. "Compiler" herumplagen.
4 Bit = 1 Nibble = 1/2 Byte Klingt brauchbar. Und wenn man sich mit Bitmanipulation ein wenig auskennt, ist das alles kein Thema. Und für einen bequemen Zugriff gibt es Funktionen. char bitfeld [35];
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
Löschen und Abfragen geht genau so
@frickelsprachenhasser (Gast) >EDV-Geschichte. Verwende Assembler, dann musst Du Dich nicht mehr mit >den Unzulänglichkeiten und Fehlern der sog. "Compiler" herumplagen. Aha. Verwende einen Faustkeil, weil das iPad noch nicht Gedanken lesen kann und man es noch mit den Fingern bedienen muss.
Gast
#3196809
> Wenn ich dafür Char[x] verwende, dann ist das doch > Speicherplatzverschwendung. Wieso das denn, braucht genau (n +7) /8 unsigned char, noch dichter gepackt gehts nicht auf den üblichen binären Plattformen. Nur die Zugriffe sind suboptimal, das kann man sich mit eine paar Makros aber stark vereinfachen.
Hallo, also das sehe ich ja ganz anders. Ich komme aus der Assembler Welt. Wer den PIC kennt, der weiß was ich meine. C ist für mich die ideale Programmiersprache für MCUs. Dirk
K&R, The C Programming Language, 1978, Seite 136, Bit Fields. Geht simpel und bequem.
Gast
#3196824
Dirk F. schrieb: > C ist für mich die ideale Programmiersprache für MCUs. Und genau weil genügend Leute aus der Anfangszeit der PC- und µC-Welt dies von sich behaupten, ist dieses Gefrickel aus den 80er Jahren des vorigen Jahrhunderts immer noch Standard in der µC-Welt.
>>>K&R, The C Programming Language, 1978, Seite 136, Bit Fields.
Kenne das Buch leider nicht .
Das heißt, laut C Definition geht es, nur es wird in den Compilern nicht
verwendet ?
LG Dirk
Ich kenne keinen Compiler, der es nicht kann. Das zitierte Buch ist die "Bibel" vom Erfinder der Sprache C. Such mal nach "bit field" und nicht nach "bit array".
Georg G. schrieb: > K&R, The C Programming Language, 1978, Seite 136, Bit Fields. > > Geht simpel und bequem. Dann kannst du aber nicht mehr mit Arrays arbeiten. Die Struktur hat dann 70 Member, die jeweils ein Bit gross sind und auf die alle manuell zugegriffen werden muss. Nicht gerade praktikabel. Oder meinst du was anderes? Mach mal ein Beispiel.
frickelsprachenhasser schrieb: > Verwende Assembler, dann musst Du Dich nicht mehr mit > den Unzulänglichkeiten und Fehlern der sog. "Compiler" herumplagen. Ach, unser alter Egbert mal wieder :) Und welcher Assemblersprache unterstützt Bit-Arrays, wenn ich fragen darf? Bit-Arrays bzw. gepackte Bool-Arrays gibt es bspw. in C++ (vector<bool>) und in Pascal. Aber in Assembler habe ich noch nicht einmal gewöhnliche Arrays gesehen, geschweige denn Bit-Arrays. Georg G. schrieb: > K&R, The C Programming Language, 1978, Seite 136, Bit Fields. Bitfelder sind leider wieder etwas anderes: Zum einen ist deren Größe begrenzt, zum anderen sind es keine Arrays, da man darauf nicht per Index zugreifen kann.
Bitfelder und Bitarrays sind zwei recht verschiedene Paar Stiefel. C hat in seinem Sprachsansatz praktisch nur Datentypen vorgesehen, die sich ziemlich direkt auf die Maschinen der Entstehungszeit abbilden liessen. Bitadressierung war nicht darunter. In dieser Tradition ging es auch später weiter. Und da kann nun drüber meckern oder glücklich sein, und trollen bis der Arzt kommt, aber ändern wird sich das wohl nicht mehr. Wen das stört, der kann jederzeit die Sprache wechseln. Bereits bei C++ hat er die Freiheit, sich das synaktisch wie gewünscht zu implementieren.
Yalu X. schrieb: > Aber in Assembler habe ich noch nicht einmal gewöhnliche > Arrays gesehen, geschweige denn Bit-Arrays. Bei den PIC18 gibt es Tabellen, auf die fast wie ein Array zugegriffen werden kann (Keine Ahnung wie das genau funktioniert, habs noch nie selbst gemacht). Die PIC18 wurden aber auch speziell für C entwickelt, deshalb ist sowas wohl implementiert worden.
PS: Wer unbedingt C mit syntaktisch auch als Arrays dargestellten Bitarrays braucht, der kann sich mal bei den µCs auf Basis der Cortex-M3/M4 Cores umsehen, Zu deren eher selten genutzen Features gehört nämlich eine Einzelbitadressierung des RAMs. Siehe [[ARM Bitbanding]].
Yalu X. schrieb: > Und welcher Assemblersprache unterstützt Bit-Arrays, wenn ich fragen > darf? Alle x86 beispielsweise. Ein paar Controller sind aber wohl auch mit von der Partie.
Hallo, tja, die Schaltung ist ja schon fertig mit dem PIC18. Da kann ich jetzt nicht kurzfristig auf eine neu CPU Typ umsteigen. Trotzdem Danke für den Hinweis. LG Dirk
Bitarrays kann man in Embedded C durch einen Named Address Space darstellen. Wer Lust hat, kann eine entsprechende Unterstützung zB in GCC reinklöppeln. :-) Damit kann man dann auch die Adresse eines Bits nehmen und hat "richtige" Arrays, mit denen auch memcpy etc. funktioniert.
Gast
#3196864
Hi Dirk, Bitfields sehen so aus:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
Allerdings kann man sie nicht aĺs Array verwenden (im Beispiel oben: bit kann kein Array sein), da Bitfields halt nicht direkt adressierbar sind. Außerdem schaden sie der Performance, da man sich erst das richtige Bit rausfriemeln muß. Deshalb werden Daten auch oftmals nicht so dicht wie möglich gepackt sondern an Adressen gelegt, auf die möglichst effizient zugegriffen werden kann (z.B. ganzzahlig durch 4, 8, .... teilbar); das macht dann structs auch größer, als sie sein sollten (und dieses Verhalten verhindert man durch die explizite Kompilerdirektive "packed"). Letztere ist allerdings nicht in C spezifiziert und variiert daher von Kompiler zu Kompiler. Viele Grüße flipsi
Gast
#3196887
Achso, mit Macros kann man sich übrigens ev. auch die Bit-Array-Funktion bauen, aber das sieht wahrlich syntaktisch nicht schön aus (bezogen auf meinen vorherigen Code) (folgende Version eignet sich nicht für Schleifen):
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
Falls notwendig, kann man aber auch ein Macro formulieren, das für Schleifen geeignet ist (oder einfacher ein SetBit Makro und ein GetBit Makro). Viele Grüße & viel Erfolg flipsi
A. K. schrieb: >> Und welcher Assemblersprache unterstützt Bit-Arrays, wenn ich fragen >> darf? > > Alle x86 beispielsweise. Sicher? Mit welchen Befehlen bzw. Adressierungsarten geht das?
Yalu X. schrieb: > Sicher? Mit welchen Befehlen bzw. Adressierungsarten geht das? BT/BTC/BTR/BTS mem, reg Die Mikrocode-Rechnerei ist aber nicht gratis, diese Befehle sind bei feststehendem Wort, also Bits 0..31/63, möglicherweise langsamer als die Ersatzsequenz. Korrektur: Gibts erst ab 386.
Und wie erhält man die Adresse eines Bits und greift indirekt darauf zu?
mem = normale Speicheradresse reg = Bitnummer, 0..2^32/64-1 Was fehlt ist die Möglichkeit, einen variablen Wert zu speichern. Man kann nur testen, setzen, löschen, komplementieren. Bei 68020 ging das über die Bitfeldbefehle. Das stammt aus einer Zeit, als die Allmacht des Microcodes noch nicht durch den RISC Ansatz in Frage gestellt wurde.
Gast
#3196923
be stucki schrieb: > Bei den PIC18 gibt es Tabellen, auf die fast wie ein Array zugegriffen > werden kann (Keine Ahnung wie das genau funktioniert, habs noch nie > selbst gemacht). Du meinst nicht die Konstruktion mit Computed-Goto und dem Retlw-Befehl, wie sie in der AN556 [1] beschrieben ist? Die bezieht sich auf Bytes. [1] http://ww1.microchip.com/downloads/en/appnotes/00556e.pdf
A. K. schrieb: > BT/BTC/BTR/BTS mem, reg Ich dachte bisher immer, diese Instruktionen würden nur mit Bitnummern bis 31 (bzw. 63) funktionieren. Hab's aber gerade ausprobiert: Man kann damit tatsächlich auch auf Bit-Seqeuenzen zugreifen, die aus mehreren Worten zusammengesetzt sind. A. K. schrieb: > Was fehlt ist die Möglichkeit, einen variablen Wert zu speichern. Man > kann nur testen, setzen, löschen, komplementieren. Ja, das ist allerding ein Wermutstropfen bei der Sache. So etwas wie
1 | |
ist damit leider nicht direkt in einem Assembler-Befehl umsetzbar. > Bei 68020 ging das über die Bitfeldbefehle. Ob der "frickelsprachenhasser" 68020-Assembler programmiert? Dann würde ich mich von ihm geschlagen geben :) Edit: Nein, doch nicht, denn es geht hier ja explizit um AVRs: Dirk F. schrieb: > Wie sieht es in der AVR Welt aus ? Auf einem AVR dürfte die Implementierung eine Bit-Arrays in Assembler noch ein ganzes Stück mehr Schreibarbeit sein als in C.
Yalu X. schrieb: > Auf einem AVR dürfte die Implementierung eine Bit-Arrays in Assembler > noch ein ganzes Stück mehr Schreibarbeit sein als in C. Nicht wirklich. Das implementiert man als Makros. Anders als in C sieht das dann richtig "echt" aus. Als obs Befehle wären.
Gast
#3196988
flipsi schrieb: > Bitfields sehen so aus: So machte ich es bei den ARM7, und teilte einen Long-Wert in 32 bits. Man muß sich aber den compilierten Code anschauen, der arbeitet nur in ganzen Befehlen für ein Register. Was man da mit der Bitaufteilung zu sparen glaubt, erzeugt in Wirklichkeit eine Menge Code. Bei heutigen µC spielt es oft keine Rolle mehr, wenn man mal ein Byte für nur ein bit mißbraucht, und das dann auf Zero oder Not Zero testet. Die neueren µC haben reichlich RAM. Dann klappt es auch mit der Indizierung.
Viele Prozessoren kennen keine Bit-Arrays, weil sie den Speicher nicht bitweise adressieren können. Die Sprache C wurde an die Möglichkeiten der damaligen Prozessoren angelehnt, deswegen kennt sie nur Bitfelder, aber keine Bit-Arrays. Viele Mikrocontroller können einen Teil des internen RAM's mit speziellen Befehlen bitweise ansprechen. Soweit ich weiß nutzt der C Compiler dann auch die bit adressierenden Befehle (z.B. sbi und cbi bei 8051). Mit Hilfe von Prozeduren, Funktionen oder Makros kann man sich sowas ähnliches wie Bit arrays selbst basteln. Aber der Zugriff auf die einzelnen Bits ist in den allermeisten Fällen langsamer, als auf Bytes. Man spart nur Speicherplatz. Deswegen benutze ich in der Regel Bytes, um boolesche Werte zu speichern.
@ Wilhelm Ferkes (ferkes-willem) >So machte ich es bei den ARM7, und teilte einen Long-Wert in 32 bits. >Man muß sich aber den compilierten Code anschauen, der arbeitet nur in >ganzen Befehlen für ein Register. Was man da mit der Bitaufteilung zu >sparen glaubt, erzeugt in Wirklichkeit eine Menge Code. Das macht er EINMAL für die Funktion. Die kann man dann beliebig oft aufrufen. >Bei heutigen µC spielt es oft keine Rolle mehr, wenn man mal ein Byte >für nur ein bit mißbraucht, und das dann auf Zero oder Not Zero testet. EINS sicher nicht. 70 schon eher, auch wenn heute selbst kleine uCs 1kB++ RAM haben.
Ein Kompromiss wäre, wenn sich das programmtechnisch von 4 Arrays à 70 Bits auf ein 70 Byte langes Array à 4 Bits umbauen liesse. Wenn man die 4er Komponente primär als Maske statt Nummer rumschleppt ist das recht effizient.
Die 4x70 kann man aber auch als 70 Nibble interpretieren. Nichts genaues weiß man nicht.
A. K. schrieb: > Yalu X. schrieb: >> Auf einem AVR dürfte die Implementierung eine Bit-Arrays in Assembler >> noch ein ganzes Stück mehr Schreibarbeit sein als in C. > > Nicht wirklich. Das implementiert man als Makros. Das meinte ich auch. Das Makro muss ja erst geschrieben werden und dürfte länger sein als eine entsprechende Funktion in C (s. obiges Beispiel von Falk). Allein schon deswegen, weil die AVRs keine Shift- Befehle mit variabler Shift-Weite haben. > Anders als in C sieht das dann richtig "echt" aus. Als obs Befehle > wären. Das stimmt schon, aber nur deswegen, weil es in Assembler im Gegensatz zu C für solche Operationen keinen syntaktischen Zucker gibt, den es nachzubilden gälte. Ein Assembler-Makroaufruf würde etwa so aussehen:
1 | |
Ein C-Funktionsaufruf so:
1 | |
Beides ist gleich (un)übersichtlich. Die C-Version sieht nur deswegen ungewohnt aus, weil dort die Erwartungshaltung an die Syntax höher ist. In C++ ist aber auch das kein Problem, weil man dort den []-Operator überladen kann.
Gast
#3197033
Stefan Frings schrieb: > Soweit ich weiß nutzt der C > Compiler dann auch die bit adressierenden Befehle (z.B. sbi und cbi bei > 8051). sbi und cbi gehört sicher eher zum AVR, nicht zum 8051. Dort heißt das setb bit oder clr bit oder cpl bit, oder bedingte Sprungbefehle jb, jnb, jbc. Den Befehl jbc verwendete ich über die Jahre nur ein einziges mal in einem Programm. Aber beim 8051 fand ich in C auch noch keine Möglichkeit, die Bitfelder in Einzelbits und Array anzulegen. Er hat keinen Pointer auf bits, nur auf Bytes. Die Einzelbits sind da auch für Steuerungen als Flaggen (Flags) gedacht, der 8051 war was für kleine und mittlere Steuerungsaufgaben. Flag, ich bin da, oder ich bin nicht da. Und nein, der 8051 war noch nicht speziell auf die Hochsprache C optimiert. Als er der Öffentlichkeit vor gestellt wurde, 1980, da kam ungefähr auch erst C raus. Im Assembler hatte man aber Bitbefehle, die effizienter sind, als Byteverarbeitung. Aktuell arbeite ich mit dem kleinen PIC12F675, und bin auch über dessen Bitverarbeitung erstaunt. In jedem File SFR und RAM läßt sich auch jedes bit einzeln verarbeiten. Vor Zeiten machte ich da Byte-Masken, um ein bit zu testen, und die warf ich heute mal aus einer alten Software raus.
Wilhelm Ferkes schrieb: > Und nein, der 8051 war noch nicht speziell auf die Hochsprache C > optimiert. [...] Aktuell arbeite ich mit dem kleinen PIC12F675, Die PICs mit 12/14-Bit Befehlen sind für eine C Implementierung freilich noch ärger als 8051. Allerdings ist die 12er Architektur in ihrem Ursprung noch einige Jahre älter als 8051.
Yalu X. schrieb: > Allein schon deswegen, weil die AVRs keine Shift- > Befehle mit variabler Shift-Weite haben. Zumindest für Linksshift kann man die in AVRs meist vorhandene Multipliziereinheit verwenden. Nur dass der Arrayzugriff nicht immer schneller ist, als die Schleife um das "Schieb um 1"...
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
mfg mf PS: Dass C eine Fummelsprache ist, kann ich voll bestätigen, solange es um Bitgefummel geht.
frickelsprachenhasser schrieb: > Warum? Weil C keine ernstzunehmende Programmiersprache ist und auch > nicht als solche konzipiert wurde. Nichts weiter als ein Treppenwitz der > EDV-Geschichte. Verwende Assembler, dann musst Du Dich nicht mehr mit > den Unzulänglichkeiten und Fehlern der sog. "Compiler" herumplagen. Pah ! Das ganze Halbleitergedöns ist ein Treppenwitz ! Richtige Männer verwenden Röhren, Kondensatoren, Spulen und Widerstände für einen richtigen Analogrechner, dann musst Du Dich nicht mehr mit den Unzulänglichkeiten und Fehlern der sog. Digitalsystem herumplagen.
Gast
#3197113
Dirk F. schrieb: > ja ich denke die Frage ist eindeutig ? > Ich muss in meinem MCU ca. 4x70 Bit abspeichern. Eindeutig? Nun ja, die Fragestellung als solche zeigt wirklich eindeutig, daß du dir einfach zu wenig Gedanken zuvor gemacht hast. Kein Mensch MUSS 4x70 Bit abspeichern - sondern er sollte sich vorher Gedanken über eine bessere Organisation seiner eigentlichen Aufgabenstellung machen. Aber wenn du partout deinen Algorithmus mit 280 einzelnen Bits machen willst, dann hat dir Falk Brunner bereits die fertige Lösung geliefert. Wozu also jetzt noch die ganze Aufregung? Als selbstzweck, also um sich aufzuregen?: Joachim минифлоть schrieb: > PS: Dass C eine Fummelsprache ist, kann ich voll bestätigen, solange es > um Bitgefummel geht. Nanana. C ist wahrlich keine schöne Sprache, ist auch keine gute Sprache, ist auch keine mächtige Sprache und ist auch keine unproblematische und leicht verständliche Sprache. Aber C ist schon ausreichend benutzbar und bei den allermeisten uC neben Assembler die einzige verfügbare Sprache. Direkte Bitmanipulationen sind gerade bei den jetzt fast allgegenwärtigen ARM's ohnehin maschinenmäßig nicht drin, sondern immer wieder mit der üblichen "Lade-Verknüpfe-Speichere" Sequenz verbunden - eben wegen der grundsätzlichen Struktur dieser CPU's. Da helfen auch die neuerdings eingeführten Bit-Adressierungsarten nix. Logische Konsequenz: Programme anders strukturieren, dann kann man auch gut damit leben. Also nicht meckern und C benutzen, solange sich keiner aufrafft und nen Compiler für was viel viel viel Besseres schreibt. W.S.
Dirk F. schrieb: > Warum gibt es kein Bit-Array in C? Weid nie ein Bedarf dafür bestand und niemand Bit-Arrays wirklich brauchte. Wenn nämlich ein Bedarf dazu existiert hätte, dann wäre eine entsprechende Spracherweiterung längst in ISO-C eingeflössen oder zumindest in GNU-C implementiert. Wenn also in über 20 Jahren C-Geschichte niemand es für nötog hielt, BIT-Arrays auch nur zu spezifizieren dann kann es wirklich kein Bedarf dafür geben bzw. gegeben haben!
C ist Maschinen nah und da (fast?) keine CPU indizierte Bitbefehle hat, gibt es für nichts auch keine Entsprechung in C. Man kann sich natürlich leicht eine Bitlib machen und dann aufrufen. Der Aufruf zeigt einem dann auch, daß sowas deutlich teurer ist, als Bytezugriffe. Hier mal meine Bitlib aus 8051-Zeiten:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
#define TestBit(ByteArray, BitIdx) (ByteArray[BitIdx>>3] & (1<<(BitIdx & 7))) SetBit und ClrBit nach gleichem Schema Das kann man natürlich auch als Funktionen (ggf. mit inline) implementieren.
Johann L. schrieb: >> Warum gibt es kein Bit-Array in C? > > Weid nie ein Bedarf dafür bestand und niemand Bit-Arrays wirklich > brauchte. Doch, ich schon. Dirk F. offensichtlich auch. Und sicher noch eine ganze Reihe mehr. Der Grund, warum die Bit-Arrays nicht in den Standard einflossen, liegt vermutlich eher darin, dass sie nur sehr schlecht in das Array-Konzept von C passen. Eine Umsetzung hätte noch aufgesetzter ausgesehen als die bereits existierenden Bitfelder, die selbst Dennis Ritchie als "a botch and a blemish" bezeichnet haben soll. > Wenn also in über 20 Jahren C-Geschichte niemand es für nötog hielt, > BIT-Arrays auch nur zu spezifizieren dann kann es wirklich kein Bedarf > dafür geben bzw. gegeben haben! Ich hätte sogar einen Ansatz für eine Spezifikation, könnte den aber nicht mit voller Überzeugung dem C-Konsortium vortragen, weswegen ich das lieber bleiben lasse. Es würde mir wesentlich leichter fallen, Gründe für die Abschaffung der Bitfelder zu nennen. Aber auch diese würden sicher nicht auf fruchtbaren Boden fallen, weil man sie wegen der Abwärtskompatibilität beibehalten muss. Es gibt ja immerhin die Möglichkeit, Bit-Arrays mit vorhandenen Sprach- mitteln zu implementieren. Das sieht zwar im Vergleich zu einer nativen Implementation syntaktisch nicht so elegant aus, ist aber immer noch besser, als neue, krüppelige Sprachkonstrukte einzuführen.
Gast
#3198655
Yalu X. schrieb: > Ich hätte sogar einen Ansatz für eine Spezifikation,.. Laß es, es wäre sinnlos. Denk doch mal an die Realisierung auf Maschinenebene bzw. Assemblerebene. Bei solchen uC wie den kleinen PIC's haben wir durchaus mächtige Bitbefehle, aber das sind ja nun uC, die man wirklich eher in Assembler als in C oder Pascal programmieren sollte. Bei allen größeren uC werden wir in wenigen Jahren fast nur noch Risc-Architekturen haben, die immer nach dem Schema Laden-Ändern-Speichern funktionieren und da wird es keine wirklich sinnvollen Bit-Befehle geben. Das Einzige, was dort Sinn hat, sind Ausdrücke der Art if (A & (1<<nn)), aber das sind keine eigentlichen Bitbefehle. Kurzum, auch jemand, der immer nur in C programmiert, sollte sich Gedanken machen um einen geeigneten Entwurf für die Realisierung einer Funktionalität und nicht auf sowas wie Bit-Arrays bestehen wollen. W.S.
Gast
#3198755
duck&wech schrieb: > Dirk F. schrieb: >> C ist für mich die ideale Programmiersprache für MCUs. > > Und genau weil genügend Leute aus der Anfangszeit der PC- und µC-Welt > dies von sich behaupten, ist dieses Gefrickel aus den 80er Jahren des > vorigen Jahrhunderts immer noch Standard in der µC-Welt. Und alle Maso- Programmierer finden die hirnverknotende C Freak-Syntax nur endgeil, besonders wenn sie Pointer Bugs zwischen dem hochoptimierten tildeshiftshiftoderundplusgleichdodummyminusminuspointerauf bis zum Erbrechen suchen..Lies mal die Scheisse ein Jahr später und verstehe was. Da lob ich mir einen Compiler, der mir nicht sooooo viele Freiheiten läßt, wenns auch vielleicht einen Zyklus mehr braucht. Na und - bei den Prozessorleistungen heut ?
grrrrrr schrieb: > Und alle Maso- Programmierer finden die hirnverknotende C Freak-Syntax > nur endgeil, besonders wenn sie Pointer Bugs zwischen dem > hochoptimierten > tildeshiftshiftoderundplusgleichdodummyminusminuspointerauf bis zum > Erbrechen suchen. Hmm. Dann muss ich was falsch machen. Pointer Bugs kommen bei mir selten vor und wenn, dann such ich die nicht bis zum Erbrechen, sondern hab die eigentlich ziemlich schnell dingfest gemacht. > Lies mal die Scheisse ein Jahr später und verstehe > was. Kein Problem damit. Ist dir schon mal in den Sinn gekommen, dass hier genug Leute rumhängen, die Code, den sie noch nie zuvor gesehen haben in 10 Minuten oder weniger analysieren können? Probier das mal mit einem vollständigen Assembler Programm und frag dich, wo der Stack aus dem Tritt gekommen ist bzw. wo welcher Funktionsaufruf welches SREG-Flag verstellt hat. > Da lob ich mir einen Compiler, der mir nicht sooooo viele > Freiheiten läßt, wenns auch vielleicht einen Zyklus mehr braucht. Na und > - bei den Prozessorleistungen heut ? "Man kann in jeder Sprache Fortran Programme schreiben." Ja - kann man. Man muss aber nicht. Edit: Nicht, das wir uns falsch verstehen. Ich halte C keineswegs für das Beste seit geschnittenem Brot. Es ist nur ein Werkzeug. Und wie mit allen Werkzeugen muss man eben lernen, damit umzugehen.
Schön, das die BASCOM-Fraktion auch hier vertreten ist :-) Ja, C ist schon schlimm für Leute die es nicht verstehen. Einzel-Bit-Zugriffe sind ineffizient, deshalb braucht man auch kein Bit-Array. Brauchen tut man das wirklich nur bei Bitstreams oder 1-Bit LCDs. Ich finde wie Flipsi oder Michael S1 es gezeigt haben (Bit-Field oder Array mit Makro) ist es gut nachvollziehbar. Man kann die Bit-Field Version ja noch mit Michaels Indizierung erweitern:
1 | |
Geht natürlich nicht für Schleifen, aber wenn man schon eine Schleife über einzelne Bits machen muss, gibt es bestimmt auch eine effizientere Verarbeitung (auf Byte-Basis). Dafür müsste man die Schleife halt "entrollen".
Hallo, also mit so einer Resonanz hätte ich nicht gerechnet. Danke für die Hinweise und Code Beispiele. Als Zusatzinformation folgende Schaltungebeschreibung: AUf dem Main board sitzt der PIC18, der über SPI maximal 5 Steckkarten mit Relais ansteuert. Jede Steckkarte hat 74 Relays. Jetzt muss sich die MCU merken, welche Relais angesteuert wurden, um weitere Verknüpfungen zu machen. Da wäre hat ein 2-dimensionales Bit Array genial gewesen, eine Dimension für die Relay Nummer 1-74, die andere für die Kartennummer 1-5. Jetzt werde ich wohl ein 1 dimensionales char Array mit 74 Stellen erstellen, in jedem Byte 5 Bit nutzen. Gruß Dirk
Dirk F. schrieb: > Jetzt werde ich wohl ein 1 dimensionales char Array mit 74 Stellen > erstellen, in jedem Byte 5 Bit nutzen. Ist zwar möglich, aber eigentlich extrem kompliziert. Wenn du für jede Karte 74/8 gleich 10 Bytes benutzt um darin in jedem Bit ein Relais abzulegen, dann rechnet sich das ganze für den µC auch gleich viel einfacher. Und du verschwendest weniger Bits. Mann! Das ist doch einfach nur Division durch 8 mit Restbildung! Das hast du in der Grundschule gelernt! 8-jährige können das. Wir leben schon in einer seltsamen Zeit, in der die Menschen Angst davor haben einfachste Rechnungen durchzuführen. Und dann wundern wir uns, wenn immer mehr Jugendliche in die Handyfalle tappen einfach weil sie die realen Kosten ihres Handys in einem Jahr nicht ausrechnen können.
Gast
#3199170
Ein Leben ohne Bit-Array ist möglich, aber sinnlos. ;-) MfG Paul
Karl Heinz Buchegger schrieb: >> Jetzt werde ich wohl ein 1 dimensionales char Array mit 74 Stellen >> erstellen, in jedem Byte 5 Bit nutzen. > > Ist zwar möglich, aber eigentlich extrem kompliziert. Ich finde es einfacher als deinen Vorschlag. ;-)
A. K. schrieb: > Karl Heinz Buchegger schrieb: >>> Jetzt werde ich wohl ein 1 dimensionales char Array mit 74 Stellen >>> erstellen, in jedem Byte 5 Bit nutzen. >> >> Ist zwar möglich, aber eigentlich extrem kompliziert. > > Ich finde es einfacher als deinen Vorschlag. ;-) Bei 3 verschenkten Bits pro Byte?
Gibts Geld zurück, wenn man RAM nicht verwendet? Sind 74 Bytes gegenüber 50 Bytes. Diesen Zirkus würde ich mir erst antun, wenns wirklich knapp wird.
A. K. schrieb: > Gibts Geld zurück, wenn man RAM nicht verwendet? Der Unterschied wird > erst relevant, wenn das RAM knapp wird. Nun. So gesehen könnte er dann ja auch einfach ein uint8_t[5][74] benutzen? Aber ok. Das mit dem kompliziert nehm ich zurück. Da hast du schon recht - das ist kein wirkliches Argument, selbst dann wenn das Übertragen der Relaisstände auf die einzelnen Karten dann zu einer Array-Zugriffsorgie ausartet. Mich haben eigentlich die verschenkten Bits geärgert und das weiter oben ja schon Code gepostet wurde, der genau dieses Problem nicht hat. Und bei Relais Bearbeitung spielt dann auch das Fehlen eines Barrel-Shifters nicht wirklich eine Rolle.
Dirk F. schrieb: > Jetzt werde ich wohl ein 1 dimensionales char Array mit 74 Stellen > erstellen, in jedem Byte 5 Bit nutzen. Warum willst Du unnötig Hardware verschwenden? Das SPI gibt immer ganze Bytes aus und die SRG (74HC595) sind auch 8 Bit breit. 74 / 8 sind 10 SRG. 74 / 5 sind aber schon 15 SRG.
Ich würde an dieser Stelle ohnehin überlegen, ob an Stelle von Schieberegistern vielleicht 74HC259 einfacher zu verwenden sind. Da lassen sich die Relais einzeln ansteuern.
Peter Dannegger schrieb: > 74 / 8 sind 10 SRG. > 74 / 5 sind aber schon 15 SRG. Er hat 5 Karten mit je 74 Relais. Ich nehme doch stark an, dass die Shifter auf der jeweiligen Karte sind, um nicht so viele Verbindungen zu benötigen. Die SPI-Bytes aus 8 aufeinanderfolgenden Array-Bytes einzusammeln ist wahrlich kein Hexenwerk. Und Relais sind auch keine Rennpferde.
@ A. K. (prx) >Gibts Geld zurück, wenn man RAM nicht verwendet? Der Unterschied wird >erst relevant, wenn das RAM knapp wird. Jain. Aber mal 5 Minuten vorausschauend zu denken ist wohl selten verkehrt. Zumal wir es hier nicht mit einem komplexen Problem zutun haben, es ist, wie so oft, ein Luxusproblem.
Gast
#3199405
Wie wäre es mit dieser AppNote: http://www.atmel.com/Images/doc1497.pdf
Nochmal ganz zurück zum eigentlichen Bit Problem... Ich denke das Problem wird einfach auf der falschen CPU gelöst. Schließlich kann ein SMT32F oder STM32M auch im RAM auch bitbanding access. Ein Bit aus dem RAM wird durch ein word in einem anderen Adressbereich repräsentiert. Schreibt man in der bitbanding area eine 0 in ein word, wird das correspondierende Bit auf 0 gesetzt, sonst auf 1. Vorteile: Zugriff per uint32_t array[] möglich ohne eine neue Type einzuführen. Zugriff ist atomic für setzen und löschen eines Bits. Zugriff erfordert keine bitshift Operationen, obwohl ein Cortex diese als load and shift in einem Schritt machen könnte. Zugriffe werden an einigen Stellen sehr viel schneller und Code wird kleiner: Statt if (a > 0) then bla[n] |= (1<<x); else bla[n] &= ~(1<<x); schreibt man einfach bla[n] = a; Gruß Ulrich
Yalu X. schrieb: > Johann L. schrieb: >>> Warum gibt es kein Bit-Array in C? >> >> Weil nie ein Bedarf dafür bestand und niemand Bit-Arrays wirklich >> brauchte. > > Doch, ich schon. Dirk F. offensichtlich auch. Und sicher noch eine ganze > Reihe mehr. > > Der Grund, warum die Bit-Arrays nicht in den Standard einflossen, liegt > vermutlich eher darin, dass sie nur sehr schlecht in das Array-Konzept > von C passen. Eine Umsetzung hätte noch aufgesetzter ausgesehen als die > bereits existierenden Bitfelder, die selbst Dennis Ritchie als "a botch > and a blemish" bezeichnet haben soll. > >> Wenn also in über 20 Jahren C-Geschichte niemand es für nötig hielt, >> BIT-Arrays auch nur zu spezifizieren, dann kann es wirklich kein >> Bedarf dafür geben bzw. gegeben haben! > > Ich hätte sogar einen Ansatz für eine Spezifikation, könnte den aber > nicht mit voller Überzeugung dem C-Konsortium vortragen, ... Falls du deinen Spieltrieb nicht bremsen kannst: Wie wär's mit einem Proof-of-Concept? 1) Nimm dir die GCC-Quellen 2) Definiere einen neuen Address Space __bitmem. Der neue AS ist disjunkt zu allen anderen AS (Hook: TARGET_ADDR_SPACE_SUBSET_P). Es ist also nicht möglich, bei Zeigern den AS-Qualifier "hinzu" oder "weg" zu casten. 3) Beim Lesen wird 1 Bit gelesen und zum Zieltyp expandiert:
1 | |
2 | |
3 | |
4 | |
4) Beim Schreiben wird nut Bit 0 geschrieben oder (wahlweise, etwa über einen neuen Schalter) wird eine 0 genau dann geschrieben, wenn die zu schreibende Variable == 0 ist. 5) "Abgeholt" werden die neuen Lade- und Speicher-Insns für den neuen AS in den mov<mode> insns, also movqi, movhi, etc. Hier wied auch die Adressberechnung ausgegeben und es werden Spezialfälle behandelt, etwa bei direkter Adressierung. 6) GCC neu compilieren und Testprogramm damit übersetzen. 7) Fertig :-)
Gast
#3199751
Indizierte bits gibts also nicht. Beim 8051 kann man sagen, setb 125, das spricht dann Byte 0x2F und das bit 5 dort an, oder jb 125, Sprungadresse, bedingte Sprungbefehle nach Bitzustand, sonst geht da nichts. Es war aber damals ganz was modernes, Einzelbits als Flaggen Merker für Steuerungen. Man kann die 125 nie als Indiz gebrauchen. Alles andere macht Bytebefehle im Code. Bei heute gigantischem RAM würde ich auch ein Byte nur für eine Null oder Eins verbrauchen. Wayne interessierts? 1976, als RAM und ROM wirklich sehr knapp war, und man froh war, nur 256 Bytes für einen Speicher her zu stellen, da machte man sich noch einen Kopf um effiziente Befehlssätze, wie beim 8048, die nur ein Byte haben. Sowas Bitbefehle in einen C-Sprachschatz zu übernehmen, halte ich für etwas schräg. Viele Prozessoren außer den PIC und 8051 kennen keine Einzelbitbefehle, und haben keinen Einzelbitprozessor, wie es der 8051 hat. Es wäre schön gewesen, wenn ein 8051 einen Pointer auf Bits gehabt hätte, aber der Befehlssatz ist mit 256 Befehlen in 8 bit auch schon vollständig auscodiert, da gibt es keinen Platz mehr.
Wilhelm Ferkes schrieb: > Sowas Bitbefehle in einen C-Sprachschatz zu übernehmen, halte ich für > etwas schräg. Es passt nicht wirklich gut in eine Sprache, die sich relativ dicht an den Fähigkeiten üblicher Maschinen orientiert. Anders bei Programmiersprachen mit wesentlich höherem Abstraktionsgrad. Wie oben schon erwähnt wurde kann man auch schon die Bitfelder eher als Irrtum denn als Errungenschaft sehen. Gäbe es nur C, wäre die Diskussion um die Entwicklung der Sprache offen. Aber dank u.A. C++ erscheint mir das sinnarm. Viele lehnen C++ bei µCs ob eines angeblich exzessiven Ressourcenverbrauchs ab. Was Unfug ist, wenn man weiss was man tut. Exakt solche Sachen lassen sich da aber sehr gut und durchaus effizient abbilden.
Wilhelm Ferkes schrieb: > Indizierte bits gibts also nicht. Doch, wieso denn nicht?
Johann L. schrieb: > Doch, wieso denn nicht? Im 8051 Befehlssatz gibt es sie nicht. Nur direkt adressierte Bits.
A. K. schrieb: > Johann L. schrieb: >> Doch, wieso denn nicht? > > Im 8051 Befehlssatz gibt es sie nicht. Nur direkt adressierte Bits. Ja, und? Gibt man eben eine Befehlsfolge aus, das wied das Ding wohl können. Schieben, Maskieren, ...
Klar, aber sein Kontext war 8051, also bezog er das evtl. darauf.
Und der hat keine Befehle zum Schieben oder zur Maskierung von Bits? Wow...
Herrje, was soll diese unsinnige Diskussion? Wir reden kilometerweit aneinander vorbei.
na denn...
Gast
#3204649
>Aber der Zugriff auf die >einzelnen Bits ist in den allermeisten Fällen langsamer, als auf Bytes. Die CPU liesst (auch wenn sie explizite Bitbefehle hat) zumindest immer 1 Byte ein, schreibt ggfs zurück (RMW), also ist es von daher egal. Evtl zus Operationen (ob OPCode-intern oder mit sep ASM.-Befehl umgesetzt) brauchen nat. nochmal Zeit, ggfs weiteren Platz im ROM. >Und nein, der 8051 war noch nicht speziell auf die Hochsprache C >optimiert. Als er der Öffentlichkeit vor gestellt wurde, 1980, da kam >ungefähr auch erst C raus. 1. gibt es bei keiner CPU wirkliche Features speziell für C (ausser nen Stack, aber das hat wohl jeder (ausser die kleinsten PICs und die ältesten Intels) 2. hat man das "für Hochsprachen optimiert" bereits 1979 bei der Vorstellung des 68k behauptet. 3. ist reiner Marketing-Quatsch. Denn sinnvoll in ASM prgorammiert geht automatisch auch sinnvoll in ner Hochsprache. Befehle um mit zusammenhängeden Bits umzugehen (bsp mit 1..2 Index-Regs), sollten (neuere) CPUs schon haben.
Gast
#3204665
>werden wir in wenigen Jahren fast nur noch Risc-Architekturen haben, >die immer nach dem Schema Laden-Ändern-Speichern funktionieren und da >wird es keine wirklich sinnvollen Bit-Befehle geben. Vonwegen. Selbst bei "Schema Laden-Ändern-Speichern" CPUs macht das Sinn, weil 1. atomar möglich und 2. nur 1 statt 3 ASM-Befehlen.
Gast
#3204668
(edit) und 3. das dann auch noch viel schneller gehen kann
MCUA schrieb: >>werden wir in wenigen Jahren fast nur noch Risc-Architekturen haben, >>die immer nach dem Schema Laden-Ändern-Speichern funktionieren und da >>wird es keine wirklich sinnvollen Bit-Befehle geben. > Vonwegen. Selbst bei "Schema Laden-Ändern-Speichern" CPUs macht das > Sinn, weil 1. atomar möglich und 2. nur 1 statt 3 ASM-Befehlen. Daß die Operation atomar durchgeführt werden kann ist auf Mulicore-MCUs sogar unabdingbar, denn ein globales IRQ-Disable wirkt nicht auf die anderen Cores.
MCUA schrieb: > Die CPU liesst (auch wenn sie explizite Bitbefehle hat) zumindest immer > 1 Byte ein, schreibt ggfs zurück (RMW), also ist es von daher egal. Fast immer. Die CPUs der TI9900 Familie hatten zusätzlich zum Speicherbus noch einen weiteren Adressraum mit 1 Bit Datenbreite. Darin war das naturgemäss nicht nötig.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.