Guten Tag, ich möchte euch hier ein Scheduler zeigen. Vielleicht kann das für jemand behilflich werden. Grundidee stammt von einem Blogger mit Pseudonym DI HALT. Vorteil so einer Lösung, wenn auf den ersten Blick auch etwas abschreckend aussieht: man kann Projekt leichter pflegen und erweitern. Hier ist eine Probe, mit einer Platine mit AtMega128A von Olimex. Scheduler selbst, das sind rtos.c und rtos.h. Alles andere ist nur zum Verständnis, wie alles funktioniert. Tastenabfrage ist nach Herrn Dannegger. lcd.c und lcd.h - Grundideen aus diesem Forum, dazu noch Modus mit Puffer in RAM (um nicht nach jedem Zeichen 50 us nutzlos warten zu müssen). Außer Init gibt es vier Funktionen: SetTask speichert eine Aufgabe in Puffer. SetTimerTask speichert eine Aufgabe in Timmerpuffer, für Verzögerung. TaskManager arbeitet in der Hauptschleife ( while(1) ) und führt die Aufgaben aus. TimerService wird in Timerinterrupt jede 1 ms (oder so ähnlich) durchgeführt: Die Programmtimer werden decrementiert und nach der Zeit wird die Aufgabe mit SetTask in Puffer gesetzt. Aufgabenpuffer ist als Ring gemacht, Timerpuffer nicht als Ring. Zusätzlich gibt es die Möglichkeit, für jede Aufgabe bis 3 Variablen zu speichern, die auch in Puffern bleiben. Diese Funktionalität ist zwar nicht zwingend notwendig und kostet RAM und Zeit, erleichtert aber das Programmieren. Für eure Kritik werde ich dankbar. Viele Grüße, Maxim.
Säbelzahn schrieb: > die Programme und die Ideen von > Anderen. Sollte ich Fahrrad selbst erfinden? Selbst in Datenblatt stehen Programmbeispiele. Nicht benutzen? Autoren von Ideen habe ich genannt, noch eigene Ideen dazu gebracht... Hoffentlich etwas brauchbares bekommen. Ich habe schon mit Scheduler (aber die Variante ohne Variablen) ein Ding gemacht. Selbst J.S.Bach, mein Kollege aus Leipzig, hat die Tonleiter nicht selber erfunden.
:
Bearbeitet durch User
OT: Es ist mir immernoch schleierhaft, warum man auf einem 8bit Prozessor einen Scheduler braucht? Kriegt man es nicht hin so ein paar Prozesse ohne Wartezyklen parallel laufen zu lassen?
Albert schrieb: > warum man auf einem 8bit > Prozessor einen Scheduler braucht? Um schneller viele gute Dinge machen zu können. Ohne die Zeit für Gerippe zu verlieren. Aber Scheduler kann genau so gut auch mit STM32 arbeiten. Das ist ja C.
:
Bearbeitet durch User
>Kriegt man es nicht hin so ein paar Prozesse ohne Wartezyklen parallel laufen zu
lassen?
Ein Scheduler ist praktisch wenn man zyklisch mehrere Aufgaben
quasi-parallel erledigen will ... was ja der Sinn eines Controllers ist
(zyklisch Eingaben abfragen, Daten holen/ablegen, .. )
Nicht nur einfach zyklisch. Man kann aus einer Aufgabe eine andere mit Verzögerung rufen und somit komplizierte Abhängigkeiten schaffen. Hauptidee: die Zeit für delay nicht verschwenden. Im Vergleich mit Flag-Automat ist Scheduler weniger problematisch, wenn eine oder andere Aufgabe zufällig mehr Zeit braucht, als zwischen Timer-Interrupts bleibt.
:
Bearbeitet durch User
Maxim B. schrieb: > Nicht nur einfach zyklisch. Man kann aus einer Aufgabe eine andere mit > Verzögerung rufen und somit komplizierte Abhängigkeiten schaffen. Genau das ist es - die Leute denken zu kompliziert. Dann braucht man auch keinen Scheduler.
... scheduler habe ich verschiedene auf avr/pic/stm zu laufen und finde es auch oft sinnig, aber richtig "böse" finde ich immer noch 1. viele triviale kommentare ohne informationsgehalt, anstatt vielsagende bezeichner zu verwenden! 2. immer und immer wieder klammern zu setzen, auch wenn da keine sein müssen - ein unding! 3. die redundante programmierung, sprich copy&paste oder basteln! eins von vielen beispielen; lcd.c function //original void lcd_string_P( PGM_P data ) { u8 tmp; tmp=pgm_read_byte(data); while( tmp != '\0' ) { lcd_data( tmp ); data++; tmp = pgm_read_byte(data); } } //mein zweizeiler aus der pistole in 3sec void lcd_puts_p(PGM_P sp) { uint8_t s; while (s=pgm_read_byte(sp++), s) lcd_data(s); } mt p.s. der hier gezeigte "scheduler" verdient den namen NICHT!
Albert schrieb: > OT: Es ist mir immernoch schleierhaft, warum man auf einem 8bit > Prozessor einen Scheduler braucht? Seit wann ist es verboten, sich auch auf 8-Bittern die Arbeit zu erleichtern? Ich benutze einen Scheduler in fast allen Projekten, sobald etwas verzögert ausgeführt werden muß. Das erspart einem, jedesmal extra Zählschleifen hinschreiben zu müssen. Hier mal meine Version. Die Idee mit der sortierten Liste ist aber nicht von mir. Beitrag "Wartezeiten effektiv (Scheduler)"
Danke Peter, dass Du dein Projekt hier noch mal verlinks. Ich verwende deinen Scheduler (peda) auch meinen Projekten und kann ihn mit der Tastenentprellung (peda) nur empfehlen.
Apollo M. schrieb: > 2. immer und immer wieder klammern zu setzen, auch wenn da keine sein > müssen - ein unding! Ich bin anderer Meinung. Die Klammer kosten nichts. Aber unter bestimmten Umständen können sie viel Ärger sparen. Apollo M. schrieb: > 1. viele triviale kommentare ohne informationsgehalt, anstatt > vielsagende bezeichner zu verwenden! Lieber zu viel als zu wenig. Sonst vergesse ich bald selber, was und warum so und nicht anders. Zeitverschwendung, ohne Kommentare zu schreiben. Wer aber besser ohne Kommentare lebt, der darf sie natürlich löschen. So oder so, das Ding funktioniert. Man kann das natürlich auch besser machen...
1 | //original
|
2 | void lcd_string_P( PGM_P data ) { |
3 | u8 tmp; |
4 | |
5 | tmp=pgm_read_byte(data); |
6 | while( tmp != '\0' ) { |
7 | lcd_data( tmp ); |
8 | data++; |
9 | tmp = pgm_read_byte(data); |
10 | }
|
11 | }
|
12 | |
13 | //mein zweizeiler aus der pistole in 3sec
|
14 | void lcd_puts_p(PGM_P sp) { |
15 | uint8_t s; |
16 | while (s=pgm_read_byte(sp++), s) |
17 | lcd_data(s); |
18 | }
|
Kannst du bitte erklären, welche Vorteile deine Schreibweise hat? Du hast ein paar Zeilen weniger. Was hast du gespart? Papier? Geld? CO2? Apollo M. schrieb: > 3. die redundante programmierung, sprich copy&paste oder basteln! Für mich hat Verständlichkeit höchsten Wert. Wenn das ein paar Zeilen mehr bedeutet, so muß das sein. Apollo M. schrieb: > p.s. der hier gezeigte "scheduler" verdient den namen NICHT! Egal wie das heißt. Hauptsache, das Ding arbeitet wie soll.
:
Bearbeitet durch User
Albert schrieb: > Genau das ist es - die Leute denken zu kompliziert. Dann braucht man > auch keinen Scheduler. Ja, früher habe ich das auch ohne gemacht. Für LED blinken je LED ein Programmtimer. Für Tastenabfrage je Taste ein Programmtimer :) Ja, so kann das auch funktionieren. Das Problem kommt erst wenn man nach einem Jahr etwas zu ändern hat. Einmal wollte ich genau sehen, was per MIDI übertragen wird. Es kam immer wieder zu Verschlucken von MIDI-Code. Na ja, habe ich gedacht: AVR sei sicher zu langsam :) In Wirklichkeit war Problem natürlich nicht in AVR...
:
Bearbeitet durch User
Maxim B. schrieb: > Kannst du bitte erklären, welche Vorteile deine Schreibweise hat? > Du hast ein paar Zeilen weniger. Was hast du gespart? Papier? Geld? CO2? ... ich bin zwar nicht der Author des Zweizeilers, aaaaber: deine Version produziert zweimal Code für den Zugriff auf das Flash, der Zweizeiler nur einmal (der Zweizeiler gefällt mir aber dennoch nicht so sehr). "Deine" Schleife wäre besser in einer do .. while Schleife aufgehoben (um eben nur einmal Code für Flashzugriff zu generieren...
Ralph S. schrieb: > deine > Version produziert zweimal Code für den Zugriff auf das Flash, der > Zweizeiler nur einmal (der Zweizeiler gefällt mir aber dennoch nicht so > sehr). Du wirst sicher lachen: ich habe jetzt ausprobiert, das Programm mit meiner Variante 2 bytes kleiner, als von Apollo M ... Compiler optimiert alles, man sollte oft einfach ausprobieren... Also, meine Variante ist ein bißchen kürzer, aber das ist eigentlich egal. Übrigens, Gerechtigkeit halber: die Variante ist nicht meine. Ich habe nach diesem Muster auch ähnliche Funktion für Arbeit über Puffer gemacht. Interessant ist Listing zu sehen: erste ist "meine".
1 | 2f2: cf 93 push r28 |
2 | 2f4: df 93 push r29 |
3 | 2f6: ec 01 movw r28, r24 |
4 | 2f8: fe 01 movw r30, r28 |
5 | 2fa: 84 91 lpm r24, Z |
6 | 2fc: 88 23 and r24, r24 |
7 | 2fe: 21 f0 breq .+8 |
8 | 300: 0e 94 ea 00 call 0x1d4 |
9 | 304: 21 96 adiw r28, 0x01 |
10 | 306: f8 cf rjmp .-16 |
11 | 308: df 91 pop r29 |
12 | 30a: cf 91 pop r28 |
13 | 30c: 08 95 ret |
14 | |
15 | |
16 | 2f2: cf 93 push r28 |
17 | 2f4: df 93 push r29 |
18 | 2f6: fc 01 movw r30, r24 |
19 | 2f8: 84 91 lpm r24, Z |
20 | 2fa: ef 01 movw r28, r30 |
21 | 2fc: 21 96 adiw r28, 0x01 |
22 | 2fe: 88 23 and r24, r24 |
23 | 300: 21 f0 breq .+8 |
24 | 302: 0e 94 ea 00 call 0x1d4 |
25 | 306: fe 01 movw r30, r28 |
26 | 308: f7 cf rjmp .-18 |
27 | 30a: df 91 pop r29 |
28 | 30c: cf 91 pop r28 |
29 | 30e: 08 95 ret |
So oder so, es kommt nur einmal lpm. Compiler optimiert alles gut.
:
Bearbeitet durch User
Spätestens seit dem SSL Bug sollte jeder wissen, dass man in Programmiersprachen wie C niemals auf Klammern verzichten sollte. Eben mal lcd_data durch ein kompliziertes Macro ersetzt und schon ist alles kaputt. Gruß Sven
... programmieren hat auch was mit ästhetik zu tun, der hier gezeigte code ist typisch für halbwissende, wenn ihr solchen code irgendwo zeigt könnt ihr gleich wieder nach hause gehen! UND einzeilige if/else anweisungen immer schön brav zu klammern ist klippschule und verbessert wohl kaum die lesebarkeit, aber pumpt das listing auf! // Sendet eine 4-bit Ausgabeoperation an das LCD static void lcd_out( u8 data ) { lcd_dataline_null(); if (data & 0x10) LCD_PORT_DB4 |= (1<<LCD_DB4); if (data & 0x20) LCD_PORT_DB5 |= (1<<LCD_DB5); if (data & 0x40) LCD_PORT_DB6 |= (1<<LCD_DB6); if (data & 0x80) LCD_PORT_DB7 |= (1<<LCD_DB7); lcd_enable_puls(); } // Sendet eine 4-bit Ausgabeoperation an das LCD static void lcd_out( u8 data ) { lcd_dataline_null(); if (data & 0x10){ LCD_PORT_DB4 |= (1<<LCD_DB4); } if (data & 0x20){ LCD_PORT_DB5 |= (1<<LCD_DB5); } if (data & 0x40){ LCD_PORT_DB6 |= (1<<LCD_DB6); } if (data & 0x80){ LCD_PORT_DB7 |= (1<<LCD_DB7); } lcd_enable_puls(); } genauso wenig wie kommentare dieser art ... außer man "spricht" die sprache garnicht wdt_reset(); // Watchdog auf Null UND auch mal coding styles lesen, damit mal kappiert wird wo/wo nicht leerzeichen hingehören wenn schon dann eher so das ganze ... void lcd_string_P(PGM_P data) { u8 tmp = pgm_read_byte(data); while (tmp != 0) { lcd_data(tmp); tmp = pgm_read_byte(++data); } } UND auch mal über konsistenz im coding nachdenken - der code ist VOLL von inkonsistenz z.b. die function vor lcd_string_P() incrementiert den data pointer ganz normal im parameter feld, also hatte dort der to noch keine "leseschwäche wie behauptet" aber '\0' anstatt 0 ist immer dumm void lcd_string( u8 *data ) { while( *data != '\0' ) lcd_data( *data++ ); } Maxim B. schrieb: > ich habe jetzt ausprobiert, das Programm mit meiner Variante 2 bytes > kleiner, als von Apollo M ... kann ich nicht bestätigen, sondern umgekehrt! mit gcc v8.2 und -Os //mein zweizeiler aus der pistole in 3sec void lcd_puts_p(PGM_P sp) { uint8_t s; while (s=pgm_read_byte(sp++), s) 96: fc 01 movw r30, r24 98: 24 91 lpm r18, Z 9a: 01 96 adiw r24, 0x01 ; 1 9c: 21 11 cpse r18, r1 9e: fb cf rjmp .-10 ; 0x96 <lcd_puts_p> lcd_data(s); } a0: 08 95 ret //original void lcd_string_P( PGM_P data ) { uint8_t tmp=pgm_read_byte(data); while (tmp != 0) { lcd_data( tmp ); tmp = pgm_read_byte(++data); 96: fc 01 movw r30, r24 98: 24 91 lpm r18, Z while (tmp != 0) { 9a: 21 11 cpse r18, r1 9c: 01 c0 rjmp .+2 ; 0xa0 <lcd_string_P+0xa> } } 9e: 08 95 ret tmp = pgm_read_byte(++data); a0: 01 96 adiw r24, 0x01 ; 1 a2: f9 cf rjmp .-14 ; 0x96 <lcd_string_P> mt
... meine buchempfehlung für jene die c-programmierung wirklich mal lernen wollen und "hart" genug sind, weil starker tabak wenn man dann schrittweise kapiert, dass man eigentlich gar keine ahnung von der sprache hatte! Schellong, Moderne C-Programmierung dann lernt ihr z.b. auch was ko-logik in c-programmierug bedeutet und was man damit alles machen kann ... liegt auch als pdf im web rum! mt
:
Bearbeitet durch User
Apollo M. (Firma: @home) (majortom) >... programmieren hat auch was mit ästhetik zu tun, der hier gezeigte >code ist typisch für halbwissende, wenn ihr solchen code irgendwo zeigt >könnt ihr gleich wieder nach hause gehen! Wenn Du jetzt noch lernst, beim posten die Code-Tags zu setzen, damit das "Syntax-Highlighting" funktioniert, dann wird auch Dein Code noch schöner. Die Form von Code hat immer was mit dem eigenen Stil zu tun und ich habe noch keinen Code gesehen, an dem ich nichts kritisieren könnte.
Apollo M. schrieb: > ... programmieren hat auch was mit ästhetik zu tun, der hier gezeigte > code ist typisch für halbwissende, wenn ihr solchen code irgendwo zeigt > könnt ihr gleich wieder nach hause gehen! Ich glaube nicht, daß dieses Forum nur für Profis gedacht ist, daher muß man nicht gleich alle Leute anpissen, die hier was veröffentlichen. Man kann Tipps geben, dann aber bitte in freundlichem Ton.
Maxim B. schrieb: >> 1. viele triviale kommentare ohne informationsgehalt, anstatt >> vielsagende bezeichner zu verwenden! > > Lieber zu viel als zu wenig. Sonst vergesse ich bald selber, was und > warum so und nicht anders. Zeitverschwendung, ohne Kommentare zu > schreiben. “Every time you write a comment, you should grimace and feel the failure of your ability of expression.” ― Robert C. Martin, The Robert C. Martin Clean Code Collection (Collection)
>“Every time you write a comment, you should grimace and feel the failure >of your ability of expression.” >― Robert C. Martin, The Robert C. Martin Clean Code Collection >(Collection) Dem stimme ich zu hundert Prozent zu: Code muss so geschrieben sein, dass Kommentare überflüssig sind. Das Problem: Code und Kommentare laufen mit der Zeit immer auseinander. Also: Kommentare weg, Code verbessern !
Marc schrieb: > Das Problem: Code und Kommentare laufen mit der Zeit immer auseinander. Genau. Natürlich hat Uncle Bob auch dazu was schlaues gesagt: “Redundant comments are just places to collect lies and misinformation.”
Peter D. schrieb: > Ich glaube nicht, daß dieses Forum nur für Profis gedacht ist, daher muß > man nicht gleich alle Leute anpissen, die hier was veröffentlichen. Danke! Ich bin natürlich kein Profi, ich verdiene mein Gehalt anders. Was aber meine Kommentare angeht: einmal früher habe ich bemerkt, daß ich kaum noch verstehe, was ich vor einem Jahr geschrieben habe. Seit dem schreibe ich möglichst viele Kommentare. Wenn einem oder anderem Profi das nicht gefällt... Na, man kann nicht für allen gut sein, leider... :) Kommentare schreibe ich FÜR MICH. Übrigens, wie ich am Anfang schon geschrieben habe: es geht hier um rtos.h und rtos.c. Alles andere ist nur als Zugabe zu betrachten, die alles etwas verständlicher macht. Stattdessen wird hier aus irgendwelchem Grund nur über meine Variante von lcd.h - lcd.c diskutiert (die übrigens nach Anregung von Ihnen, Herr Dannegger, gemacht wurde. Danke noch mal für Tipps!). lcd.h - lcd.c funktioniert genau wie ich möchte. Ich habe dort seit langer Zeit fast nichts geändert. Ich mache nur Anpassungen bei Pin-Def, je nach der Platte. Einziges, was mir im Moment noch als fehlerhaft erscheint: in Puffer-Mode möchte ich gerne auch blinkende Zeichen ermöglichen. Darüber muß ich noch überlegen. Auch bessere Zusammenspiel mit rtos wäre gut. Hier gab es noch von Apollo M. ein Tipp, ein Buch zu lesen: "Schellong, Moderne C-Programmierung". Leider muß ich sagen, daß dieses Buch, wie auch viele anderen, gleiche Nachteil hat: zu oberflächlich. Viele Fragen und Momente sind entweder nicht ausreichend erklärt oder gar nicht erwähnt. Deshalb bin ich eigentlich hier in Forum (und nicht nur hier). Viele Grüße!
:
Bearbeitet durch User
Maxim B. schrieb: > Was aber meine Kommentare angeht: einmal früher habe ich bemerkt, daß > ich kaum noch verstehe, was ich vor einem Jahr geschrieben habe. Seit > dem schreibe ich möglichst viele Kommentare. Wenn einem oder anderem > Profi das nicht gefällt... Na, man kann nicht für allen gut sein, > leider... :) Nun du könntest aber Vorschläge trotzdem annehmen. Und der Vorschlag ist klar: Schreibe besseren Code.
Apollo M. schrieb: > //original > void lcd_string_P( PGM_P data ) { > uint8_t tmp=pgm_read_byte(data); > while (tmp != 0) { > lcd_data( tmp ); > tmp = pgm_read_byte(++data); > 96: fc 01 movw r30, r24 > 98: 24 91 lpm r18, Z > while (tmp != 0) { > 9a: 21 11 cpse r18, r1 > 9c: 01 c0 rjmp .+2 ; 0xa0 <lcd_string_P+0xa> > } > } > 9e: 08 95 ret > tmp = pgm_read_byte(++data); > a0: 01 96 adiw r24, 0x01 ; 1 > a2: f9 cf rjmp .-14 ; 0x96 <lcd_string_P> Lieber Herr Apollo M., das ist nicht mein Code! Mein ist etwas anders:
1 | tmp = pgm_read_byte(++data); |
gibt es in meinem Code nicht! So kleine Unterschiede machen schon große Unterschiede bei Optimieren von Compiler. Deshalb passen Sie bitte auf, was Sie schreiben!
:
Bearbeitet durch User
Karl M. schrieb: > Danke Peter, > > dass Du dein Projekt hier noch mal verlinks. > Ich verwende deinen Scheduler (peda) auch meinen Projekten und kann ihn > mit der Tastenentprellung (peda) nur empfehlen. Hast Du keine Angst, dass Du auf deinen Schleimspur ausrutschst?
Cyblord -. schrieb: > Und der Vorschlag ist klar: Schreibe besseren Code. Sage ich etwas dagegen? Aber in der Funktion, über die Herr Apollo M. schrieb, scheint meine Variante eher besser zu sein, als seine. Außerdem hat er mich nicht überzeugt, wie er schrieb, man brauche wenige Klammern. Ich habe in der Literatur genau Gegenteil gelesen: man mache lieber zu viel Klammern als zu wenig. Und auch in der Literatur gibt es Erklärungen, warum.
Apollo M. schrieb: > dann lernt ihr z.b. auch was ko-logik in c-programmierug bedeutet und > was man damit alles machen kann ... Das gleiche, was alle anderen unter Short-Circuit-Evaluation verstehen und was viele andere Sprachen auch können? Wieder was gelernt!
Dr. Sommer schrieb: > Apollo M. schrieb: >> dann lernt ihr z.b. auch was ko-logik in c-programmierug bedeutet und >> was man damit alles machen kann ... > > Das gleiche, was alle anderen unter Short-Circuit-Evaluation verstehen > und was viele andere Sprachen auch können? Wieder was gelernt! Der Herr Apollo M. ist das Programmiereräquivalent der üblichen und verhassten Rechtschreibfanatiker. Es mag ja stimmen, dass man Code besser schreiben kann (speziell C ist da ja sehr "variabel") Aber hier kam nur Herumgemäkle an Kleinigkeiten, und nichts substantielles. Leute wie dieser "Apollo M." machen dieses Forum so unangenehm...
Apollo M. schrieb: > // Sendet eine 4-bit Ausgabeoperation an das LCD > static void lcd_out( u8 data ) { > lcd_dataline_null(); > if (data & 0x10) LCD_PORT_DB4 |= (1<<LCD_DB4); > if (data & 0x20) LCD_PORT_DB5 |= (1<<LCD_DB5); > if (data & 0x40) LCD_PORT_DB6 |= (1<<LCD_DB6); > if (data & 0x80) LCD_PORT_DB7 |= (1<<LCD_DB7); > lcd_enable_puls(); > } Was bitte ist das denn? Wer kommt hier auf die Idee jedes Bit einzeln zu setzen?
1 | LCD_PORT &= 0x0F; // Pins low |
2 | LCD_PORT |= data & 0xF0; //high Nibble setzen |
Karl K. schrieb: > Was bitte ist das denn? Wer kommt hier auf die Idee jedes Bit einzeln zu > setzen? Wahrscheinlich der Gleiche, der die Zuordung der Bits zu den Portbits maximal variabel halten wollte. Wo liegt das Problem? Die 3us CPU-Laufzeit? > LCD_PORT &= 0x0F; // Pins low > LCD_PORT |= data & 0xF0; //high Nibble setzen Nö, das geht nur bei eingeschränker Zuordung der Bits am Port.
Marc schrieb: > Dem stimme ich zu hundert Prozent zu: Code muss so geschrieben sein, > dass Kommentare überflüssig sind. Es ist immer leichter, Dogmen aufzustellen, als sie auch einzuhalten. Wenn es so leicht wäre, gäbe es die Kommentarfunktion ja nicht. Ich schreibe lieber mal einen Kommentar, als 80 Zeichen lange Funktions- und Variablennamen. Die Vergabe von beschreibenden Namen ist ein wirklich schweres Thema. Ich möchte nicht deutlich länger an der Namensvergabe grübeln, als an dem eigentlichen Code. Marc schrieb: > Das Problem: Code und Kommentare laufen mit der Zeit immer auseinander. Aber auch Namen können veralten, wenn man eine Funktion verändert, z.B. wenn ich eine Funktion universeller mache oder etwas daraus in eine Unterfunktion auslagere. Was ich extrem unleserlich finde, ist CamelCase. Ich benutze immer den Unterstrich als Trenner in einem Namen.
:
Bearbeitet durch User
Falk B. schrieb: > Wahrscheinlich der Gleiche, der die Zuordung der Bits zu den Portbits > maximal variabel halten wollte. Genau deshalb. Zuerst machte ich mit Def. drei Varianten: alles auf einem Port, Data auf einem und E und RS auf einem anderen Port, und völlig frei. Aber am Ende habe ich nur die freie Variante gelassen. Zeitunterschiede gegen anderen Varianten sind unbedeutend. Aber die Platte kann viel bequemer gemacht werden. Alles, was nicht für andere Funktionen gebraucht wird, kann für LCD benutzt werden.
Ich versuche mich in Namen nach meinen Regeln zu halten: falls ich das nicht vergesse, mache ich immer Prefix mit Filename und Unterstrich. Z.B. void indikator_schreib_ind_puff(u8 a,u8 b,u8 c,u8 d) befindet sich in indikator.c. Es sei denn, ich benutze Bibliothek von anderen.
Falk B. schrieb: > Die 3us > CPU-Laufzeit? Ist zehnmal so lang wie das nötige Write Enable von 300ns.
Karl K. schrieb: > Ist zehnmal so lang wie das nötige Write Enable von 300ns. Das ist sehr wichtig, wenn zu berücksichtigen, daß E etwa 500 ns braucht und zwischen Befehlen ca. 40-50 us zu warten ist :) Ich habe übrigens gekuckt: lcd_out( data ); zusammen mit lcd_enable_puls(); 500 ns braucht ca. 3,3 us (mit F_CPU = 16 MHz).
:
Bearbeitet durch User
Maxim B. schrieb: > Das ist sehr wichtig, wenn zu berücksichtigen, daß E etwa 500 ns braucht > und zwischen Befehlen ca. 40-50 us zu warten ist :) Wenn man linear programmiert freilich nicht. Wenn man einen Displaybuffer verwendet und der µC zwischendrin was anderes machen kann, braucht es Zehnmal so lange. Das ist so typisch Arduino-Programming: starte die Messung - delay(1000) - lese den Messwert. Und dann rumheulen: Mein µC ist zu langsam, ich brauch einen schnelleren µC.
>Was ich extrem unleserlich finde, ist CamelCase. Ich benutze immer den >Unterstrich als Trenner in einem Namen. Das fand ich am Anfang auch, aber ich habe eine Zeitlang Java gemacht und dort ist es Standard. Deshalb habe ich mich auf die Konvention "CamelCase" auch für C geeinigt. Mit der Zeit gewöhnt man sich dran. oderEtwaNicht ? ;-)
Karl K. schrieb: > Wenn man einen > Displaybuffer verwendet und der µC zwischendrin was anderes machen kann, > braucht es Zehnmal so lange. Stimmt schon. Aber da ich PCB selber mache, ist für mich die Möglichkeit, PINs frei bestimmen zu dürfen, am wichtigsten. Übrigens, die Ausgabe kann man sehr leicht ändern, wenn man will. Statt
1 | |
2 | static void lcd_out( u8 data ) { |
3 | lcd_dataline_null(); |
4 | if (data & 0x10){ |
5 | LCD_PORT_DB4 |= (1<<LCD_DB4); |
6 | }
|
7 | if (data & 0x20){ |
8 | LCD_PORT_DB5 |= (1<<LCD_DB5); |
9 | }
|
10 | if (data & 0x40){ |
11 | LCD_PORT_DB6 |= (1<<LCD_DB6); |
12 | }
|
13 | if (data & 0x80){ |
14 | LCD_PORT_DB7 |= (1<<LCD_DB7); |
15 | }
|
16 | lcd_enable_puls(); |
17 | }
|
kommt
1 | |
2 | static void lcd_out( u8 data ) { |
3 | LCD_PORT &= 0x0f; |
4 | LCD_PORT |= (data & 0xf0); |
5 | lcd_enable_puls(); |
6 | }
|
. Statt 50 Cycle wird 28. Statt 3,125 us wird 1,75 us. Hilft das viel?
Peter D. schrieb: > Es ist immer leichter, Dogmen aufzustellen, als sie auch einzuhalten. Dogma: Schreibe, in den Kommentaren warum du etwas so tust. Nicht, was du tust, denn das steht schon im Code.
Karl K. schrieb: > Wenn man einen > Displaybuffer verwendet und der µC zwischendrin was anderes machen kann, > braucht es Zehnmal so lange. Wenn das irgendwie nicht bemerkt wurde: LCD-Puffer wird nur jede 1 ms bedient. Auch für 4x20 LCD bedeutet das nur 84 ms, das ist für Auge kaum zu merken. Die Auslastung für LCD wird: so wie das steht: 7/1000=0,7% (nur während Kopierens, danach nicht mehr). Alles auf einem Port: 3,5/1000=0,35%. Ist das wirklich so kritisch?
:
Bearbeitet durch User
... so da habe ich ja den finger richtig in die wunden gelegt, aber wir können alle zufrieden sein, da an den comments offensichtlich wird, dass hier einige noch mitdenken. der hier gezeigte code ob mit sinnige oder unsinnige comennts wird jede wette, keiner von uns nach kurzer zeit noch verstehen und darum gings mir! dieser code hier hat leider nur unqualität, lese doch mal bitte jemand rtos.c/rtos.h und erkläre mir was das rtos.x hier zum scheduler macht und wo es klemmt und z.b. welchen sinn die parameter "// die Aufgaben bekommen je 3 Parameter: u16,s16,u8" haben, scheduler principle? round robin, preemptive ...? nichts davon offenbart dieser code müllberg! ich erkenne noch nicht einmal elementare queue functions - liegt aber bestimmt an meiner sonnenbrille?! bevor man irgend eine aufgabe dieser art angeht sollte mann/frau erstmal grundsätzliche dinge darüber lesen und ein grundsätzliches verständnis erlangen, und bitte auch die richtigen begrifflichkeiten verwenden. hier http://www.cocoos.net/intro.html da könnt ihr euch mal die finger ablecken, an dem beispiel wie ein sehender das macht. aber vorsicht, dass ist richtig viel arbeit, und studiert doch mal den code dazu, dann lernt ihr auch was dazu - ich habe das bereits hinter mir! dick unterstrichen, eine der schwierigsten aufgaben, ist die namensgebung von functions, variabeln ... ob mit suffix/prefix, unterschrich, camel style, gross/klein, ... um eine logische strukture des systems gut lesbar abzubilden. diese aufgabe hat der to weder erkannt noch ansatzweise hinbekommen. wenn wir hier nicht unter beobachtung wären, dann würde ich euch mal ein paar gute pdf bookz zu embedded rtos hochladen, aber auch die muss man selber lesen. ... und leider, die werden ja gleich wieder hier gelöscht! einfach nur zum abtörnen ... was soll das, äh? //rtos.c /********************************************************/ /*** Fuer Ringpuffer TaskQueue *************************/ /********************************************************/ static u8 task_count = 0; static u8 task_schwanz = 0; static u8 task_kopf = 0; static void task_count_inc(u8 *count, u8 max_wert){ (*count)++; if(*count >= max_wert){ *count = 0; } } mt
Apollo M. schrieb:
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Kannst Du das nicht oder bist Du überfordert?
Apollo M. schrieb: > dieser code hier hat leider nur unqualität Apollo M. schrieb: > nichts davon offenbart dieser code müllberg! Apollo M. schrieb: > diese aufgabe hat der to weder erkannt noch ansatzweise hinbekommen. Apollo M. schrieb: > bevor man irgend eine aufgabe dieser art angeht sollte mann/frau erstmal > grundsätzliche dinge darüber lesen und ein grundsätzliches verständnis > erlangen, und bitte auch die richtigen begrifflichkeiten verwenden. Apollo M. schrieb: > einfach nur zum abtörnen ... was soll das, äh? Kann bitte die Moderation hier eingreifen? Ich denke, an dem gesamten Beitrag ist nichts konstruktives, dafür aber vieles, was zumindest an Beleidigungen grenzt. Mich stört es, und mich interessiert die ursprüngliche Diskussion zumindest als Mitleser.
Säbelzahm schrieb: > Wichtige Regeln - erst lesen, dann posten! > > Groß- und Kleinschreibung verwenden ... ich bin nicht regelgläubig, das ist eher was für katholiken, andere leichtgläubige, arduino jünger oder was für das breite mittelmass das sich hier tummelt!
jemand schrieb: > Ich denke, an dem gesamten Beitrag ist nichts konstruktives, dafür aber > vieles, was zumindest an Beleidigungen grenzt. du wohnst auf eine ponnyhof, richtig? bist wahrscheinlich blind und beschwerst dich gerne regelmäßig über zuviel/zuwenig sonnenschein?! wenn ein blinder einen blinden hilft, dann fallen beide in die grube! das wäre dann wohl für kleingeister immer eine beleidigung, habe ich das richtig verstanden? mt
Apollo M. schrieb: > wenn ein blinder einen blinden hilft, dann fallen beide in die grube! > das wäre dann wohl für kleingeister immer eine beleidigung, habe ich das > richtig verstanden? Ja, so ist das. Dein Wunsch, auf Klammer zu verzichten, macht Verdacht nahe, du bist ja auch kein Profi, wie?
Apollo M. schrieb: > hier http://www.cocoos.net/intro.html da könnt ihr euch mal die finger > ablecken, an dem beispiel wie ein sehender das macht. Nunja... Da scheint jemand den Präprozessor sehr zu lieben. Kennt aber nichtmal den do-while-"Trick":
1 | #define os_assert( test ) if ( !(test) ) {\
|
2 | os_on_assert(__LINE__);\
|
3 | }
|
Explizites Padding? Ernsthaft?
1 | typedef struct { |
2 | uint8_t signal; |
3 | uint8_t reserved; /* Alignment byte */ |
4 | uint8_t pad0; |
5 | uint8_t pad1; |
6 | uint16_t delay; /* Delay of posting in ticks */ |
7 | uint16_t reload; /* Reload value for periodic messages */ |
8 | } Msg_t; |
Überall nur uint8_t, uint16_t ... verwendet, keine sprechenden Aliase wie pid_t oder time_t ... Jetzt irgendwie nicht so der Wahnsinn.
Dr. Sommer schrieb: > Überall nur uint8_t, uint16_t ... verwendet, keine sprechenden Aliase > wie pid_t oder time_t ... Jetzt irgendwie nicht so der Wahnsinn. da bin ich bei dir! @pid_t oder time_t, chibios kommt dir da mehr entgegen und läuft auch auf avr und small 328p Dr. Sommer schrieb: > Nunja... Da scheint jemand den Präprozessor sehr zu lieben. Kennt aber > nichtmal den do-while-"Trick": der präprozessor ist ein wesentlicher teil der sprachdefinition von c, die meisten rtos setzen entsprechende macros daher massiv ein, weil so recht flexible das rtos configuriert werden kann.z.b. werden dann gerne verschiedene dispatcher, dynamische/statische timer handler, ... zur auswahl gestellt. code macros in header files, ob mit oder ohne do{...}while(0) kapselung sind standard in der landschaft, macros haben vor- und nachteile, ich selber benutze sie häufig, anfänger sind regelmäßig darüber befremdet ... ich habe hier einige rtos quellen rumliegen und jede hat irgendwas besonderes gemacht, z.b. rtos für pic12/16 ist was anderes als für pic18/24/32 oder arm/avr. ich kenne auch ein rtos wo jede task als eigene isr läuft einschliesslich dem dispatcher - interessanter ansatz, wenn kein richtiger sw stack existiert, wie bei pic16. mt
Apollo M. schrieb: > der präprozessor ist ein wesentlicher teil der sprachdefinition von c, Ja leider. Den sollte man so sparsam wie möglich einsetzen, und so viel wie möglich mit (Inline-) Funktionen machen. In C++ geht das noch deutlich besser. In beispielhaft gutem Code sollten jedenfalls nicht wesentlich mehr Makros als die Include-Guards auftauchen...
Maxim B. schrieb: > Säbelzahn schrieb: > die Programme und die Ideen von > Anderen. > > Sollte ich Fahrrad selbst erfinden? > Selbst in Datenblatt stehen Programmbeispiele. Nicht benutzen? > > Autoren von Ideen habe ich genannt, noch eigene Ideen dazu gebracht... > Hoffentlich etwas brauchbares bekommen. Ich habe schon mit Scheduler > (aber die Variante ohne Variablen) ein Ding gemacht. > > Selbst J.S.Bach, mein Kollege aus Leipzig, hat die Tonleiter nicht > selber erfunden. Nicht gut deutsch dies Depp.
@Sommer & Apollo Habt es ihr schon gemerkt, dass ihr beiden euch über die Programmierung eines Schedulers so unterhaltet, wie zwei Jungfrauen über Gruppensex? Weder ihr noch die wissen wovon sie reden.
Säbelzahn schrieb: > Weder ihr noch die wissen wovon sie reden. Dafür kenn ich mich mit Gruppensex aus ¯\_(ツ)_/¯
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.