Ich bin im Moment gut in Assembler eingefahren und benutze das STK500 und STK600 mit Atmel AVRs zum entwickeln. Ich benutze das JTAG II in cirquit debugging und es läuft soweit so gut... Nur wenn ich irgendwelche Programmbeispiele hier im Netz suche, dann sind diese zum meissten Teil in C geschrieben, was mich zum grübeln bringt, ob C irgendwelche Vorteile hätte, die ich nicht erkannt habe... Hat es denn Vorteile oder Nachteile? Ist der aus C compilierte Programmcode im Prozessor langsamer oder gleich schnell? Braucht er mehr Platz? In wie weit erleichtert es die Programmierung? Wenn alles in Bibliotheken vorliegt, dann kann man es bestimmt schneller in das Programm einbinden, oder? Ich habe in Assembler auch schon Macros und Subroutinen geschrieben, die bei späteren Projekten einfach hinein kopiert wurden. Ist das das selbe oder hat C dabei weitere Vorteile? Postet mal eure Erfahrungen, Pro's und Contra's...
> ob C irgendwelche Vorteile hätte, die ich nicht erkannt habe...
Er ist leichter lesbar, leichter wartbar, leichter portierbar...
Da die ganzen Definitionen der Register prozessorspezifisch ist und auch die Hardwareansteuerung spezifisch zu den Controllern ist ist eine Portierung von einem Controller zum anderen ziemlich utopisch. Insofern ist das bei Controllerprogrammierung eigentlich kein Thema. Mein Senf: pro Assembler: - man versteht genau was man tut - leichtes Debugging (man muss nicht erst verstehen was der Compiler daraus macht) - schnell - keine krude Systax um dem Compiler z.B. mitzuteilen daß sich eine Variable jederzeit "von aussen" ändern kann. - man sieht deutlich besser wie lange ein Block braucht. Pro C - Leichteres Handhaben von 16 und 32 Bit Zahlen - Leichtes Umgehen mit Strings (bei Verwendung von Displays). - Schneller wenn man viel Übung hat - kann (nicht muss) übersichlicher bei größeren Projekten sein - bedingt leicher lesbar (nicht bei C Spaghetticode) Mein Fazit: Die paar Mal die ich Microcontroller programmiert habe habe ich das in Assembler gemacht, obwohl ich beruflich 10Jahre C programmiert habe.
Auf jeden Fall in C Programmieren, in Assembler nur wenn es unbedingt sein muss. Sobald die Programme etwas länger werden bleibt es übersichtlich. In C löst man Aufgabenstellungen, um den Rest kümmer sich der Compiler. Axel
Ich schließe mich der Meinung von Axel an, allerdings möchte ich selbige niemandem aufdrängen :-) Ich programmiere so weit wie möglich in C und nur wenns unbedingt sein muss in Assembler. Hintergrund ist die erheblich einfachere Portierbarkeit, und zwar nicht nur auf einen anderen Prozessor der selben Familie, sondern auch 'mal eben' auf eine komplett andere Architektur. Beispielsweise entwickle ich derzeit einen Bytestream-Interpreter, der Grafiken auf Displays pinselt. Ein Paar Präprozessordefines dazu und schon pinselt der selbe Code in GTK+.. :-) Das beschleunigt das Debuggen und Designen (der Menüstruktur) massiv. Und wenn ich lustig bin, dann läuft der selbe Code später nicht nur auf einem AVR8 (derzeit in Gebrauch in Form eines Mega32), sondern auch auf ARM. Klar könnte ich, wenn ich mich richtig anstrengen würde, vielleicht hier oder da ein Quentchen mehr Leistung rauskitzeln mit handoptimiertem Assembler - dafür dürfte ich die Arbeit für die diversen Architekturen dann aber mehrfach erledigen.. Und die Lesbarkeit ist in C ebenfalls erheblich besser, sofern man anständig strukturiert und benennt. Aber auch Assembler hat seine Berechtigung - und zwar dann, wenns auf jeden einzelnen Takt und das in einer bestimmten Reihenfolge ankommt (eine Reihenfolge, die natürlich(tm) nur der Programmierer kennt..). Timing beim Bitbanging z.B. In anderen Worten: Anständiges C wo immer es möglich ist, und Assembler nur da, wo es unbedingt sein muss.
> Da die ganzen Definitionen der Register prozessorspezifisch ist und auch > die Hardwareansteuerung spezifisch zu den Controllern ist ist eine > Portierung von einem Controller zum anderen ziemlich utopisch. Das gilt für das Hardware-Layer. Wenn man das einigermaßen abstrahiert, kann man die drauf aufsetzenden Teile aber relativ leicht portieren. Bei kleinen Programmen bringt das nicht viel, aber sobald es etwas größer wird, ist das durchaus sinnvoll. Außerdem kann man diese Teile dann auch auf dem PC direkt testen, weil der auch in C programmiert werden kann.
>> Er ist leichter lesbar, leichter wartbar, leichter portierbar...
Es ist weder leichter noch lesbarer es sei denn man bemüht sich darum.
Der Kopierschutz kann sozusagen im Sourcecode, mittels schreibweise,
veranckert werden :-)
Es gibt aber durchaus gute Gründe für C und einer ist Assembler. C ist
zu großen Teilen protierbar. Außerdem zwingt dich C in saubere
Strukturen.
C versus Assembler wird aber immer "flamewar" werden. Sieht man der
Realität ins Auge so stellt man heutzutage sehr schnell fest das C von
den Kunden gefordert wird. Das war vor 20... 10 Jahren noch ganz anders.
Ich habe meinen Umstieg aus genau diesem Grund vor ca. 5 Jahren
vollzogen und er dauert bis heute an :-) Assembler ist ne feine Sache
aber leider nicht mehr gern gesehen.
C ist aus meiner Sicht äußerst komplex und du wirst einige Zeit für den
Umstieg brauchen. Aus heutiger Sicht würde ich es dir aber empfehlen.
Winzige Projekte -> Assembler ("Huch, ich hab ja nur 32 Byte RAM!") Kleine Projekte -> C oder Assembler Grosse Projekte -> C In bisschen Bit friemeln hat in Assembler sogar echte Vorteile, man denke auch an den direkte Zugriff auf das Carry-Flag. Komplexe Projekte willst Du aber schon deswegen in C programmieren, weil Du die fertige Laufzeitbibliothek gleich mit am Start hast. In Assembler sitzt Du erst mal dabei, Deine ultimative Divisionsroutine zu debuggen.
@Autor: Igor Ebner Tausendmal diskutiert im Internet, mit Vorliebe von Dummschwätzern. Mein Rat: C muss man eh (etwas) beherrschen, wie Englisch, Autofahren, Schwimmen,.. Lerne also C, wenn Du etwas Zeit hast. Dann kannst Du selber entscheiden.
Danke für Eure Antworten. Würde mir beim Umstieg auf C irgendwelche Nachteile bei der Benutzung der IDE auftreten? Z.B. könnte ich darin noch mit meinem AVRATJTAGICE mkII ein in circuit debugging machen? Könnten Assembler Routinen in den C Code mit eingebaut werden, wenn ich der Meinung bin an der Stelle brauche ich es? (z.B. Bitfrimeleien, zeitkritische Unterroutinen usw)? Oder müsste ich es von vorne herein entscheiden dass es alles in Assembler geschrieben werden muss, wenn ich schon weiss, dass ein paar kleine Assembler Unterroutinen benötigt werden würden?
>> Könnten Assembler Routinen in den C Code mit eingebaut werden
kannst du, brauchst du aber nicht. Genau solche Fragen haben mich
seinerzeit auch beschäftigt aber du wirst es herausfinden.
Debugging geht ebenso allerdings siehst du den vom C Compiler
generierten Code und nicht mehr das, was du gewohnt warst.
Das klingt doch alles schon mal super. Ich glaube es geht gleich los mit dem einlernen :c) > >kannst du, brauchst du aber nicht > Ich habe z.B. ein Projekt für eine lernbare Fernbedienung. Hier muss das Timing der Signale ganz genau stimmen. Das wird wohl nur mit Assembler funktionieren. Diesen Teil habe ich in Assembler schon fertig. Könnte ich also das Programm in C mit dem (AVR Studio GCC Plugin) beginnen und den Assemblerteil problemlos in der IDE mit einbauen / importieren anhängen aufrufen? Könnte ich z.B. auch die zeitkritischen IRQ Routinen alles in Assembler lassen? > >Debugging geht ebenso allerdings siehst du den vom C Compiler >generierten Code und nicht mehr das, was du gewohnt warst. > Würde der Debugger dann auch in diesen eingebauten Assembler Routinen bei Breakpoints stehen bleiben und es wie früher gewohnt anzeigen? Was zeigt er denn bei C an? Nur die ganze Zeile?
Ist mir auch zu Anfang passiert, nach 10 Jahren Assembler wollte ich C mit Assembler mixen. Damit vereint man aber nur die Nachteile von beiden. Zu 99,99% braucht man das auch nicht, es geht alles in C. C ist natürlich portabel. Ich programmiere 8051 und AVR und habe keine Probleme, Routinen auf beiden einzusetzen. Z.B. für 1-wire muß man nur das Timing der Resetfunktion und der Bit-IO-Funktion anpassen, der Rest bleibt unverändert (Byte-IO-Funktion, Messung starten, Temperatur auslesen, ROM-Search, CRC). Da selbst die kleinsten AVRs (ATtiny13) inzwischen alle SRAM haben, kann man also immer C nehmen. Peter
>> Ich habe z.B. ein Projekt für eine lernbare Fernbedienung. Hier muss das >> Timing der Signale ganz genau stimmen. Das wird wohl nur mit Assembler >> funktionieren. NEIN !!! Das kannst du genauso in C machen und ich würde dir, wie jedem Anfänger, empfehlen erst mal ne LED zum blinken zu bringen. AVR Studio verwende ich nicht aber probiers doch mal aus.
>zeigt er denn bei C an? Nur die ganze Zeile?
Keine Ahnung.
Es soll auch Leute geben, die eingentlich nie einen Simulator/Debugger
benötigen. Man kann natürlich versuchen alles durch Probieren zu lernen.
Man kann aber auch zuerst Lesen/Lernen, dann nachdenken und erst dann
den Code schreiben. Als Debugging nimmt man dann am PC eine "print"
Ausgabe, oder man schickt die Ausgabe vom uC per UART an den PC.
Stefan Salewski schrieb: > Es soll auch Leute geben, die eingentlich nie einen Simulator/Debugger > benötigen. Stimmt. Ich programmiere immer nach Datenblatt und dann prüfe ich nur, ob das Gewünschte passiert, d.h. ob ich alles richtig verstanden hab. > Man kann natürlich versuchen alles durch Probieren zu lernen. Das halte ich nicht für effektiv, auch nicht mit einem Debugger. Peter
> Würde der Debugger dann auch in diesen eingebauten Assembler Routinen > bei Breakpoints stehen bleiben und es wie früher gewohnt anzeigen? Ja. > Was zeigt er denn bei C an? Nur die ganze Zeile? Du kannst wählen, ob er dir C-Codezeilen, Assembler oder beides zusammen anzeigt. Wenn du bei C aber Optimierungen an hast, sortiert der Compiler evtl. auch schon mal Instruktionen um, und dann sieht es auf C-Ebene nach einem recht wilden Hin- und Hergespringe aus. Daran muß man sich erst gewöhnen. Assembler kannst du entweder mit C mischen, indem du in Assembler geschriebene Funktionen dazulinkst. Dann mußt du dich aber selbst darum kümmern, das ABI korrekt umzusetzen (Aufrufkonventionen u.s.w.). Einfacher ist es, kurze Assembler-Fragmente als Inline-Assembler in den C-Code einzubetten.
Manch ein Debugger kann einem auch anzeigen, welche Zeile vom C-Sourcecode quasi gerade ausgeführt wird. Selbst schon so gearbeitet mit einem NEC 78K0R und der dazugehörigen Entwicklungsumgebung.
Igor Ebner schrieb: > Ich habe z.B. ein Projekt für eine lernbare Fernbedienung. Hier muss das > Timing der Signale ganz genau stimmen. Das wird wohl nur mit Assembler > funktionieren. Nö. Zuerst mußt Du mal festlegen, wie genau genau sein muß, also ganz konkret in µs. Bei IR-Signalen bietet sich ein Timer-Compare-Pin an, damit ist man immer zyklusgenau, d.h. unabhängig von Programmlaufzeiten. Somit hat C keinerlei nachteiligen Einfluß und man muß nicht Instruktionen abzählen. Vorteilhaft ist in C, daß man den Compiler die Berechnung der Timerwerte als float machen lassen kann und er dann einfach die Konstanten zur Compilezeit ausrechnet und einsetzt. Muß es nicht zyklusgenau sein, arbeiten auch die Delay-Funktionen der AVR-GCC Lib recht ordentlich. Da muß man aber eventuell Interrupts sperren, damit die das Delay nicht verlängern. Peter
Coooool... Ihr habt mich schon überzeugt und bin am installieren vom WinAVR :c) Die blinkende LED bekomme ich heute bestimmt noch gebacken :c) Also ich sehe überhaupt keine Nachteile von C - ausser dass er mehr Speicher im Prozessor benötigen wird. Kann man den Mehrverbrauch irgendwie abschätzen z.B. das doppelte?
Igor Ebner schrieb: > Also ich sehe überhaupt keine Nachteile von C - ausser dass er mehr > Speicher im Prozessor benötigen wird. Kann man den Mehrverbrauch > irgendwie abschätzen z.B. das doppelte? Wenn man effektiv mit den Datentypen umgeht, braucht C etwa 5 ... 50% mehr. Für das Doppelte muß man schon grobe Schnitzer machen. Peter
>> Wenn man effektiv mit den Datentypen umgeht, braucht C etwa 5 ... 50%
Naja, 5 - 10%, mehr sollte es nicht sein. 50% ist mehr als ein grober
Schnitzer... ich programier die ganzen Tinys in C und die haben gerade
mal zum Teil 2K.
Also ich war auch lange auf dem Hardcore-Assembler-Tripp, obwohl ich in der Softwareentwicklung für den PC in C, C++ und Java sehr fit bin. Irgend wann hab ich dann mal den gcc für AVR getestet. Seitdem würde ich nur noch unter größtem Protest nochmal viel in Assembler machen. Wenn überhaupt, dann nur wirklich wichtige Teile des Gesamtprogramms. Die C-Syntax ist wesentlich ausdruckstärker, macht ein Programm viel übersichtlicher und deshalb unter anderem deutlich einfacher lesbar. In C kann man die Programme auch wesentlich besser strukturieren. Also es gibt IMO eigentlich kaum einen Grund (außer zum Einstieg), auf eine Hochsprache zu verzichten. Wobei ich ehrlich gesagt C++ für einfache uC im Moment noch für leicht oversized halte. Mal sehen, wie ich in zehn Jahren darüber denke.
Realist schrieb: > Wobei ich ehrlich gesagt C++ für einfache uC im Moment noch für > leicht oversized halte. Mal sehen, wie ich in zehn Jahren darüber denke. Was soll sich da aber groß verändern? Wenn der Mikrocontroller nur wenig Speicher hat, kann man den halt nicht groß für Objekte und vtables verbraten. C++, Java, C# etc. macht eigentlich auch erst mit einer vernünftigen Speicherkonfiguration Spaß. Zum Beispiel: C++ ohne die STL? Nicht wirklich. Oder aber man verwendet eine entsprechend abgespeckte Version dieser OO-Sprachen, mit reduzierten Features, aber dann kann man auch gleich bei C bleiben. ;-)
Ich finde beispielsweise Templates auch bei Controllern ganz nützlich. Nicht unbedingt die STL, aber geht ja auch anders. Ok, mein Kontakt mit C++ ist älter als die STL, ich kann mir auch noch ein Leben ohne sie vorstellen. Auch virtuelle Funktionen machen sich gut. Beispielsweise wenn man diverse Sensoren gleicher Klasse (Temperatur) aber unterschiedlicher Implementierung hat (DS1820, LM335). Gleiches Interface über die Basisklasse, verschiedene Implementierung als Ableitung. Das bischen vtable ist kein Problem. Natürlich kann man nicht das ganze C++ verwenden. Dynamischer Speicher ist nicht so gut, RTTI lässt man besser weg und für Exceptions fehlt leider nicht selten der Runtime-Support obwohl grad das nicht übel wäre. Aber schon rein stilistisch hat man was von C++.
Danke Jungs, ihr habt mich auf den richtigen Weg gelenkt. Die LED blinkt schon, die uart.c ist auch schon eingebunden und auf dem Comport gehen schon Daten raus... Die Hochsprache macht jetzt schon richtig Spass :c) Das Tutorial hier im Forum ist spitze :c) Das wird zwar nun hier offtopic aber eine Frage habe ich zum Grundsätzlichen: Ich habe mir als Beispiel Peter Fleury's uart.c eingebunden. Wenn ich nun diese Bibliothek erweitere (z.B. U2X Einstellungen fehlen, UART1 muss andere Baudrate bekommen als UART0), dann gibt es drei Möglichkeiten: 1) Entweder ich verändere Peter Fleury's Datei 2) oder ich schreibe mir eine persönliche uart_extension.c dazu, die die fehlenden Aufgaben erledigt. 3) Ich schreibe es einfach in die main.c dazu Wie macht Ihr solche Arbeiten? Lösung 1 wäre das sauberste, würde aber irgendwann durcheinander kommen, wenn ich später mal verschiedene uart.c Versionen auf der Platte habe, oder wenn neue Versionen von Peter heraus kommen würden. Lösung 2 würde auch funktionieren, ist aber nicht so sauber, wie Lösung 1. Ich muss bei jedem neuen Projekt einen Schritt dazu denken. Lösung 3 ist wohl die unsauberste, ich muss dann aber immer bei neuen Projekten diesen Programmteil aus einem alten Projekt heraus kopieren. Was wäre die beste Strategie, wenn es mal viele Projekte werden?
Hallo Igor In C zu Programmieren ist viel komfortabler da der Compiler Dir viel "Fleissarbeit" abnimmt. (z.b. auf 1^6 zählen) Ich selbst brauchte recht lange, um von Assembler auf C aufzuspringen und ich bin jetzt ziemlich glücklich mit C. (Obwohl immer noch kein C-Crack) Wenn es zeitkritisch wird, und Du C nicht vertraust, kannst Du Seqenzen immernoch in ASM programmieren. Du verlierst nichts sondern Du erweiterst dein Wissen. Gruss Dubrain
Igor Ebner schrieb: > Das wird zwar nun hier offtopic aber eine Frage habe ich zum > Grundsätzlichen: Erkenntnis "nun hier offtopic" = neuen Thread erstellen. Wie auch immer... > Ich habe mir als Beispiel Peter Fleury's uart.c eingebunden. Wenn ich > nun diese Bibliothek erweitere (z.B. U2X Einstellungen fehlen, UART1 > muss andere Baudrate bekommen als UART0), Hmm, zumindest in aktuellen Versionen von P. Fleurys AVR UART-Library sollte beides schon vorhanden sein. Habe grade nochmal in seinen aktuellen Code geschaut (nutze selbst ältere selbst modifizierte Versionen seines Codes, da die neueren Fassungen unter GPL stehen - eine Lizenz die zumindest meine Auftraggeber für Firmwarecode nicht akzeptieren) Betr. "U2X" z.B.:
1 | #define UART_BAUD_RATE 19200
|
2 | uart_init( UART_BAUD_SELECT_DOUBLE_SPEED(UART_BAUD_RATE,F_CPU) ); |
Das *_DOUBLE_SPEED-Makro sorgt dafür, dass das MS-Bit im Parameter zu uart_init gesetzt ist. uart_init nutzt dies zur Fallunterscheidung (U2X-Einstellung ja/nein, if ( baudrate & 0x8000 )...) Betr. unterschiedliche Baudraten z.B.:
1 | #define UART0_BAUD_RATE 19200
|
2 | #define UART1_BAUD_RATE 9600
|
3 | uart_init( UART_BAUD_SELECT_DOUBLE_SPEED(UART0_BAUD_RATE,F_CPU) ); |
4 | uart1_init( UART_BAUD_SELECT(UART1_BAUD_RATE,F_CPU) ); |
>dann gibt es drei > Möglichkeiten: > > 1) Entweder ich verändere Peter Fleury's Datei > 2) oder ich schreibe mir eine persönliche uart_extension.c dazu, die die > fehlenden Aufgaben erledigt. > 3) Ich schreibe es einfach in die main.c dazu > > Wie macht Ihr solche Arbeiten? Im Grunde wie unter (3), in "main.c", die Library-Funktionen mit den entsprechenden Parametern aufrufen, da - sofern die das richtig interpretiert habe - (1) und (2) für die genannten Anforderungen nicht erforderlich sind. > Lösung 1 wäre das sauberste, würde aber irgendwann durcheinander kommen, > wenn ich später mal verschiedene uart.c Versionen auf der Platte habe, > oder wenn neue Versionen von Peter heraus kommen würden. daher nicht so wirklich "sauber", eben da man immer wieder neu selbst Hand anlegen müsste. Es ist aber oft nur eine Wunschvorstellung, dass man den Quellcode nur einmal auf der Platte hat (hier z.B. uart.h/.c) und damit alles Gut ist, denn manchmal ändern Library-Ersteller die Schnittstellen. Dann darf man jedes alte Projekt nochmal anfassen, an die einzige gerade aktuelle Version anpassen bzw. einen "Interface-Layer" nachrüsten und dann mglw. nochmal aufwändig diverse Tests durchlaufen lassen. Der große Vorteil einer einzigen Version ist allerdings, dass eine Fehlerkorrektur in der Library sich "automatisch" beim neucompilieren in allen Projekten "herumspricht". > Lösung 2 würde auch funktionieren, ist aber nicht so sauber, wie Lösung > 1. Ich muss bei jedem neuen Projekt einen Schritt dazu denken. Denke, dass ist hier nicht erforderlich (s.o.). Ansonsten halte ich eine solche Lösung allerdings schon für "sauber" da (a) Code der Fremdlibrary ohne Änderung wiederverwendbar, (b) eigene Hilfs-Library auch (irgendwann wenn man genug Fallunterscheidungen eingebaut hat) ohne Quellcodeänderung wiederverwendbar. Beides minimiert den Aufwand bei neuen Projekten. > Lösung 3 ist wohl die unsauberste, ich muss dann aber immer bei neuen > Projekten diesen Programmteil aus einem alten Projekt heraus kopieren. Herauskopieren finde ich per se nicht verwerflich, manchmal ist es später leichter nachvollziehbar, wenn man z.B. Initialisierungen "an einem Stück" sieht, statt in diversen Unterfunktionen nachzulesen, was genau passiert (o.k. mit einem schicken Editor wie dem in Eclipse, ist das per "mouse-hoover" recht schnell zu sehen). Kommt - wie meistens - darauf an, ob man viel Arbeit in wiederverwendbaren Code steckt oder mglw. mit geringerem Aufwand per copy-paste-anpassen nur projektspezifischen Code erstellt. > Was wäre die beste Strategie, wenn es mal viele Projekte werden? s.o. - ist aber natürlich eine subjektive Einschätzung. Eine studierter Informatiker mit Schwerpunkt Software-Engineering sieht das mglw. anders.
Ahhhh, verstehe, verstehe... ... das mit der Baud Rate. Es ist nicht nur ein Wert, das für die ganze uart.c/h Datei gilt, sondern je nach dem welche Unterroutine in der Datei aufgerufen wurde, für die wird der aktuelle Wert verwendet. Genial... :c) Das ist definitiv einfacher als im Assembler. Dann muss ich an Peters Lib ja gar nichts ändern :c) Dann sollte man Lösung 1 also auf keinen Fall machen und immer brav die Original Libs original lassen und in ein neues Projekt umkopieren. Gut, nachdem es nun wirklich off topic ist - meine Ursprüngliche Frage ist ja beantwortet - nochmal Danke an alle für die Geduld - ihr habt jetzt einen neuen C Liebhaber am Hals :c) Für weiteres mache ich dann schon neue Threads auf, nachdem ich noch ein paar tausend Threads zum vorher durchlesen habe...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.