ATmega und USB, suche Tutorial

Genau wie dein main().

Meine Umsetzung geht natürlich davon aus, daß die while-Schleife der einzige Inhalt von main() ist. Naheliegende Optimierung nicht erkannt? Naja, warum solltest du auch besser sein als dein Compiler...

Inwiefern? Das sind zwei 16Bit-Zeiger als Parameter. Wieso sollte ich für sowas den ultralangsamen Stack bemühen? Diese Optimierungsmöglichkeit erkennt ja sogar jeder halbwegs brauchbare Compiler noch.

Aber ansonsten ist das ein schönes Beispiel, um zu zeigen, wie suboptimal Compiler (inbesondere avr-gcc) tatsächlich immer noch sind. Nehmen wir mal an, "machwas" sollte näherungsweise mit der von dir vorgegebenen Funktionssignatur arbeiten und die Aufgabe von "machwas" wäre, in feld[X] jeweils die Summe der ASCII-Werte der chars in text von Position 0 bis Position X abzulegen. Also das komplette (natürlich ziemlich sinnfreie) Programm sähe in C in etwa so aus:

char *text="Hallo Welt"; int feld[256];

void machwas(text,textlen,feld) { int sum=0; for (i=0;i

Reply to
Heiko Nocon
Loading thread data ...

Josef Moellers schrieb:

Wir sprachen immer noch von µCs. Im speziellen von Atmega/ATtiny. Da gibt es im allgemeinen recht wenig umzuordnen und im speziellen eigentlich gar nichts.

Im übrigen ist beim AVR-GCC die Compiler-Option -Os eigentlich obligatorisch. So wird aus

int main(void) { // Enable output on port B3: DDRB|=(1U

Reply to
Jan Kandziora

Stefan Brröringschrieb: "

.. gut lesbar sieht es so aus

enum {ECHO =0, POLL =1, READ =2};

uchar usbFunctionSetup(uchar data[8]) { uchar len = 0;

switch(data[1]) { /* ECHO */ case ECHO: replyBuffer[0] = data[2]; replyBuffer[1] = data[3]; len = 2; break;

/* poll data available */ case POLL: replyBuffer[0] = fifoSize(); len = 1; break;

/* read data */ case READ: if(fifoSize()) { fifoRead(replyBuffer); len = 8; } break;

default: break; }

usbMsgPtr = replyBuffer; return len; }

Dirk

Reply to
Dirk Ruth

Ja und vor allem sollte der OP sowas auch von Pascal her kennen, denn die dortigen "records" sind nix anderes, heißen halt bloß anders.

Jepp. Das mußte sogar ich als eingefleichter C-Hasser zugeben.

Reply to
Heiko Nocon

Falsch.

Ganz schwacher Versuch...

Ich habe mir erlaubt, "machwas" als static zu deklarieren. Andernfalls kann der Compiler die Funktion nicht inlinen.

...

Je

nachdem ob eher auf Codesize oder Geschwindigkeit optimiert wird.

...

Reply to
Falk Willberg

Am 22.12.2010 17:59, schrieb Jan Kandziora:

...

Statt der seltsamen SUBI würde man halt DEC schreiben. SUBI braucht aber auch nur einen Takt (dafür mehr Code), ist aber vermutlich universeller.

Es fehlt halt die Option "--create-readable-assembler-code" ;-)

Falk P.S.: Dieser Klugscheißer von Usenet-Server nölt wieder mal herum, daß das Verhältnis zwischen Zitat und Text nicht gut ist. Dieser Klugscheißer von Usenet-Server nölt wieder mal herum, daß das Verhältnis zwischen Zitat und Text nicht gut ist. Dieser Klugscheißer von Usenet-Server nölt wieder mal herum, daß das Verhältnis zwischen Zitat und Text nicht gut ist. Dieser Klugscheißer von Usenet-Server nölt wieder mal herum, daß das Verhältnis zwischen Zitat und Text nicht gut ist. Dieser Klugscheißer von Usenet-Server nölt wieder mal herum, daß das Verhältnis zwischen Zitat und Text nicht gut ist. Dieser Klugscheißer von Usenet-Server nölt wieder mal herum, daß das Verhältnis zwischen Zitat und Text nicht gut ist.

Reply to
Falk Willberg

Vielleicht lese ich das falsch, aber obiger Code zaehlt 'i' doch von Null her hoch. Das passt irgendwie nicht zum Assembler-Code unten. Vor allem erstmal R24 mit 2 zu laden und dann 1 abzuziehen damit 1 drinsteht ist schon sehr komisch. Auch fehlt mir das Aquivalent zum zweiten 'i++', oder soll das wirklich ein durch ein R24 = R24 - 255 dargestellt sein? Inwiefern ist das besser als inc?

Ich haette da eher was mit

ldi r24, 0x00 inc r24 (*) out 0x18, r24 inc r24 out 0x18, r24 rjmp (nach (*))

erwartet...

Gerrit

Reply to
Gerrit Heitsch

Falk Willberg schrieb:

Nein, lies nochmal. Subi statt addi zu benutzen ist eine GCC-Marotte, macht er auch bei anderen Architekturen entsprechend. Inc und dec beim AVR zu ignorieren ist auch kein Verbrechen, der AVR hat eine Menge äquivalenter Opcodes, z.B. ldi r16,0x00 und clr r16. (Dafür fehlen wieder andere, sinnvolle Opcodes...)

Im obigen Code ist aber die Schleife seltsam "optimiert". Beim ersten i++ macht er subi 0xff, was inc entspricht, genauso groß ist und genauso lange dauert. Ich bin zwar nicht entzückt, aber einverstanden. Beim zweiten i++ macht er aber erstmal subi 0xfe, dann den Sprung, dann nochmal subi 0x01. Warum? Es gibt keinen Grund, dieses i++ anders zu übersetzen als das erste.

Mit freundlichem Gruß

Jan

Reply to
Jan Kandziora

Hallo Jan,

Jan Kandziora schrieb:

Ich tippe mal, daß der Codegenerator will, daß nach einem ++ die Flags passend sitzen, damit er darauf basierend Sprünge machen kann. Optimal ist in der Tat etwas anderes.

Gruß Martin

--
Bitte nicht an der E-Mail-Adresse fummeln, die paßt so.
Reply to
Martin Schoenbeck

Jan Kandzioraschrieb: "

Du vergisst, dass solche Fertigboards nur für erste Gehversuche, oder für Industrieprodukte in kleinen Stückzahlen sinnvoll sein können.

Was machst du, wenn diese Boards rein mechanisch schon nicht passen? Stell dir einfach ein kleines Navigationssystem vor. Da gibt es auch welche, die nicht in riesigen Stückzahlen laufen. Oder nimm einen hochwertigen Fotoapparat mit Display, FAT-File-System und Bilderkennungssoftware um z.B. Autofokus zu steuern. Auch solche hochwertigen Kamaras laufen nicht in riesigen Stückzahlen. Meßgeräte (passend zur Gruppe) laufen nicht in riesigen Stückzahlen und haben auch USB und FAT32, Ethernet usw. Ich könnte jetzt noch mehr Beispiele aufzählen, aber allein das es für solche Boards (wichtige Komponente) keine second source gibt, ist für die meisten Hersteller ein absolutes KO-Kriterium. Kernkomponenten entwickelt man immer selbst, sonst baut man irgendwann nur noch zugekaufte Zeile zusammen und wird am Ende auch nix mnehr daran verdienen, bzw. kann sich auch nicht mehr vom Wettbewerber absetzen.

Dirk

Reply to
Dirk Ruth

Am 21.12.2010 16:20, schrieb Stefan Brröring:

Wenn Du einen AVR mit integrierter USB Hardware (AT90USB...) verwendest, schau Dir mal LUFA an:

formatting link

Der Entwickler ist noch Student, aber seine Library wirklich top. Er hat Beispielprogramme für so ziemlich jede Anwendung dabei und hilft auch schnell weiter, falls Du auf Fehler oder Probleme solltest.

Gruß

Ronnie

Reply to
Ronnie Jäger

Martin Schoenbeck schrieb:

Hätte ich auch gedacht, aber schreibt man naheliegend mal

uint8_t i;

int main(void) { i=0; DDRB=0xff; for(;i

Reply to
Jan Kandziora

Hallo Jan,

Jan Kandziora schrieb:

Der Code an den Stellen ist ja auch gleich geblieben. Ich denke, die Codegenerierung schaut hier einfach nicht über den Tellerrand. Bei einem if (i++) PORTB = i; würde man den Effekt vermutlich sehen.

Wenn der Codegenerator so schlecht ist, bietet sich das an. Vorausgesetzt, der Platz ist knapp oder die Performance reicht nicht. Ansonsten tut man generell besser daran, sich um so etwas nicht zu kümmern, sondern die Arbeit in Dokumentation / Kommentare und das Design auf höherer Ebene zu stecken. Das spart zwar im ersten Moment keine Takte und keinen Platz, langfristig aber garantiert mehr.

Gruß Martin

--
Bitte nicht an der E-Mail-Adresse fummeln, die paßt so.
Reply to
Martin Schoenbeck

Dirk Ruth schrieb:

Genau das schrieb ich: Es kommt auf die Stückzahl an. Du bekommst brauchbare ARM-Boards schon für unter 100 Euro (Einzelstück). Nehme ich 100 Stück, komme ich auf unter 70 Euro runter.

Da sind mehrere USB2.0 und Fast Ethernet bereits funzend drauf, etliche GPIOs oder UARTs und evtl. ein FPGA für schnelle Sachen hat so ein Board auch noch. Viel mehr Speicher als ein µC ohnehin. Dann kommt noch dazu, dass ich mir über das ganze Treibergedöns nur relativ wenig Gedanken machen muss, mit dem draufgespielten OS funktionieren USB, Ethernet, SD-Card usw. einfach.

Um an diese Stelle mit einem "fetten" selbstentwickelten Board überhaupt zu kommen müsste man bereits >>100 Arbeitsstunden reinstecken. Das sind Minimum 10000 Euro. Wenn du ehrlich rechnest das doppelte. Dafür kann man

Auch fertige Handheld-Geräte kriegst du in allen Größen und Maßen hinterhergeworfen. Und wenn irgendeine Peripherie nicht passt wird sie passend gemacht. Das ist ohnehin alles modular.

Ich denke schon, dass sie in vergleichsweise riesigen Stückzahlen laufen. Von einem 500-Euro-Fotoapparat sieht der Hersteller vielleicht 150 Euro. Wenn er gut verhandelt hat. Allerdings knabbern die Entwicklungskosten vermutlich sowieso an der Millionenmarke, so dass sich die Entwicklung eines eigenen MIPS/ARM-Boards natürlich lohnt. Aber schon die Entwicklung eines eigenen OS dürfte schon wieder nicht lohnen.

Da ist die Bauform relativ wumpe, würde ich auch mit einem zugekauften Board machen.

Und da muss man sich fragen: Was ist unsere Kernkompentenz? Ist es das Erstellen von Schaltplänen, Layouts und Treibern für USB-Hosts, für Ethernetchips, für Speicherkarteninterfaces? Das ist in 2 Jahren sowieso alles wieder Schnee von gestern. Soll ich mir für

Reply to
Jan Kandziora

Martin Schoenbeck schrieb:

Genau das ist ja der Punkt:

Ich gehe davon aus, dass man einen µC einsetzt, weil man an kritischen Stellen jede µs braucht. Wenn mir das Timing mehr oder weniger egal ist kann ich das von einem OS auf einem "richtigen Rechner" machen lassen.

Deshalb ja meine anfängliche Feststellung, dass C auf µC meiner Meinung nach keinen wirklichen Anwendungsfall hat.

Mit freundlichem Gruß

Jan

Reply to
Jan Kandziora

Wuerde ich so pauschal nicht sagen. Hier sind viele Designs ueber den Tisch gegangen wo der uC (nicht von mir) in C programmiert wurde. Zum einen verstehe ich das als Analogix dann so einigermassen, zum anderen sind spaeter Aenderungen durch jemand anders als den Autor einfacher. Zumal bei solchen Sachen leider oft davon ausgegangen wird dass ein paar Kommentarzeilen im Source Code eine ausreichende Dokumentation darstellen.

Nicht jeder uC wird bis Oberkante Unterlippe ausgeknirzt. Die meisten die mir unterkommen nehmen nur Keyboard und RF Inputs an, schalten hie und da eine Sache, bisserl PWM, und wenn's hoch kommt treiben sie noch ein LCD. Das war's dann schon fast. Sowas geht gemuetlich in C. Fuer flotte Interrupt Routinen gibt es notfalls Inline-Assembler.

--
Gruesse, Joerg

http://www.analogconsultants.com/

"gmail" domain blocked because of excessive spam.
Use another domain or send PM.
Reply to
Joerg

Am 22.12.2010 21:48, schrieb Jan Kandziora:

...

Das dürfte eher die Ausnahme sein.

Low-Power Systeme, die in der kurzen On-Time etwas kompliziertere Ganzzahlarithmetik betreiben müssen.

Systeme, die noch 1cm² Platz für die komplette Logik haben, umfangreiche Protokollimplementierungen für Automotive, größere Stückzahlen mit entsprechendem Kostendruck.

Evtl. muß ich nächstes Jahr ein kleines Ding neu machen. Da 90% der Firmware CPU-unabhängig ist, bin ich in der Wahl des Prozessors frei.

Deshalb mein Widerspruch ;-)

Falk

Reply to
Falk Willberg

Hallo Jan,

Jan Kandziora schrieb:

Ok. Dann gehst Du von falschen Voraussetzungen aus. Man wäre ziemlich schlecht beraten, in irgendwelchen Kleinkram 'große' Prozessoren einzusetzen, nur weil man einen µC damit nicht komplett auslasten kann.

Wie kommst Du zu der Idee, 'timing nicht egal' hätte irgendwas damit zu tun, ob man einen Prozessor bis zur letzten µS vollpackt?

Sogar dann, wenn es auf die µS ankommt, bin ich im Zweifelsfall besser beraten, denn nächst schnelleren Prozessor zu nehmen und dafür die Software in der halben Zeit zu entwickeln. Wenn's nicht ganz riesige Stückzahlen sind. Und in dem Fall bietet sich dann an, etwas Geld in den Compiler zu investieren, damit man einen hat, der ordentlich optimiert. Was der gcc prinzipiell eigentlich recht gut kann, nur offenbar dieser Codegenerator nicht. Und ja, ein wirklich guter Codegenerator erzeugt gerade aus C Code, über den Du beim Assemblerprogrammieren dreimal nachdenken mußt und ihn zwei Wochen später nicht mehr ohne Nachdenken verstehst.

Gruß Martin

--
Bitte nicht an der E-Mail-Adresse fummeln, die paßt so.
Reply to
Martin Schoenbeck

Am 22.12.2010 23:03, schrieb Martin Schoenbeck:

...

Mich würde mal der Assembler-Code eines kommerziellen Compilers für eines der gegebenen Beispiele interessieren.

Falk

Reply to
Falk Willberg

Falk Willberg schrieb:

Mich auch.

Mit freundlichem Gruß

Jan

Reply to
Jan Kandziora

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.