Selbst das finde ich in C angenehmer: while (PORTB & (1 weil man ohnehin nur Bits setzt, löscht und durch die Gegend schiebt.
...
Wieso? "printf" geht auch mit kleinen µC an LCD. Dateisysteme sind auch nur Bibliotheksfunktionen.
Auch nur bedingt. Sachen wie "Timer initialisieren" gehören sowieso in Funktionen, die man dann bei Bedarf tauscht und die einfachen Bitpfriemeleien lassen sich oft sehr komfortabel in Makros schreiben.
Seit ich vom PIC16F84 weg bin, habe ich Assembler nicht mehr geschrieben.
Gute Idee. Sowas wie einen Makro-assembler, der noch ein paar simple Kontrollstrukturen für Schleifen und Funktionen hat und Variablen, die von der Registerbreite unabhängig sind. Nehmen wir noch Zeiger und Strukturen dazu, ist C fertig ;-)
Kann ich so nicht nachvollziehen. Einen Cortex-M3 möchte *ich* nicht in Assembler bearbeiten. Zumal ein guter Kompiler deutlich effektiver optimieren kann, als ein ASM-Hacker...
Es gab ab 1974 an der ETH Lausanne von Prof. Nicoud
formatting link
den Versuch CALM "Common Assembly Language for Microprozessors" zu etablieren.
Wurde wohl ursprünglich für die experimentellen schweizer SMAKY-Tischcomputer verwendet:
formatting link
Die wollten natürlich von 8080 auf Z80/6809 und später
68000 den verfügbaren leistungsstärkeren CPUs folgen ohne daß man jeweils das OS neu schreiben mußte. Vgl. Kildall und PL/M für CP/M.
Zitat: "I rather dislike C and this sort of language which hide away the machine from you". Basierte ursprünglich auf der Einsicht, daß die damaligen
8 Bit CPUs recht ähnlich waren. Aber zu hohe Hardwarenähe war beim Übergang auf 16 Bit CPUs dann wohl tödlich weil da die Einheitlichkeit verlorenging. Wurde in den 80er Jahren bekannter, brachte es bis zur DIN-Norm.
Literatur dazu stapelt sich hier schon: Nicoud, Wagner "Major Microprocessors A Unified Approach using CALM" Noth Holland 1987 Schnell, Hoyer "Mikrocomputerfibel" Vieweg 3. Auflage 1987 Zeltwanger "Genormte Assemplersprache für uPs" Elektronik 8/1988
Werde bei Gelegenheit mal einen historischen Artikel in der omiösen Zeitschrift darüber bringen.
Ja man kann auch alles falsch machen, was aber keine Begründung für die Argumentation ist. Es ist auch nicht unüblich, wenn mehrere Leute an dem gleichen Modul arbeiten, sowohl gleichzeitig als auch zeitversetzt. Bereits wenn einer krank wird, muss ein anderer, vielleicht aus einer anderen Abteilung, oder auch ein Firmenfremder, sich kurzfristig darin einarbeiten, oder alles bleibt für ein paar Wochen liegen. Wenn der dann den Aufwand für seine Einarbeitung abschätzt, bekommt der Projektleiter einen dicken Hals. Modularisierung lößt nicht alles, eher Teamfähigkeit und verantwortungsbewußtes Denken, oder über den Tellerand hinausblicken, vielleicht auch mal selbst ein Projekt leiten zu müssen.
Hoher Kostendruck ist in DE immer, und Zeitdruck sowieso. Letzterer bestimmt, wie viele Leute mitarbeiten müssen, um das Projekt in absehbarer Zeit zum Ende zu bringen. Projekte mit z.B. grafischem Display gibt es genügend (nein da liegen keine Bitmaps im Speicher) und der Einsatz eines fetten und trägen Linux schraubt die Prozessorauswahl gleich um mehrere Stufen nach oben incl. Dominoeffekt (BGA, Multilayer, 1,8V etc.). Dazwischen gibt es also eine Menge Projekte, die vermutlich ein paar hundert kBytes brauchen (dieses Beispiel erhebt keinen Anspruch auf Vollständigkeit).
Wenn es wirklich so wäre, gäbe es in C-Programmen niemals Asm-Einschübe zu Optimierung. Es gibt sie aber, und zwar massenhaft, insbesondere auch im Bereich der µC. Damit fällt Unkenntnis des wahren Sachverhaltes als Entschuldigung aus.
Also: Die Aussage ist eine bewußte Lüge, verbreitet wider besseren Wissens.
deutlich einfacher lesbar. Außerdem weiß ich dann sofort zuverlässig, daß ich eine Latenz von 2..4 Takten und einen Jitter von 3 Takten vom Ereignis bis zum "machwas" habe.
Wie ein C-Compiler das übersetzt, muß ich hingegen raten oder im Compilat nachschauen und kann mich auf nichts verlassen, denn schon andere Optionen für denselben Compiler können ein abweichendes Zeitverhalten bewirken, was andere Compilerversionen oder andere Compiler machen, steht sogar völlig im Dunkeln.
Die meisten ASM-Einschübe rühren aber daher, daß der entsprechende Konstrukt oder Zugriff in C nicht realisierbar ist. Bestes Beispiel: nicht-memory-mapped-IO.
Umgekehrt ist es ein Fakt, daß ein guter C-Compiler wirklich besser optimieren kann, denn er kann die Eigenschaften ganzer Befehlssequenzen und ihre Abarbeitung in der CPU (interne Parallelisierung) besser berücksichtigen! Sicher kann ein guter Programmierer das für den einen oder andere Prozessor auch, aber so ein Compiler kann das eben für mehrere Prozessor-Varianten und ist ausdauernder.
He, hola, komm' mal 'runter.
Josef
--
These are my personal views and not those of Fujitsu Technology Solutions!
Josef Möllers (Pinguinpfleger bei FTS)
Wie die anderen Poster sehe ich das anders. Wir sind hier zwar ein kleines Team, aber ich lege schon Wert darauf, dass zumindest einer meiner Mitarbeiter meine Projekte bearbeiten kann.
Das hat jetzt auch nichts mit C oder Pascal zu tun.
Meine Kritik an bestimmten Programmierbeispielen bezieht sich auf sowas:
(stammt alles aus dem Powerswitch Beispiel bei OVDEV.AT)
procedure TForm1.Button4Click(Sender: TObject); var i,status:integer; begin if Assigned(udev) then begin status:=getstatus; label5.Caption:=inttostr(status); label5.Visible:=true; for i:=low(cb) to high(cb) do cb[i].Checked:=btbool(status,i); end; statusbar1.Panels[0].Text:=usb_strerror; end;
Hier insbesondere die Function btbool, die offenbar nur prüft, ob das Bit Nr. bit in data gesetzt ist. Die hier gezeigte Lösung ist einfach nur krank. Warum formuliert man das nicht einfach sauber in Pascal? Es gibt überhaupt keinen Grund, hier inline asm einzusetzen.
------------------------------------------------------------------------- Ich bin jetzt in GCC nicht so fit, dass ich das alles auf Anhieb verstehe, aber ich habe den Eindruck, dass hier auch einiges herumgezaubert wurde um Eindruck zu schinden.
Die Sache mit dem rq erschließt sich mir dabei nicht so ganz. Offenbar gibt es hier 8 Bytes, die vom Treiber zurückgegeben werden. Warum werden die nicht einfach ausgelesen und verarbeitet? Statt dessen wird mit einer Class rq herumgewurschtelt...
Und: Was in aller Welt soll die Scheiße mit dem EEProm hier?
Und der Schwachsinn mit den actionTimers?
In Main() steht dazu:
----------------------------------------- for(;;){ /* main event loop */ wdt_reset(); usbPoll();
Das sehe ich anders. Ich habe 20 Jahre lang 8031 und 15 Jahre lang PIC ausschließlich in asm programmiert und bin vor einigen Jahren auf AVR und Winavr umgestiegen.
Seitdem habe ich noch nicht die Notwendigkeit gesehen, asm in meine C-Programme einzubauen...
Früher, zu Basic Zeiten auf dem TRS-80 oder dem PC-XT mit 8088 und 4,77 MHz war das etwas anderes. Oder bei meinem Sharp-Basic Taschenrechner.
ich vermute eher, du kannst kein C, hast dich nicht mit dem API des obdev-USB-treibers auseinandergesetzt *und* auch nicht über die konkrete applikation nachgedacht:
das ist keine class, sondern eine struct. und die macht hier sehr viel sinn, weil die einzelnen werte in diesem 8-byte-ding festgelegte bedeutungen haben, also bildet man sowas in C als struct ab. das ist keine schwarze magie, sondern lehrbuchgemäß.
der kommentar drüber mit "permanent" veranlaßt mich, zu vermuten, daß man die einzelnen kanäle "temporär" (bis zum power-off) oder permanent schalten kann, und die permanenz wird wohl durch speicherung im eeprom erreicht werden.
herauszufinden, daß das so ist, hat übrigens ca 3 klicks bis ins vusb-wiki zur API-doku gebraucht.
die doku zu dieser USB-implementation weist darauf hin, daß man die USB-transfers nicht interrupten darf. also wird das flag, das der timer setzt, gepollt.
ich glaub eher, es kann einen sowieso verwirrten leser nicht entwirren.
nein, es gibt wirklich keinen grund, über VUSB zu schimpfen, nicht nur wegen des geschenkten gauls, sondern weil es definitiv zu den gut designten und dokumentierten open-source-projekten gehört.
cm.
--
** christian mock in vienna, austria -- http://www.tahina.priv.at/
> www.flamingtext.com
Ich hab mir jetzt mal das Beispiel mit dem Remotecontrol angesehen.
Dort sieht das so aus:
------------------------------------------------------------------- static uchar replyBuffer[8]; /* we don't need to store much status because we don't implement multiple * chunks in read/write transfers */
uchar usbFunctionSetup(uchar data[8]) { uchar len = 0;
if(data[1] == 0){ /* ECHO */ len = 2; replyBuffer[0] = data[2]; replyBuffer[1] = data[3]; }else if(data[1] == 1){ /* poll data available */ len = 1; replyBuffer[0] = fifoSize(); }else if(data[1] == 2){ /* read data */ if(fifoSize()){ len = 8; fifoRead(replyBuffer); } } usbMsgPtr = replyBuffer; return len; }
Ich finde pures ASM gerade bei den kleinen AVRs sehr praktisch. Durch die huebsche Architektur sind die gut in Assembler zu programmieren und der kleine Speicher begrenzt den Einsatz auf Projekte die als ganzes ueberschaubar bleiben. Wenn dann die Anwendung auch noch speziell auf die Hardware zugeschnitten ist, spielt es oft keine Rolle wenn die Firmware nicht 1:1 auf andere Architekturen portierbar ist. Ausserdem hat man mit ASM bessere Kontrolle und besseren Ueberblick ueber das Echtzeitverhalten.
Grosse Sachen sind in C dagegen viel einfacher zu realisieren, mit weniger Fehlern, uebersichtlicher und deutlich portabler. Das Gemisch mit Inline-ASM ist halt fuer den Bereich dazwischen die geeignete Loesung. Ab einem gewissen Punkt ist vielleicht sogar C++ sinnvoll wenn die Firmware _richtig_gross_ wird.
Wenn man Strom sparen muss, laesst man einen AVR heute auch nicht unbedingt mit 20MHz laufen ...
Das ist ein herkömmlicher "Type cast". Das ist ganz normale C-Syntax um einen Datenwurm zu strukturieren. Wäre Dir anstelle von "rq->bRequest" "data[3]" lieber? Oder "data[BREQUEST]"? Immerhin kann man bRequest nicht auf andere Datenwürmer loslassen. Wenn überhaupt würde ich bemeckern, daß der Funkion nicht schon (usbRequest_t *) übergeben wird. Denn beim Aufruf kann man sich noch überlegen, ob der Wurm wirklich ein usbRequest_t sein soll.
Der Wert soll wohl über Stromlose Zeiten erhalten bleiben. Und EEPROM lesen ist was anderes, als Instruction oder Data zu lesen. So ganz kannst Du Dich auch in C nicht von der Hardware abheben.
8 unabhängige Rückwärtszähler. Nicht allzu genau, falls computeOutputStatus halbwegs vorhersagbare Ausführungszeit hat.
Hätte vielleicht mal ein Interrupt werden sollen...
Ich sprach nicht blumig von Kostendruck, sondern von den Kosten, die ein Selbstbau und Komplettentwicklung auf µC gegenüber einem Einkauf eines fertigen (z.B. ARM-)Boards und Entwicklung von Software und (soweit notwendig) Peripheriemodulen verursacht.
Das ist ganz klar stückzahlabhängig. Bei geringer Stückzahl lohnt es sich einfach nicht, ein "fettes" µC-Board samt Software selbst zu entwickeln.
Ich glaube meine Meinung dazu ist in der Gruppe hier bekannt. Wenn man solche Boards selbst designen will sollte man dazu einen sehr guten Grund haben. Wenn die Stückzahl nicht extrem hoch liegt, kriegt man die Entwicklungskosten nimmer wieder rein.
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.