Datum:
Angehängte Dateien:Hallo Nutzerinnen und Nutzer ;) Ich habe ein eigenes OS für AVR Mikrocontroller geschrieben, dass ich euch hiermit (inkl. Sourcecode) zur Verfügung stellen möchte. Ich habe es Nano OS getauft. Es beinhaltet folgende Features: -preemptives Multitasking inkl. Prioritäten, -binäre Semaphore (Mutex), -Message Queues, -ein einfaches Speichermanagement (basiert auf einem array im RAM) sowie -Funktionen zur Task-Kontrolle (anhalten, löschen usw...) Die einzelnen Funktionewn sind im Quelltext dokumentiert. Das zip beinhaltet folgende Files: /software/nano_os.c - Das main-File /software/system/header/nano_os.h - die zentrale Konfigurationsdatei /software/system/idle.c - den idle-task /software/system/kernel.c - den "kernel" /software/system/memory.c - das Speichermanagement /software/system/message.c - die Message Queue /software/system/scheduler.c - den Scheduler /software/system/tasks.c - die Task-Steuerung /software/user/user.c - die Usersoftware /software/user/user.h - das header-file für die User-Software Das OS ist im Rahmen einer Diplomarbeit entstanden, die hier leider nicht veröffentlicht werden kann. Es wurde entwickelt auf einem AtMega 168; Für andere Prozessoren muss das File nano_os.h angepasst werden. Die Dokumentation des APIs findet sich in den einzelnen Dateien; als User-Software ist eine Binäruhr für einen Atmel AtMega 168 dabei, die die Uhrzeit über PORTC und PORTD ausgibt. Der Schaltplan der Hardware im eagle-Format liegt bei. Mich interessiert insbesondere das Feedback. Also viel Spass mit dem OS, in dem sicher noch viele Fehler zu finden sind ;) Fragen werden gern angenommen. gruß tobi
Datum:
Gefällt mir, werd ich mal ausprobieren. :) Unter welcher Lizenz veröffentlichst du den Code? BSD wär nett, muss aber nich. :) Auch als Hobbyist will ich vor Überraschungen gefeit sein. Ausserdem weiss ich ja nie wann ich das wieder mal brauche und allenfalls ganz "legal" auf offenen/freien Code zurückgreifen kann. Oder nach Herzenslust rumhacken und nicht gezwungen bin, meinen Code wieder offen zu legen, wenn ich dereinst eine Kleinserie an WallClocks verticke. ;)
Datum:
> Für andere Prozessoren muss > das File nano_os.h angepasst werden. Wenn ich das richtig sehe dann doch wohl auch scheduler.c weil dort ein paar sehr prozessorspezifische Annahmen gemacht werden und es sogar Assemblercode gibt. Olaf
Datum:
@Tom: Das ganze veröffentliche ich unter GNU GPL. Du kannst den Code also gern verwenden, und auch weitergeben. Solltest du den Code des OS selbst verändern, wäre eine Meldung (hacker-tobi@gmx.net) nicht schlecht. Die user - Software ist hiervon ausgenommen. Lese ich das richtig...du baust Uhren ? Genau dafür ist dieses OS geschrieben worden ;) Ich baue hauptsächlich Multifunktions-Uhren mit AVR-Controllern, und daher kam die Idee, einige immer wiederkehrende Themen zusammenzufassen, und ein OS draus zu gießen. Hauptthemen waren dabei: -Verschiedene Aufgaben (z.B. Display-Steuerung, Auslesen von Sensoren) mit verschiedenen Prioritäten erledigen zu können, -einheitliche Kommunikationswege zu schaffen und -das ganze noch auf schwere Ausnahmefehler zu überwachen. @Olaf: Jain ;) Wenn du das System für andere Prozessoren anpassen willst, müsstest du die Scheduler.c anpassen. Und auch andere Teile des Codes, welche avr-gcc - spezifische Makros verwenden, müssten angepasst werden. Wenn man in der Atmega - Familie bleibt, dann reicht es jedoch, die Parameter in nano_os.h anzupassen. gruß tobi
Datum:
Da Du zu beginn bei scheduler() die Register selber sicherst, müsste man da nicht den GCC ein Attribut setzten, dass er das nicht macht? Quasi so:
void scheduler() __attribute__ ((naked)); void scheduler() { ... } |
GCC Function-Attributes http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
Datum:
Hallo Mario, nein, denn ich sichere die Register nicht! auf den Stack, sondern in die Task-Struktur, genauer in das für diesen Zweck vorhandene Array. Es wäre evtl. noch als Ergänzung möglich, um dem gcc etwas Arbeit zu ersparen, das muss ich mal testen. aber es "geht" auch so. gruß tobi
Datum:
hacker-tobi schrieb: > nein, denn ich sichere die Register nicht! auf den Stack, sondern in die > Task-Struktur, genauer in das für diesen Zweck vorhandene Array. Ausschnitt aus deinem Quelltext
#define PUSH(r) asm volatile("push r"#r) #define POP(r) asm volatile("pop r"#r) // ... void scheduler() { //save R0-31 to current->stack PUSH(31);PUSH(30);PUSH(29);PUSH(28);PUSH(27);PUSH(26);PUSH(25);PUSH(24); PUSH(23);PUSH(22);PUSH(21);PUSH(20);PUSH(19);PUSH(18);PUSH(17);PUSH(16); PUSH(15);PUSH(14);PUSH(13);PUSH(12);PUSH(11);PUSH(10);PUSH( 9);PUSH( 8); PUSH( 7);PUSH( 6);PUSH( 5);PUSH( 4);PUSH( 3);PUSH( 2);PUSH( 1);PUSH( 0); // ... |
Ich verstehe jetzt nicht genau wieso Du "nein" behauptest und es trotzdem machst, aber ja... Mir ist übrigens klar, dass der Stackpointer immer wieder auf die aktuelle Task gesetzt wird. Kann es sein, dass Du dich an GOS orientiert hast. Da sind ja schon einige Gemeinsamkeiten. Beitrag "GOS: einfacher preemptive multitasking scheduler"
Datum:
Hallo Mar IO, stimmt, GOS ist in der Tat recht ähnlich. Aber nein, die beiden Systeme sind unabhängig voneinander entstanden. Ich kannte GOS gar nicht. GOS ist ein reiner Scheduler ohne weitere Funktionalität, wenn ich das richtig sehe. Ich glaub, wir haben uns missverstanden. Ich meinte, dass ich die Register in ein Array in der Task-Struktur sichere (current->stack[]). Dass sie zusätzlich in den Stack gesichert werden, ist korrekt, aber: Ich hab gerade mal ausgetestet, was passiert, wenn ich das Attribut aufnehme. Das Ergebnis ist interessant: Bei Optimierungslevel 0 verändert sich erwartungsgemäß die Größe des Compilats leicht nach unten, und die Taskumschaltung erfolgt schneller als ohne das Attribut. Bei höheren Optimierungsveln bewirkt der Eintrag hingegen nichts; Es scheint so, wie als ob gcc von selbst erkennt, dass eine separate Sicherung der Register unnötig ist. Ich werde das Attribut daher mit aufnehmen; Vielen dank für den Rat. gruß tobi
Datum:
Was man vielleicht noch dazu schreiben sollte: Ich "verbiege" in tasks.c den Stackpointer so, dass er für jeden Task auf eine interne Datenstruktur char[64] zeigt, welche für den aktuellen Task unter current->stack[] zu finden ist: t->sp = (unsigned char *)(t->stack + sizeof(t->stack) - 3); So gesehen ist es korrekt, "PUSH" und POP" sind Stack-Operationen, arbeiten aber in diesem Fall auf die interne Datenstruktur. gruß tobi
Datum:
Tobi, super cool... eine kleine Empfehlung.. da du ja eigentlich weisst, wie gross dein task stack ist, überprüfe beim scheduler, ob der task nicht seine grenzen überschritten hat. spart viel debuging.. am besten noch bevor register auf den stack gesichert werden, den schon dort könnte es passieren, das Daten überschrieben werden.. lg roman
Datum:
Hallo Roman, prinzipiell eine gute Idee. Ich nehme an, du meinst ein Konstrukt a la if (SP >= (current->sp + STACK_SIZE)) task_anhilate(¤t); ? Ich überlege nur gerade, wann ein Task seine Grenzen überschreitet, denn eigentlich hat er ja auf dem Stack nichts zu schaffen ;) Mir fallen da im Moment nur verschachtelte Funktionsaufrufe und die Rettung der GPR ein... Na ja, wenn ich schon dabei bin, kann ich auf die Art auch einen Stack-underrun vermeiden mit if (SP >= (current->sp + STACK_SIZE) || SP < current->sp)) task_anhilate(¤t) Bitte korrigiert mich, wenn ich falsch liege. PS. task_anhilate ist jetzt natürlich nur ein Beispiel; hier könnten auch andere Aktionen stehen.
Datum:
Hallo hacker-tobi, bin dabei mich mit Deinem OS zu beschäftigen. Kannst Du nicht eine abgespeckte Anleitung dazu legen? Ich denke, daß wird auch anderen helfen sich an diese Materie heran zu wagen, und es eher zu Benutzen. Gruß
Datum:
Hallo Lernender, die API ist im Quelltext dokumentiert. Es gibt eine vollständige Anleitung, diese ist aber leider in der Diplomarbeit enthalten, und die darf ich erst veröffentlichen, wenn ich die Freigabe dazu habe. Sollte ich keine Freigabe zur Veröffentlichung bekommen, werde ich eine Kurzanleitung erstellen und veröffentlichen. Aber auch das spreche ich dann zur Sicherheit erst mit der Hochschule ab. Also habt Geduld...
Datum:
Hi, das ganze klingt sehr interresant. Wird deine Diplomarbeit noch anders veröffentlicht. (z.B. von der Uni) grüße
Datum:
//+++++++++++++++++TASK Control Structure+++++++++++++++ typedef volatile struct Task { volatile uint8_t ID; volatile unsigned char sreg; volatile unsigned char *sp; volatile TaskPrio prio; #ifdef TASK_USE_SIGNAL volatile TaskState state; volatile uint8_t laps; #endif volatile unsigned char stack[STACK_SIZE]; } Task; |
Also ich verstehe jetzt nicht ganz, wieso Du beim Checken ob ein Stacküberlauf bzw. -unterlauf Du den Stackpointer SP mit current->sp vergleichst??? StackÜBERlauf tritt doch auf, wenn SP kleiner als current->stack ist
if (SP < current->stack) ... |
und ein StackUNTERlauf triff auf, wenn SP größer als höchste Adresse vom Array current->stack[]
if (SP >= &(current->stack[STACK_SIZE]) ... |
Datum:
// Ausschnitt nano_os.h // ... //+++++++++++++++++++++Signal-Handler++++++++++++++++++ SIGNAL (SIG_OVERFLOW0) { scheduler(); } // ... |
Was mir noch aufgefallen ist, wieso eigentlich SIGNAL und nicht ISR?
Wieso springst Du aus scheduler() aus dem Interrupt zurück (letzte
Zeile, asm volatile("reti");) und wird eigentlich current ausser in
scheduler() nochmals verändert? Wenn nicht, dann macht die Zeile
"current = tasks[currentTask];" keinen Sinn, denn current ==
task[currentTask]. Wenn ja, dann würde ich noch ein volatile bei der
Deklaration von current schreiben (nano_os.h).
void scheduler() { //save R0-31 to current->stack PUSH(31);PUSH(30);PUSH(29);PUSH(28);PUSH(27);PUSH(26);PUSH(25);PUSH(24); PUSH(23);PUSH(22);PUSH(21);PUSH(20);PUSH(19);PUSH(18);PUSH(17);PUSH(16); PUSH(15);PUSH(14);PUSH(13);PUSH(12);PUSH(11);PUSH(10);PUSH( 9);PUSH( 8); PUSH( 7);PUSH( 6);PUSH( 5);PUSH( 4);PUSH( 3);PUSH( 2);PUSH( 1);PUSH( 0); TIMER_REG = CLK1024; //save SREG and SP if (currentTask >= 0) { current = tasks[currentTask]; // // // // die Zeile current->sreg = SREG; current->sp = (unsigned char *)(SP + 32); } //switch to next task do { currentTask++; if (currentTask >= NUMBER) { currentTask = 0; } current = tasks[currentTask]; #ifdef TASK_USE_SIGNAL if (current && current->state == TaskStateWaitForLaps) { if (current->laps > 0) current->laps--; else current->state=TaskStateActive; } #endif } #ifdef TASK_USE_SIGNAL while (!(current && current->state==TaskStateActive)); #else while (!current); #endif //restore this task (SREG, SP and R0...31) if (current) { TCNT0 = current->prio; SREG = current->sreg; SP = (unsigned int)(current->sp - 32); } POP( 0);POP( 1);POP( 2);POP( 3);POP( 4);POP( 5);POP( 6);POP( 7); POP( 8);POP( 9);POP(10);POP(11);POP(12);POP(13);POP(14);POP(15); POP(16);POP(17);POP(18);POP(19);POP(20);POP(21);POP(22);POP(23); POP(24);POP(25);POP(26);POP(27);POP(28);POP(29);POP(30);POP(31); asm volatile("reti"); // // // // das reti } |
Datum:
mar IO schrieb: > Was mir noch aufgefallen ist, wieso eigentlich SIGNAL und nicht ISR? Ich geh übrigens von AVR-GCC + nongnu AVR Libc aus. http://www.nongnu.org/avr-libc/user-manual/group__...
Datum:
Hallo tobi, ja so was habe ich gemeint... es sind nicht nur verschachtelte funktions konstrukte, die probleme verursachen koennen, auch lokale variablen. btw. zb. bei Linux oder Solaris, kann man die stack groesse als parameter angeben. Ich weiss frueher hatten wir im solaris ein page kernel thread stack dh. 8K spaeter 16k. Meistens hat es gereicht..jedoch wenn nicht.. big baga bum. das waere vieleicht gar nicht so schlecht, den stack nicht als array zu definieren, sondern dynamisch allozieren und den stack size als parameter uebergeben beim task create. ehh.. nur so eine dumme frage.. beim interrupt, wo wird der stack gesichert ?? auf dem current task ?? lg roman
Datum:
Roman65536 schrieb: > ehh.. nur so eine dumme frage.. beim interrupt, wo wird der stack > gesichert ?? auf dem current task ?? Beitrag "Re: NeuesOS für AVR Mikrocontroller" zu finden in scheduler.c
Datum:
Angehängte Dateien:Jetzt habe ich mal deinen Code mit dem AVR-GCC übersetzt mit OPT=3 und irgendwie frage ich mich ob der Code auch so funktioniert. Grund ist die Zeile 0x175e, da wird aus dem Interrupt rausgesprungen, aber der Ursprung ist noch nicht wieder hergestellt. Dies ist erst nach Zeile 0x1770. Ich kann mich auch irren, bin mir aber nicht 100 %ig sicher
Datum:
Angehängte Dateien:Hi @Mario: Stack: Da liegst du richtig. Sorry war mein Fehler. Hatte vorhin den Quelltext auch nicht vor mir. Habs aufgenommen. Jetzt wird das System vom Scheduler zurückgesetzt, wenn eine Stack-Violation auftritt. Thema Signal: Macht der Gewohnheit. Aber es macht auch keinen Unterschied, da Signal und ISR() das selbe bewirken. Des wegen auch das RETI. Thema current: kann theoretisch wegbleiben, ist ja nur ein Pointer auf tasks[currentTask]. Ich empfinde es aber so als Vereinfachung, daher bleibt der ;) Thema code: Der läuft - schon in mehreren Projekten. Ich werd mir dein File die Tage mal ansehen, heut bin ich zu müde @Bachelor: Das weiß ich zur Zeit noch nicht. Ich poste hier wenn ich was neues weiß. @Roman: Wie schon an Mario adressiert, ist die Stack-Überwachung mit aufgenommen. Das dynamische Management überleg ich mir die Tage mal, ob ich das z.B. mit malloc() im heap realisiere. Aber eigentlich bin ich kein freund von malloc(). Wird auch nur für die queues verwendet. Any better idea? @All Ich habe einen Ordner "doku" angelegt, und dort die komplette API dokumentiert. Ist momentan noch eine simple API-Zusammenfassung, aber wenn ich Zeit und die Eralubnis hab, kommt da evtl. noch mehr.
Datum:
@Mar IO: Anmerkung: versuchs mal mit Optimize-Level s. Bei 3 kommt bei mir funktionsfähiger code raus, der aber erheblich größer ist, als bei s. Mehr find ich heut abend nicht mehr raus...deinen Code schau ich mir die Tage an @All Schön, dass das kleine OS so viel Anklang findet. Und danke für die konstruktive Kritik. Ich freu mich auch über positive meldungen, wenn jemand ein Projekt damit realisieren sollte und es funktioniert ;)
Datum:
Angehängte Dateien:@Mar IO: Nochmal wegen dem current: Ich seh grad, ich hab dich mißverstanden. Ich dachte du beziehst dich auf den Pointer "current" an sich, aber dir gehts ja nur um die eine Zeile. Die kann raus. Habe ich auch erledigt. Und dann hab ich auch noch gesehen, das die push/pop im scheduler mit durch die if-bedingungen abgesichert werden sollten. auch das habe ich angepasst. also hier nochmal ein aktuelles file mit angepasstem scheduler... ich geh jetzt ins bett gruß und gute n8 tobi
Datum:
Tobi, eine Idee ohne den malloc.. meist weiss man ja wie viele task man braucht und auch ca. den stack verbrauch.. dh. man koennte den stack fuer den jeweiligen task schon global deklarieren. zumal man dann diesen so oder so als parameter uebergeben muss, kann man immernoch diesen per malloc allozieren. anderseits... sollte eine task irgend etwas bloedes tun, kann man, man dem der task ein rausschmiss gekriegt hat auch noch gleich sein stack loeschen. Ich habe es einmal so vorgesehen (ist schon jahre her und auf einem 68k) dass das system sich merkt welche task memory alloziert hat. Stirbt dieser oder tut was illegales, wird sein memory wieder frei fuer's system. lg roman
Datum:
Guten Morgen Roman, Okay, was gehen würde, wäre ein globales array, das die Stacks aller Tasks aufnimmt, und dessen Größe fest vorgegeben wird. Dann brauche ich zur Laufzeit nur den Stack-Pointer für jeden Task passend auf einen freien Bereich entsprechender Größe in diesem Array zu setzen. Allerdings muss ich dann das globale Array mit (Anzahl der Tasks * durchschnittliche Stack-size) initialisieren. Ich bin mir nicht sicher, ob das Vorteile bringt, zumal die Stack_size ja global in nano_os.h vorgegeben werden kann. (Mir ist bewußt, dass ich damit Speicher einsparen kann, aber ich will mal sehen, wie viel das in der Praxis ausmacht). Ich werde es testen. Das Memory Management in meinem OS arbeit übrigens genau nach diesem Prinzip, nur das dort Speicherblöcke fixer Größe verwendet werden, was den Algorithmus vereinfacht. Jeder Task kann hier bis zu einer Obergrenze (MAX_BLOCKS) Speicherblöcke reservieren, und diese auch wieder freigeben. Diese werden in einem array verwaltet, das fixnach dem Muster (MAXBLOCKS*BLOCK_SIZE) angelegt ist.
Datum:
Ich seh grad, ich hab gestern versehentlich ne alte Version hochgeladen...korigiere ich nacherher.
Datum:
Angehängte Dateien:hacker-tobi schrieb: > Thema Signal: Macht der Gewohnheit. Aber es macht auch keinen > Unterschied, da Signal und ISR() das selbe bewirken. Des wegen auch das > RETI. Signal ist halt veraltet, nicht ganz genau das selbe wie ISR und sollte nicht benutzt werden. Siehe Doku http://www.nongnu.org/avr-libc/user-manual/group__... Ausserdem springst Du mit RETI zurück aus einer Funktion (SIGNAL(...) ist die ISR). Das I-Flag wird gelöscht, obwohl Du noch in der ISR bist. Weiß ned ob das schlimme Auswirkungen mit sich zieht, ist halt etwas zu früh (aber nur etwas). hacker-tobi schrieb: > @Mar IO: Anmerkung: versuchs mal mit Optimize-Level s. Japp, habe ich soeben (den Code vom ersten Posting). Was mir da auffällt, dass in SIGNAL(SIG_OVERFLOW0) (Code-Adresse ab 0x1b0) ziemlich viel auf den Stack gesichert wird (Register, SREG, Rücksprungadressen) und in scheduer() (ab 0xa6) nochmals alle Register. Hier kannst Du sicher etwas einsparren (siehe GOS). Was da auch auffällt, in scheduler() kommt zuerst ein RETI, dann ein RET (zu dem man natürlich nicht kommt) und dann in SIGNAL(...) wieder ein RETI. Ich habe mir bis jetzt nur scheduler() angeschaut und den restlichen Code überflogen. Was mir dabei aufgefallen ist, dass Du gerne volatile schreibst. Zu struct und volatile kannst dir mal folgenden Thread durchlesen (der enthaltende Link ist auch recht interessant): Beitrag "volatile und struct"
Datum:
Angehängte Dateien:Hi MarIO, das mit dem reti kann ich so nicht bestätigen. nimmt man das reti raus, wird nicht mehr aus dem Interrupt zurückgesprungen. Was die überflüssigen volatiles angeht - die hab ich entfernt. Und noch einen Fehler in der Funktion Queue_Init entdeckt und behoben; dort wurde die queue->number nicht korrekt initialisiert. ISR() funktioniert nicht wirklich. Selbst mit dem GOS-Scheduler (im original, also mit direktem Aufruf als ISR) nicht. Es werden massiv Register überschrieben. Hier liegt wohl noch ein Fehler vor. Entweder bei mir oder beim Compiler. Aber das werde ich heut abend nicht mehr untersuchen. Mit Signal funktionierts problemlos, das reicht mir momentan gerade. Ich bin mitten dabei, mich in nen neuen Job einzuarbeiten, und mein Studium zuende zu bringen, da ist Zeit mangelware.... Anbei die aktuelle Version. gruß tobi
Datum:
Tobias W. schrieb: > stimmt, GOS ist in der Tat recht ähnlich. > Aber nein, die beiden Systeme sind unabhängig voneinander entstanden. > Ich kannte GOS gar nicht. > GOS ist ein reiner Scheduler ohne weitere Funktionalität, wenn ich das > richtig sehe. Dann hat GOS wohl von dir abgeschaut? GOS:
#define PUSH(r) asm volatile("push r"#r);
#define POP(r) asm volatile("pop r"#r);
[...]
void TIMER_VECTOR() __attribute__ ( ( signal, naked ) );
ISR(TIMER_VECTOR)
{
PUSH(31);PUSH(30);PUSH(29);PUSH(28);PUSH(27);PUSH(26);PUSH(25);PUSH(24);
PUSH(23);PUSH(22);PUSH(21);PUSH(20);PUSH(19);PUSH(18);PUSH(17);PUSH(16);
PUSH(15);PUSH(14);PUSH(13);PUSH(12);PUSH(11);PUSH(10);PUSH( 9);PUSH( 8);
PUSH( 7);PUSH( 6);PUSH( 5);PUSH( 4);PUSH( 3);PUSH( 2);PUSH( 1);PUSH( 0);
|
Deins:
#define PUSH(r) asm volatile("push r"#r)
#define POP(r) asm volatile("pop r"#r)
//****************************************************
//*scheduler() *
//* *
//* !!!INTERNAL FUNCTION!!! *
//* *
//* description: does the task switching *
//* input: none *
//* output: none *
//****************************************************
void scheduler()
{
//save R0-31 to current->stack
PUSH(31);PUSH(30);PUSH(29);PUSH(28);PUSH(27);PUSH(26);PUSH(25);PUSH(24);
PUSH(23);PUSH(22);PUSH(21);PUSH(20);PUSH(19);PUSH(18);PUSH(17);PUSH(16);
PUSH(15);PUSH(14);PUSH(13);PUSH(12);PUSH(11);PUSH(10);PUSH( 9);PUSH( 8);
PUSH( 7);PUSH( 6);PUSH( 5);PUSH( 4);PUSH( 3);PUSH( 2);PUSH( 1);PUSH( 0);
TIMER_REG = CLK1024;
|
Etwas Ehrlichkeit, bitte!
Datum:
@Helli: Das Thema hatten wir jetzt schon... sorry ich weiß was ich geschrieben hab und was nicht. Und ich sage es nochmal...GOS ist ein reiner Scheduler, Nano OS bietet ja doch etwas mehr Funktionalität, oder?
Datum:
hacker-tobi schrieb: > @Helli: Das Thema hatten wir jetzt schon... sorry ich weiß was ich > geschrieben hab und was nicht. > Und ich sage es nochmal...GOS ist ein reiner Scheduler, Nano OS bietet > ja doch etwas mehr Funktionalität, oder? Das ist nicht das Problem ... Man muss auch seine Quellen angeben, wenn man etwas fremdes verwendet hat. Niemand hätte irgendwas gesagt, wenn du gleich geschrieben hättest, dass du dich von GOS inspirieren hast lassen ... Aber eine Lüge ist eine Lüge ...
Datum:
Und mal davon abgesehen...wenn du dir den Scheduler genauer ansiehst, so sind doch einige Unterschiede da: -Ich rufe den Scheduler via Signal() auf, nicht als ISR. Das kommt daher, dass ich den Scheduler schon vor längerer Zeit geschrieben hab - für ein Uhrenprojekt- und ihn für Nano OS übernommen habe. -PUSH und POP und die Struktur sind identisch, aber der Prozessor muss ja immer das selbe ausführen, um einen Task-Switch auszulösen, ergo ist das wohl nicht verwunderlich. Ok, die Makrobezeichnungen sind identisch. Daher sehen sich die Programmteile ähnlich. Aber das wird sich auch demnächst ändern, da ich die Registeranzahl variabel gestalten will, wegen der neuen AtTinys, die nur noch 16 Register haben. -Der Scheduler in Nano OS hat einige Fähigkeiten, die der GOS-Scheduler nicht hat, wie z.B. die möglichkeit, Tasks für eine definierte Zeit schlafen zu legen. Insgesamt verstehe ich den Einwand, das die Scheduler ähnlich sind, aber es gibt eben doch unterschiede. Ich hoffe damit ist dieses (aus meiner Sicht -sorry- leidige) Thema erledigt.
Datum:
@Helli: Nochmal...ich kann nichts angeben, was ich nicht kenne. Und mich deswegen der Lüge zu bezichtigen - meinst du nicht, dass das etwas zu weit geht? Sorry, aber du hast nicht danebengesessen, als ich das OS geschrieben hab, oder irre ich mich? Also woher willst du wissen, was ich geschrieben hab und was nicht? Und wenn ich gos als Quelle benutzt hätte, würde ich es auch angeben. Warum sollte ich es denn verheimlichen? Aber ich kann gern die Makrobezeichnungen ändern, und den Programmtext umstellen, wenn dich die ähnlichkeiteen stören (das meine ich ernst, nicht als witz). gruß tobi
Datum:
Echt merkwürdig ... hacker-tobi schrieb: > Aber ich kann gern die Makrobezeichnungen ändern, und den Programmtext > umstellen, wenn dich die ähnlichkeiteen stören (das meine ich ernst, > nicht als witz). Das hier ist von dir (14.09.2010):
void scheduler()
{
//save R0-31 to current->stack
PUSH(31);PUSH(30);PUSH(29);PUSH(28);PUSH(27);PUSH(26);PUSH(25);PUSH(24);
PUSH(23);PUSH(22);PUSH(21);PUSH(20);PUSH(19);PUSH(18);PUSH(17);PUSH(16);
PUSH(15);PUSH(14);PUSH(13);PUSH(12);PUSH(11);PUSH(10);PUSH( 9);PUSH( 8);
PUSH( 7);PUSH( 6);PUSH( 5);PUSH( 4);PUSH( 3);PUSH( 2);PUSH( 1);PUSH( 0);
TIMER_REG = CLK1024;
//save SREG and SP
if (currentTask >= 0)
{
current = tasks[currentTask];
current->sreg = SREG;
current->sp = (unsigned char *)(SP + 32);
}
//switch to next task
do
{
currentTask++;
if (currentTask >= NUMBER)
{
currentTask = 0;
}
current = tasks[currentTask];
#ifdef TASK_USE_SIGNAL
if (current && current->state == TaskStateWaitForLaps)
{
if (current->laps > 0)
current->laps--;
else
current->state=TaskStateActive;
}
#endif
}
#ifdef TASK_USE_SIGNAL
while (!(current && current->state==TaskStateActive));
#else
while (!current);
#endif
//restore this task (SREG, SP and R0...31)
if (current)
{
TCNT0 = current->prio;
SREG = current->sreg;
SP = (unsigned int)(current->sp - 32);
}
POP( 0);POP( 1);POP( 2);POP( 3);POP( 4);POP( 5);POP( 6);POP( 7);
POP( 8);POP( 9);POP(10);POP(11);POP(12);POP(13);POP(14);POP(15);
POP(16);POP(17);POP(18);POP(19);POP(20);POP(21);POP(22);POP(23);
POP(24);POP(25);POP(26);POP(27);POP(28);POP(29);POP(30);POP(31);
asm volatile("reti");
}
|
und das hier ist aus einem hochgeladenen Archiv von 2007 von hier: Beitrag "Re: GOS: einfacher preemptive multitasking scheduler"
void TIMER_VECTOR() __attribute__ ( ( signal, naked ) );
ISR(TIMER_VECTOR)
{
PUSH(31);PUSH(30);PUSH(29);PUSH(28);PUSH(27);PUSH(26);PUSH(25);PUSH(24);
PUSH(23);PUSH(22);PUSH(21);PUSH(20);PUSH(19);PUSH(18);PUSH(17);PUSH(16);
PUSH(15);PUSH(14);PUSH(13);PUSH(12);PUSH(11);PUSH(10);PUSH( 9);PUSH( 8);
PUSH( 7);PUSH( 6);PUSH( 5);PUSH( 4);PUSH( 3);PUSH( 2);PUSH( 1);PUSH( 0);
TIMER_REG = CLK1024;
Task *current = 0;
if (currentTask >= 0)
{
current = tasks[currentTask];
current->sreg = SREG;
current->sp = (unsigned char *)(SP + 32);
}
do
{
currentTask++;
if (currentTask >= MAX_TASKS)
currentTask = 0;
current = tasks[currentTask];
}
#ifdef TASK_USE_SIGNAL
while (!(current && current->state==TaskStateActive));
#else
while (!current);
#endif
if (current)
{
TCNT0 = current->prio;
SREG = current->sreg;
SP = (unsigned int)(current->sp - 32);
}
POP( 0);POP( 1);POP( 2);POP( 3);POP( 4);POP( 5);POP( 6);POP( 7);
POP( 8);POP( 9);POP(10);POP(11);POP(12);POP(13);POP(14);POP(15);
POP(16);POP(17);POP(18);POP(19);POP(20);POP(21);POP(22);POP(23);
POP(24);POP(25);POP(26);POP(27);POP(28);POP(29);POP(30);POP(31);
asm volatile("reti");
}
|
Sind die beiden Codeschnippsel nicht irgendwie identisch? Sogar die Variablen heißen alle gleich usw ... Oder hast du GOS auch geschrieben? Wenn das für eine wissenschaftliche Arbeit wäre, würde ich mir langsam ernste Gedanken machen
Datum:
Ach, es gibt auch noch eine andere Möglichkeit ... Der GOS-Entwickler meinte, er würde seinen Scheduler in den AVRWizard einbauen ... Hast du den vlt verwendet? Das würde das erklären ...
Datum:
Frank M. schrieb im Beitrag #1868712: > Aber zu behaupten, Du würdest GOS gar nicht kennen, ist dummdreist. Vlt kennt er GOS wirklich nicht ... Ich hab grad nachgeschaut, das Multitasking-Dings ist im AVR-Wizard auch eingebaut worden ... Aber einen Wizard zu verwenden für das, was man selbst machen soll ... Hoffentlich hat er das wenigstens angegeben ...
Datum:
Ich habs schonmal gesagt...ich gebe zu, das sich die Scheduler ähnlich sehen. Von daher verstehe ich den Einwand definitiv. Und was die Arbeit angeht...dort sind alle benutzen Quellen gelistet. In diesem Fall war auch der Fachmentor direkt an der Entwicklung beteiligt. Ich werde die Arbeit hier veröffentlichen, sobald ich die Freigabe dazu habe, ok? Sorry, aber damit ist diese Diskussion von meiner Seite her beendet, denn sie macht keinen Sinn. Du kannst das OS gern nutzen oder auch nicht und gern andere fachspezifische Fragen stellen, aber zu diesem Thema wird von mir nichts mehr kommen, denn so lange ich die Arbeit nicht veröffentlichen darf, kann ich es dir leider nicht schwarz auf weiß widerlegen. Übrigens, der nano OS scheduler ist älter als der von gos, genauer gesagt von 2005/2006. nur das ich ihn nicht veröffentlicht habe, weil ich ihn -wie gesagt- in einem Uhrenprojekt eingesetzt habe, dass ich auch verkauft hab. Von daher - nein ich habe gos nicht geschrieben, aber weder ist gos von mir abgekupfert, noch umgekehrt. Ich finds ehrlich gesagt ein wenig unverschämt, was du da sagst. Manchmal macht der Ton die Musik. gruß tobi
Datum:
Helli schrieb: > Frank M. schrieb im Beitrag #1868712: >> Aber zu behaupten, Du würdest GOS gar nicht kennen, ist dummdreist. Während Du antwortetest, habe ich meinen Beitrag wieder gelöscht, weil ich danach Deinen Beitrag über den AVR-Wizard las, der auch noch als Möglichkeit in Frage käme. Du warst schneller, das ist halt das Problem bei asynchronen Medien ;-) Dann formuliere ich mal um: @hacker-tobi: Dass Du irgendwann irgendwo abgeschrieben hast, ist offensichtlich. Die Makros und Funktionen sind nicht nur "ähnlich", sondern komplett identisch, sogar die Spaces in den Makro-Argumenten bei einstelligen Zahlen. Am Abschreiben ist auch nicht unbedingt etwas Verwerfliches zu sehen. Aber dann gib bitte Deine Quellen auch an. Du schriebst auch: > Und wenn ich gos als Quelle benutzt hätte, würde ich es auch angeben. > Warum sollte ich es denn verheimlichen? Okay, dann sollte es ja kein Problem sein, Deine Quelle zu nennen. P.S. Es könnte auch jemand von Dir abgeschrieben haben. Aber das halte ich eher für unwahrscheinlich.
Datum:
Mal ganz abgesehen davon...wenn ich von gos abgeschrieben hätte, ohne es anzugeben, dann wär ich wohl kaum so dumm, das hier zu veröffentlichen ;) Ich würde vorschlagen...wir lassen diese Diskussion jetzt einfach. Denn sie führt zu gar nichts, oder? Ich werds jetzt jedenfalls nicht weiter kommentieren. Aber ich werde den Quelltext ändern, wenn du das willst.
Datum:
Angehängte Dateien:Tobias W. schrieb: > das mit dem reti kann ich so nicht bestätigen. nimmt man das reti raus, > wird nicht mehr aus dem Interrupt zurückgesprungen. Das kann ich mir nicht vorstellen bzw., das ist so richtig, denn Du bist ja noch im Interrupt drinnen. Der Interrupt ist erst aus, wenn Signal(...) fertig ist. Wie prüfst Du das eigentlich nach? Würde mich wundern, wenn ISR(...) nicht funktioniert. Das hat sicherlich nichts mit den Compiler zu tun. Dieser wirft bei mir übrigens einige Warnings raus. A z.B: system/message.c: In function 'queue_read_byte': system/message.c:156: warning: 'return' with no value, in function returning non-void
147 unsigned char queue_read_byte(Queue *qp, uint8_t position, uint8_t delete_message) 148 { 149 sregsys = SREG; 150 cli(); 151 uint8_t i; 152 unsigned char tempmsg; 153 if (qp->number == 0 || qp->number <= position || qp->item_size != 1) 154 { 155 SREG = sregsys; 156 return; 157 } 158 //read message 159 tempmsg = qp->message[position]; 160 if (delete_message) 161 { 162 //re-organize message queue (FIFO) 163 for (i=position;i<(qp->number)-1;i++) 164 qp->message[i] = qp->message[i+1]; 165 qp->number--; 166 } 167 SREG = sregsys; 168 return tempmsg; 169 } |
Datum:
@Frank: Da gebe ich dir in allen Punkten recht. Aber wie gesagt, ich kann nichts angeben, was ich nicht kenne ;( Tut mir echt leid. Ich sehe die Problematik ja auch absolut ein, aber was soll ich denn noch sagen? Ich werde die Arbeit hier veröffentlichen, wenn ich die Erlaubnis dazu bekomme, damit jeder das Gedankengut "hinter" nano os nachvollziehen kann. Und wie gesagt, der nano os scheduler ist älter. Nur wurde er vorher nie veröffentlicht. Von daher kann weder ich von gos abgeschrieben haben (denn das wurde ja erst 2007 veröffentlicht) noch gos von mir(da der scheduler ja gar nicht veröffentlicht war). Und den AVR Wizard kenne ich, habe ihn aber nie eingesetzt. Es ist auch müßig, darüber zu diskutieren, denn das würde sich doch nur im Kreis drehen. Vorschlag: Gegenseitiges aufeinander rumhacken bringt doch nichts, wie wäre es, wenn wir gemeinsam an nano os weiterarbeiten? gruß tobi
Datum:
hacker-tobi schrieb: > Ich würde vorschlagen...wir lassen diese Diskussion jetzt einfach. > Denn sie führt zu gar nichts, oder? Ich werds jetzt jedenfalls nicht > weiter kommentieren. Aber ich werde den Quelltext ändern, wenn du das > willst. Ich sag jetzt auch nichts mehr dazu ... Sogar die anderen Funktionen in dem selben File sind identisch ... Dann würde ich dem Günter Greschenz mal sagen, dass er nicht deinen Code klauen soll, den du 2005 geschrieben aber nie veröffentlich hast ... der ist offenbar so dumm, ihn aus deiner Uhr zu stehlen, ihn in seinem AVR-Wizard einzubauen und öffentlich zur Verfügung zu stellen ... Unten ein Link, und wenn man dann auf task.c klickt, dann erscheint dein Code ... Ich würd mal einen Virenscanner installieren, vlt hast du ja einen Trojaner ... http://greschenz.dyndns.org/avrwiz/ Mehr Kommentare gibt's von mir aus nicht mehr dazu ... Du wirst schon wissen, was du macht ...
Datum:
@mario: kann sein, ok, nicht ganz korrekt ausgedrückt. Er springt natürlich aus dem Interrupt zurück, aber das I-Bit wird nicht mehr gesetzt, ergo bleiben Interrupts inaktiv. Warum, das muss ich in Ruhe ergründen. Wegen ISR: Ich kanns mir zur Zeit auch nicht erklären. Aber wenn ich ISR verwende, dann überschreiben sich die Tasks gegenseitig die Register. Ich denke, da liegt noch was im argen. Aber auch mit dem gos-Scheduler tritt dieses Phänomen auf. Dass muss ich mir in Ruhe ansehen. Wegen der Warnung: Okay, da muss ich mal dran, ist ja keine große Sache. Interessanterweise hat er das bei mir nicht bemängelt. Hast du sonst noch irgendwelche warnungen?
Datum:
hacker-tobi schrieb: > @Frank: Da gebe ich dir in allen Punkten recht. Aber wie gesagt, ich > kann nichts angeben, was ich nicht kenne Ok, dann gib einfach das an, was Du kennst. Du eierst hier rum wie um den heißen Brei. Wo ist Dein Problem? Schauen wir uns mal die Funktion task_create() aus tasks.c an: GOS:
void taskCreate(Task *t, TaskFunction f, TaskPrio prio)
{
cli();
...
sei();
}
|
Deine Version:
void task_create(Task *t, TaskFunction f, TaskPrio prio) { sregsys = SREG; cli(); ... SREG = sregsys; return; } |
Die ca. 20 Zeilen, die ich hier mit "..." gekennzeichnet habe, sind absolut identisch - abgesehen von der kaputten Einrückung Deinerseits. (Daran könntest Du noch arbeiten, es macht keinen Spaß, Code zu lesen, der global an den linken Rand geklatscht ist). Aber was ich daraus erkenne, ist, wer von wem abgeschrieben hat, denn Deine Version ist eleganter, also erst das SREG zu sichern und nachher wieder herzustellen. GOS dagegen macht es plump mit cli() und sei(). Ergo: Eine eindeutige Code-Verbesserung, umgekehrt wäre es blöd vom Programmierer, den Code wieder zu verschlimmbessern. Also: Wie heisst Deine Quelle?
Datum:
Frank M. schrieb: > Aber was ich daraus erkenne, ist, wer von wem abgeschrieben hat, denn > Deine Version ist eleganter, also erst das SREG zu sichern und nachher > wieder herzustellen. GOS dagegen macht es plump mit cli() und sei(). Mir gefällt die GOSs Funktion besser. Ich wüsste keinen Grund, wieso man das SREG sichern sollte. Dass kein sei() später folgt, gefällt mir hier auch nicht, denn man muss wissen, dass taskCreate(...) die Interrupts ausschaltet, aber nicht wieder ein. D.h., nach der Funktion läuft das System nicht mehr so weiter wie davor (taskCreate(...) sollte ja auch zur Laufzeit eine Task einfügen können). Das taskCreate atomic ist, ist völlig OK.
Datum:
Helli schrieb: > Ich sag jetzt auch nichts mehr dazu ... Das halte ich für die falsche Einstellung. > Sogar die anderen Funktionen in > dem selben File sind identisch ... Dann würde ich dem Günter Greschenz > mal sagen, dass er nicht deinen Code klauen soll, den du 2005 > geschrieben aber nie veröffentlich hast ... Es gibt noch eine andere Möglichkeit, nämlich hacker-tobi == Günter Greschenz D.h. er würde in diesem Falle versuchen, seinter Uni seine eigene 3 Jahre alte Software jetzt neu als Diplomarbeit zu verkaufen. Aber das ist reine Spekulation. Ausserdem müsste ich hacker-tobi noch schlechtes Software-Management vorwerfen, denn der avrwiz generiert auch heute noch die uralte cli()...sei()-Variante. ;-) Als letztes: Die Software von Günter Greschenz ist zwar öffentlich runterladbar, aber nicht frei. Sie ist im GOS ("Günters OS", bezeichnend ist auch die Ähnlichkeit in der Namenswahl des Projekts, jetzt ist es "Nano OS") ausdrücklich mit "(c) 2007 by günter greschenz (g AT greschenz.de)" gekennzeichnet.
Datum:
mar IO schrieb: > Mir gefällt die GOSs Funktion besser. Ich wüsste keinen Grund, wieso man > das SREG sichern sollte. Dass kein sei() später folgt, gefällt mir hier > auch nicht, denn man muss wissen, dass taskCreate(...) die Interrupts > ausschaltet, aber nicht wieder ein. Die Interrupts werden mit Herstellen des SREG wieder eingeschaltet.
Datum:
Frank M. schrieb: > Die Interrupts werden mit Herstellen des SREG wieder eingeschaltet. Stimmt, irgendwie habe ich an das gar nicht mehr gedacht und somit völlig den Schmarrn geschrieben. Dann gefällt mir die GOS Funktion besser, weil ich die besser lesen kann.
Datum:
@Frank: Sorry, wie bereits geschrieben...diese Diskussion ist sinnlos. Es gab für den Scheduler-Code keine Quelle. Natürlich habe ich Quellen benutzt, aber die haben sich eher auf die Beschreibung der Funktionaliltät bezogen und sind auch in der Arbeit erwähnt. Dies war das Buch von Manfred Schwabl - Programmierung von Mikrocontrollern und ein Buch zu Betriebssystemgrundlagen. Zusätzlich einige Wikipedia-Artikel und weitere Internet-Recherchen. Aus dem Buch von Manfre Schwabl stammen auch die Anregungen für den Scheduler. Allerdings hat er in Assembler codiert, die C-Umsetzung ist von mir. Warum also sollte ich alle diese Quellen angeben, und eine (gos) nicht? Warum sollte ich einmal Code verbessern, und dann -im Gegensatz zu gos- statt mit ISR mit Signal arbeiten, und auch andere Kleinigkeiten, wie z.B. die Initialisierung von current anders machen? Und warum unterscheidet sich z.B. die komplette Tasksignalisierung (task_signal, task_wait, task_wait_for_laps)? gos kennt z.B. auch kein task_anhilate oder ähnliches. Wenn ich das alles abgeschrieben hätte würde es doch identisch aussehen. Ich gebe es auch zu, z.B. das konstrukt mit Signal() habe ich gemacht, weil dies mein erster Scheduler ist, und ich schlicht nicht wusste, das es auch anders (und besser) geht. Und push/pop sind nunmal Standardfunktionen. Da können auch andere drauf kommen, die so zu benennen. Und zum rest...der Prozessor muss nunmal zum Taskwechsel immer das selbe tun, egal ob der Scheduler nun gos, nanoos oder sonstwie heißt. Die Schritte sind nunmal immer...interrupts abschalten, register sreg und SP sichern, neuen Task anwählen, register sreg sp zurückschreiben und dann interrupts wieder aktivieren. Und da suich die Verwaltungsinformationen ähneln, sind nunmal auch die dafür notwendigen Verwaltungsstrukturen zwangsläufig ähnlich. Und zum Thema rumeiern...das kann ich euch genauso vorwerfen. Ihr versucht da krampfhaft, mir eine Quelle aus den Rippen zu leiern, die ich nicht kenne und auch nicht benutzt habe. Ich habe keine Ahnung, warum sich die Codes ähnlich sind, aber es interessiert mich auch nicht. Ich werfe ja auch dem gos-schreiber kein Abschreiben vor (und glaube auch nicht daran), obwohl mein Scheduler eher entstanden ist. Es wurde auch schon einmal weiter oben in diesem Thread nach den Ähnlichkeiten gefragt, und diese Frage habe ich auch beantwortet. Aber dort wurde nur einmal nachgefagt. Du und heli, ihr probiert es andauernd wieder, und -sorry- aber mehr als das was ich weiß, kann ich dazu nicht sagen. Ich werde aber meinen Code umschreiben, damit die Ähnlichkeiten weg sind, obwohl ichs für unsinnig halte, um damit dieses Thema zu beenden. So nun habe ich alle Quellen offengelegt, und auch sonst alles. Die Arbeit selbst folgt, wenn ich sie veröffentlichen darf. So, ich bin mittlerweile ziemlich entnervt. Um meine nerven zu schonen, werden weitere Anfragen zu diesem Thema nicht mehr kommentiert. Andere Fragen Anregungen Lob / Kritik werden natürlich weiter bearbeitet und beantwortet. gruß tobi
Datum:
Jetzt wirds ja völlig abstrus...klar ich bin Günther Greschenz...all right ;) Komisch, auf meiner Diplomarbeit steht ein anderer Name...Tobias W. Auf meinem Perso auch ;). Daher auch der nick (hacker-TOBI) Leute , lasst es einfach. @Mario: Es ist so, wie frank sagt. Mit dem SREG wird auch das I-Bit wieder gesetzt. Daher kein sei(). Okay ich stimme dir zu, das sieht man nur, wenn man es weiß. Von daher ist gos besser zu lesen ;) Aber ich denke, ein zuätzliches sei() der lesbarkeit wegen ist hier sinnfrei() ;) Hast du noch ne Idee, warum das mit ISR() nicht funktioniert hat?
Datum:
Angehängte Dateien:Übrigens, GOS ist eigentlich auch schon älter, aber anscheinend ging da der Code verloren... ---HISTORY---------------------------------------------------------------------- *) V0.000 2001 (?) first working version for 68000 (PalmPilot) (but i lost my old code ...) *) ... Was mich bei beiden Codes wundert, wieso SREG nicht auf den Stack sichern und den gesicherten Stackpointer auf das erste gesicherte Register (r31) zeigen zu lassen???
Datum:
hacker-tobi schrieb: > Hast du noch ne Idee, warum das mit ISR() nicht funktioniert hat? Nee, bei mir hat er übersetzt, aber ausprobiert habe ich es nicht. Siehe Anhang von Beitrag "Re: NeuesOS für AVR Mikrocontroller"
Datum:
hacker-tobi schrieb: > Wenn ich das alles abgeschrieben hätte würde es doch identisch aussehen. Einzelne Teile (insb. der Code in tasks.c) sind identisch. Das kann man nicht mit "ähnlich" abtun. Die Interfaces sind identisch, die Variablen sind identisch, der Code ist identisch. Ich habe ja nicht gesagt, dass Du alles abgeschrieben hast. Aber große Teile davon kommen aus einer anderen Quelle. > Und zum Thema rumeiern...das kann ich euch genauso vorwerfen. Ihr > versucht da krampfhaft, mir eine Quelle aus den Rippen zu leiern, die > ich nicht kenne und auch nicht benutzt habe. Ich habe keine Ahnung, > warum sich die Codes ähnlich sind, aber es interessiert mich auch nicht. Nochmal zum mitmeisseln: Die sind nicht "ähnlich", die sind in großen Teilen identisch. Es gibt also 2 deutschsprachige Programmierer auf der Welt, die - ohne sich zu kennen - identischen Code schreiben. Wahnsinn, das hat die Welt noch nicht gesehen. > Ich werde aber meinen Code umschreiben, damit die Ähnlichkeiten weg > sind, obwohl ichs für unsinnig halte, um damit dieses Thema zu beenden. Das heisst, Du machst aus dem identischen Code einen ähnlichen Code. Wegbekommen wirst Du die "Ähnlichkeiten" niemals, ausser Du schreibst den identischen Code von Scratch auf neu. > So nun habe ich alle Quellen offengelegt, [...] Ich habe keine Quelle gesehen?!? Oder habe ich Tomaten auf den Augen? > So, ich bin mittlerweile ziemlich entnervt. Das hast Du Dir selbst eingebrockt. > Um meine nerven zu schonen, > werden weitere Anfragen zu diesem Thema nicht mehr kommentiert. Als Gründer von einigen in Deutschland ziemlich bekannten OpenSource-Projekten ist Dein Verhalten, was Du hier an den Tag legst, für mich wie ein Schlag ins Gesicht. Daher ist dieses Thema (Copyright/Kupfern/Diplomarbeit) für mich noch lange nicht beendet.
Datum:
Hi Mario, stimmt. Aber so fit bin ich (noch) nicht, das ich den code vom 68000 umschreiben könnt, selbst wenn er noch vorhanden geweswen wäre ;) Der Scheduler für den avr hat mich genug mühe gekostet. Thema Sichern: Das wär ne Möglichkeit. Aber so richtig sehe ich den Vorteil jetzt nicht. Das SREG könnte ich auf den Stack schieben, aber so oder so geht mir dafür 1 byte im Speicher drauf. Hast du da einen bestimmten Grund? Stackpointer: Das lässt sich machen.
Datum:
Nachtrag als gutgemeinter Tipp: Besorge Dir von Günther Greschenz schnellstmöglich die Erlaubnis, seinen Code verwenden zu dürfen, d.h. er soll Dir eine Lizenz ausstellen. Verletzungen von Copyrights sind kein Kavaliersdelikt. Wenn das in der Uni rumgeht, kannst Du Deine Diplomarbeit in die Tonne werfen.
Datum:
Frank M. schrieb: >> Um meine nerven zu schonen, >> werden weitere Anfragen zu diesem Thema nicht mehr kommentiert. > > Als Gründer von einigen in Deutschland ziemlich bekannten > OpenSource-Projekten ist Dein Verhalten, was Du hier an den Tag legst, > für mich wie ein Schlag ins Gesicht. Daher ist dieses Thema > (Copyright/Kupfern/Diplomarbeit) für mich noch lange nicht beendet. Wie wär's wenn man Günther auf diesen Thread aufmerksam macht und ihn einfach frägt, ob er den Scheduler geschrieben hat oder nicht? Aber es stimmt - Die Source-Codes sind identisch und unabhängig identischen Source-Code zu produzieren ist unmöglich. Grüße, Mampf
Datum:
hacker-tobi schrieb: > Thema Sichern: Das wär ne Möglichkeit. Aber so richtig sehe ich den > Vorteil jetzt nicht. Das SREG könnte ich auf den Stack schieben, aber so > oder so geht mir dafür 1 byte im Speicher drauf. Wie man an diesen Ausführungen sieht, hast Du Deinen angeblich "eigenen" Scheduler nicht im Griff, d.h. Du verstehst nicht, was Du da tust. Wenn Du SREG auf eine lokale Variable einer Funktion schreibst, wo liegt diese Kopie dann? Wenn Du die Antwort wüsstest, dann würdest Du auch einsehen, dass Deine obige Antwort sinnfrei ist. Gruß, Frank
Datum:
Ich habe mich auf den kompletten code bezogen, daher von Ähnlichkeiten gesprochen. Ansonsten gebe ich dir recht, einzelne Zeilen sind identisch. Das API hingegen nur in Teilen. Ich verweise da z.B. auf task_wait und task_signal, welche andere Parameter nutzen, usw. Und ja, ich werde den code neuschreiben. Dann ist es eindeutig, denn wie gesagt - ich kann die Einwände völlig verstehen, und nachvollziehen. Auch die Schlußfolgerungen sind verständlich, aber ich kann nur das wiedergeben, was ich auch getan habe. Von daher verstehe du bitte auch, das ich mich gegen derartige Anschuldigungen zur Wehr setze, denn aus meiner Sicht sind sie nachvollziehbar, aber unberechtigt. Und las bitte Äußerungen wie "das ist für mich noch lange nicht erledigt" weg - was sollen denn solche Drohungen? Sorry, aber damit erreichst du bei mir nichts. Warum können wir nicht einfach konstruktiv an einer Lösung des Problems arbeiten? Was soll ich denn nach deiner Ansicht tun, um das Problem aus der Welt zu räumen (die Frage meine ich ernst, denn ich will das Thema friedlich aus der Welt schaffen)? gruß tobi
Datum:
Mensch Tobi, sehe es bitte mal von der anderen Seite, einfach als gut gemeinten Hinweis, dass es hier Probleme mit Urheberrechten geben könnte, vor denen man dich (noch rechtzeitig) warnt und die du jetzt klären solltest! Es muss nicht hier sein, aber in deiner Arbeit solltetst du es tun! Das hier jemand von jemanden anders "abgeschrieben" hat, ist wirklich zu offensichtlich (Frank hat ein paar Dinge genannt..., für mich ist auch die spezielle Formatierung der PUSH/POP-Anweisungen zu prägnant). Der Zufall wäre zu groß, wenn zwei Leute genau(!) so formatieren! Klar, wie du auch schon geschrieben hast, gleiches Thema = gleiche Vorgehensweise, aber nicht von unterschiedlichen Leuten vollkommen gleiche Variablennamen, Programmstrukturen, Codeformatierungen..., dass geht einfach nicht! Da hilft es auch nicht, wenn du jetzt einfach den Code umschreiben willst, dafür ist dieser Thread zu öffentlich! Es ist doch legitim, wenn du fremde Codefragmente als Grundlage nimmst und für deine Belange anpasst und erweiterst. Genau das ist doch die geistige Arbeit die du da reingesteckt hast, an der du gemessen wirst und die will/wird dir keiner streitig machen. Aber diese Grundlage musst du als Quelle angeben, selbst wenn diese unter GPL steht. Sei bitte so ehrlich, sonst kommst du spätestens bei der Einreichung deiner Arbeit in Teufels Küche. Wenn du nicht abgeschrieben hast, solltest du wirklich überdenken, woher in fremden Code deine(!) ursprünglichen Fragmente herkommen können. Hast du vielleicht doch irgendwo deine Programme und sei es auch nur ganz kurz, öffentlich gemacht oder hast du einzelnen Leuten den Quelltext gegeben und kannst du das irgendwie nachweisen (nicht uns, sondern immer im Hinblick auf deine Arbeit, mit der du einen Titel erreichen willst)? Überdenke das bitte nochmal!
Datum:
SREG wird in eine globale Struktur vom Typ task gesichert, die mit deklaration volatile versehen ist. und wo liegt die? im RAM oder?
Datum:
hacker-tobi schrieb: > Was soll ich denn nach deiner Ansicht tun, um das Problem aus der Welt > zu räumen Ganz einfach: Besorge Dir von Günter eine Lizenz. Dann löst sich das Problem in Luft auf.
Datum:
hacker-tobi schrieb: > SREG wird in eine globale Struktur vom Typ task gesichert, die mit > deklaration volatile versehen ist. und wo liegt die? im RAM oder? Die liegt auf dem Stack. Du brauchst sie also nicht auf den Stack zu schieben, da ist der Wert der lokalen Variablen bereits. RAM: peinlich peinlich...
Datum:
@hugo: Das ist ja das Thema...ich hab wirklich nichts abgeschrieben ;( Die Argumentation ist durchweg verständlich, aber was soll ich denn tun? Ich will doch nichts zugeben, was ich definitiv nicht getan hab. Und genauso wie gemeinsamkeiten gibt es eben auch eklatante Unterschiede. Wir diskutieren hier über vielleicht 40 Zeilen Code in mehren 100 Zeilen Code insgesamt. Ob der Code mal rausgegangen ist, das ist eine gute Frage. Der Scheduler ist 5 in den Grundzügen Jahre alt, ausschließen will ich es nicht, aber ich möchte hier auch niemand irgendwas unterstellen. Die Arbeit ist erledigt und abgehakt, darum mach ich mir keine Gedanken. Aber ich werd den Code umschreiben. Ich denke, damit ist allen geholfen, und das Problem ist aus der Welt.
Datum:
hugo schrieb: > Es ist doch legitim, wenn du fremde Codefragmente als Grundlage nimmst > und für deine Belange anpasst und erweiterst. Genau das ist doch die > geistige Arbeit die du da reingesteckt hast, an der du gemessen wirst > und die will/wird dir keiner streitig machen. Aber diese Grundlage musst > du als Quelle angeben, selbst wenn diese unter GPL steht. Günters Arbeit ist nicht unter der GPL gekennzeichnet. Daher reicht eine Quellenangabe nicht aus. > Sei bitte so ehrlich, sonst kommst du spätestens bei der Einreichung > deiner Arbeit in Teufels Küche. Eben. > Überdenke das bitte nochmal! Ja, dringendst.
Datum:
Waum sollte eine globale Variable, welche mit VOLATILE versehen ist, auf dem Stack liegen? Siehe: http://www.imb-jena.de/~gmueller/kurse/c_c++/c_volat.html "Das Schlüsselwort volatile teilt dem Compiler mit, daß die mit name bezeichnete Variable mit dem Datentyp typ durch Ereignisse außerhalb der Kontrolle des Programms verändert werden kann. Der Wert der Variablen muß deshalb vor jedem Zugriff neu aus dem Hauptspeicher eingelesen werden, d.h. er darf nicht in einem Register des Prozessors zwischengespeichert werden. Der Compiler arbeitet bei mit volatile deklarierten Variablen ohne jede Optimierung, d.h. läßt die entsprechenden Werte bei jedem Zugriff neu aus dem Hauptspeicher laden und sorgt bei Veränderungen dafür, daß die neuen Werte ohne Verzögerung dort sofort abgelegt werden." ergo liegt die Variable auf einer fixen Adresse im Hauptspeicher. Die Speichersegmentierung beim Atmel sieht dafür den bereich .data vor, der für Variablen reserviert ist. Was natürlich nicht ausschließt, das lokale Variablen auf dem Stack liegen können, aber diese Variable ist eben nicht lokal.
Datum:
Frank M. schrieb: > Die liegt auf dem Stack. Du brauchst sie also nicht auf den Stack zu > schieben, da ist der Wert der lokalen Variablen bereits. Ich sehe gerade, dass es eine globale Variable sregsys ist. Das hatte ich übersehen, da ich davon ausgegangen bin, dass sregsys natürlich lokal ist. Besser wäre in jedem Falle eine lokale Variable, damit die Funktionen, wo das SREG gesichert werden, auch reentrant werden. Wenn das nicht notwendig ist, kannst Du das natürlich auch lassen.
Datum:
Frank M. schrieb: > Günters Arbeit ist nicht unter der GPL gekennzeichnet. Daher reicht eine > Quellenangabe nicht aus. > ist mir bewußt und hatte ich nur als weiteres Beispiel gemeint, dass auch GPL-Software (bzw. OpenSource im allgemeinen) nicht zur sorglosen "Bedienmentalität" einladen sollte, ohne die Quellen wasserdicht anzugeben... hatte mich etwas missverständlich ausgedrückt.
Datum:
Sorry, was das andere Thema angeht, da werde ich nur den Code umschreiben. Ansonsten gibts da nicht viel zu überdenken, denn da kann ich ein reines Gewissen haben, tut mir leid. Wenn jemand anderer Meinung ist - ok. Aber das ändert nichts daran, dass der Code von mir stammt. sorry. Ich gebe aber ehrlich zu, das ich vieles zusammenschneidern musste, und das ich froh bin, dass der Scheduler überhaupt läuft. Manches habe ich auch per trial&error ermittelt. gruß tobi
Datum:
@Frank: Ja kann man so machen. Ich gebe ehrlich zu, dass war reine bequemlichkeit. mal sehen, ob ich sreg/sregsys nicht lokal anlege.
Datum:
Zum Abschluß: Wie kommen wir jetzt mit der leidigen Code-Thematik übberein? Ich werde den Code umschreiben, aber was muss ich dabei beachten? Frank, kannst du mir da helfen?
Datum:
hacker-tobi schrieb: > Sorry, was das andere Thema angeht, da werde ich nur den Code > umschreiben. Ansonsten gibts da nicht viel zu überdenken, denn da kann > ich ein reines Gewissen haben, tut mir leid. Wenn jemand anderer Meinung > ist - ok. > Aber das ändert nichts daran, dass der Code von mir stammt. sorry. > ... willst du es nicht verstehen? Wenn du nicht abgeschrieben hast (und du bestehst ja darauf, was dein Recht ist), dann hat der andere abgeschrieben! Und das ist der Knackpunkt, du musst dann deine(!) Rechte geltend machen, sonst kann es ganz leicht passieren das deine Arbeit hinfällig wird und sich fremde Leute mit deinen Federn schmücken (und u.U. irgendwann mal Geld damit verdienen). Im schlimmsten Fall meldet sich der Andere und macht seine Urheberrechteansprüche geltend... Ich würde es genau aus diesem Grund nicht so leichtfertig abtun, wie leben (leider) nicht im Software-Sozialismus. Geistige Arbeit wird nicht als gesellschaftliches Gemeingut angesehen, sondern wird knallhart als Kapital verwendet.
Datum:
hacker-tobi schrieb: > Zum Abschluß: Wie kommen wir jetzt mit der leidigen Code-Thematik > übberein? Ich werde den Code umschreiben, aber was muss ich dabei > beachten? Umschreiben bringt gar nichts. Geistiges Eigentum bleibt auch bei künstlichem Verfremden des Codes erhalten. Sonst könnte ja jeder einfach ein paar Variablennamen/Funktionsnamen umbenennen und fertig. Man kann auch eine Kaffeemaschine nicht als eigene Erfindung ausgeben, nur weil man sie umgefärbt hat. Die ganze Datenstruktur (und damit auch die benötigten Funktionen) bekommst Du nur weg durch komplettes Neuprogrammieren - ohne Hinsehen auf den alten Code. Ich selbst habe schon mehrfach eigenen Code komplett neugeschrieben, weil er durch immerwährende Erweiterungen historisch wuchs und irgendwann unhandlich wurde. Das Bezeichnende daran ist: Was man selbst einmal entworfen hat, codiert man beim zweiten Mal in einem Bruchteil der Zeit: einfach, weil man die damaligen Gedankengänge im Kopf eingebrannt hat und einen Fehler, nach dem man damals stundenlang suchte, bestimmt kein zweites Mal macht. Wenn es also Dein eigener Code ist, dürfte es für Dich ein leichtes sein, die entsprechenden Codeteile neu zu programmieren, denn Du hast Dein Programm ja im Kopf. > Frank, kannst du mir da helfen? Ich wüsste nicht, wie.
Datum:
@hugo:Ich versteh das Grundproblem. Du hast recht, von der Seite hab ich es noch nicht betrachtet. Ok, was den jetzigen Stand angeht, lasse ich es auf sich beruhen. Den neuen Code würde ich gerne als open source nach GNU GPL o.ä. veröffentlichen. Was gibt es dabei zu beachten? Ich gestehe ehrlich, das ich mich bis jetzt nicht besonders um Lizenzen und ähnliches bemüht habe. Mir war es bis jetzt egal, wenn jemand den Code verwandt hat, auch kommerziell. Ich schreibe das in meiner Freizeit und weil ich Spass daran habe. Bei Lösungen, die ich selbst verkaufe, habe ich den code nie veröffentlicht. Das mag naiv klingen, aber so war bis jetzt mein Denken. Durch diese Diskussion wurde ich eines besseren belehrt. Aus Fehlern lernt man eben. @Frank: Ich wills nicht verfremden, ich werds neu schreiben. Und dabei gleich einige der Anregungen von hier mit aufnehmen. Ich weiß aber momentan noch nicht, wann ich dazu komme. Ich poste hier, wenn ichs fertig hab. Ich bezog das weiterhelfen darauf, wie ich den Code so gestalte, dass es keine Probleme bezüglich der Verwechslung mit gos mehr gibt. Und da hast du mir mit der Aussage schon geholfen. Danke.
Datum:
Ich habe Günter Greschenz informiert, mit der bitte, sich mit mir in Verbindung zu setzen. Hallo Hr. Greschenz, folgendes Problem: Ich habe -wie sie- ein OS für AVR Mikrocontroller geschrieben, siehe auch: Beitrag "Re: NeuesOS für AVR Mikrocontroller" Leider sind sich unsere Scheduler und die Task-Verwaltung extrem ähnlich, was den Verdacht ausgelöst hat, dass hier einer von uns abgeschrieben hat. Um es vorweg zu nehmen: Ich denke nicht, dass sie bei mir kopiert haben, aber ich habe bei ihnen auch nicht abgekupfert. Meine Frage: Wie können wir das Problem lösen? Ich biete ihnen an, das ich meinen Code neuschreibe, um die Ähnlichkeiten auszuschließen, falls sie das möchten. Dann wäre das Thema definitiv aus der Welt. Bitte melden sie sich per mail an xxxxx bei mir. Gern auch telefonisch unter xxxxxxxxxxx Mit freundlichen Grüßen, Tobias W. (hacker-tobi).
Datum:
hacker-tobi schrieb: > Den neuen Code würde ich gerne als open source nach GNU GPL o.ä. > veröffentlichen. Was gibt es dabei zu beachten? Ich mache es so: 1. Ich schreibe in den Kopf einer jeden Source-Datei folgenden Kommentar:
/*---------------------------------------------------------------------
* FILENAME
*
* Copyright (c) 2010 NAME - MAIL ADDRESS
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*------------------------------------------------------------------------
*/
|
2. Ich lege ins Gesamtpaket eine Kopie der Datei
http://www.gnu.org/licenses/gpl.txt
Andere Fassungen findet Du unter
http://www.gnu.org/licenses/licenses.html#GPL
Datum:
hacker-tobi schrieb: > @hugo:Ich versteh das Grundproblem. Du hast recht, von der Seite hab ich > es noch nicht betrachtet. Ok, was den jetzigen Stand angeht, lasse ich > es auf sich beruhen. > naja, deine Entscheidung, ich würde es nicht so leichtfertig betrachten. Immerhin hat, wenn deine Aussagen wirklich zutreffen, jemand deinen Quellcode kopiert und nichtmal unter eine Lizenz gestellt, die ein ungehindertes Weiterverwenden durch anderer (und damit auch dir selbst) ermöglicht. > Den neuen Code würde ich gerne als open source nach GNU GPL o.ä. > veröffentlichen. Was gibt es dabei zu beachten? > du deklariert dies einfach so. Es gibt gewisse Regeln, wie das gemnacht wird. Wichtig ist, dass du jede Quelltextdatei mit einem entsprechenden Hinweis versiehst und den vollständigen GPL-Text als Datei mitlieferst bzw. verweist wo er zu finden ist. Wie man es genau macht, findet man recht leicht im Internet auf den entsprechenden Seiten. (Viele OS-Editoren nehmen einem auch die Arbeit ab und haben entsprechedende Funktionen, mit dem man soetwas per Tastendruck erledigen lassen kann.) > Ich gestehe ehrlich, das ich mich bis jetzt nicht besonders um Lizenzen > und ähnliches bemüht habe. Mir war es bis jetzt egal, wenn jemand den > Code verwandt hat, auch kommerziell. Ich schreibe das in meiner Freizeit > und weil ich Spass daran habe. > sagen wir mal so, Freizeit ist ok, solange man die verbrachte Zeit auch wirklich als Vergnügen ansieht. Ich mache es teilweise auch so und gebe z.B. hier einfach Quelltexte (manchmal gedankenlos)) weiter und freue mich, wenn es andere Leute gebrauchen können --> reines Hobby. Sehe den Aufschrei, den es hier jetzt in deinem Fall gab, bitte "dir wohlgesonnen". Immerhin willst du deinen Quelltext für eine Arbeit verwenden, die schon einen offizielleren Charakter hat (und die letztendlich auch Geld bedeutet)... und da hört der Spaß auf, die Welt draussen ist erst mal grundsätzlich böse!
Datum:
Tobias W. schrieb: > Ich habe Günter Greschenz informiert, mit der bitte, sich mit mir in > Verbindung zu setzen. Alle Achtung, das hätte ich nicht von Dir gedacht! > Ich biete ihnen an, das ich meinen Code neuschreibe, um die > Ähnlichkeiten auszuschließen, falls sie das möchten. Dann wäre das Thema > definitiv aus der Welt. Alternativen wären: 1. Ausstellung einer Source-Lizenz an Dich Oder 2. Anerkennung des Sources als Dein rechtliches Eigentum Das wäre dann mit weniger Arbeit verbunden. Gut, dann ist auch für mich diese Sache erstmal (vorerst) vom Tisch.
Datum:
Frank M. schrieb: > 2. Anerkennung des Sources als Dein rechtliches Eigentum > genau das würde ich auch fordern, wenn die Tatsachen wirklich so liegen! (immerhin schmückt sich hier jemand mit fremden Federn...) Grüße Uwe Berger
Datum:
Ok, danke für die Hinweise. Ich werde mich mit Günther absprechen, und dann sehen, wie wir hier weiter vorgehen. Bis dahin lass ich erstmal alles so wie es ist. Und ggf.schreibe ich den Scheduler und teile der Taskverwaltung eben neu. Das wird schon... Das was mich hier anfänglich sehr gestört hatte, war der "Ton", in dem manche Leute hier auf mich losgegangen sind. Darum hatte ich so heftig reagiert. Ich bin aber genauso an einer Lösung interessiert, daher auch die Kontaktaufnahme mit Günther. Also, wieder zurück zum Ursprung ;) @Roman und alle anderen: Eure Änderungen sind nicht vergessen. @Mar IO: Wegen dem ISR: Kompilieren tuts bei mir auch, aber es läuft nicht wirklich. Es werden eben immer wieder Register überschrieben. Hier kann ich unterstüttzung bei der Fehlersuche gut brauchen....
Datum:
Tobias W. schrieb: > Das was mich hier anfänglich sehr gestört hatte, war der "Ton", in dem > manche Leute hier auf mich losgegangen sind. Daran muss man sich einfach gewöhnen. Wenn man etwas öffentlich macht, dann steht man auch in der Öffentlichkeit, d.h. man muss sich ihr stellen. Ich habe das in den letzten 9 Jahren freier Software-Entwicklung oft genug durchgemacht. Mit der Zeit bekommt man zwar ein dickes Fell, aber eines lernt man gewiss: Die User ernstzunehmen. Wenn da jemand ein gravierendes Problem sieht, dann sollte man das auch ernstnehmen. Es hat mich ungemein genervt, dass Du diese Kritikpunkte mehrfach einfach abgetan hast mit den Worten: "Reden wir nicht mehr drüber, für mich ist das Thema damit abgehakt". Das ist genau der falsche Weg. Man kann ein Problem nicht einfach dadurch lösen, dass man es ignoriert. Besser ist es, sich den Usern zu stellen. Dann wirst Du glücklich mit ihnen - und sie mit Dir auch. Du musst zugeben: Die Code-Übereinstimmung ist frappierend. Da Günters Veröffentlichung wesentlich älter ist als Deine, kannst Du es uns auch nicht übelnehmen, wenn man da zunächst in eine ganz bestimmte Richtung denkt. Von daher ist das "Auf-Dich-Losgehen" durchaus nachvollziehbar. ;-)
Datum:
@Frank: Klar, nachvollziehbar ist es. Du hast recht, ich war auch nicht unbedingt ein Vorbild. Von daher entschuldige ich mich, falls sich jemand ungerecht behandelt gefühlt hat, das war hier nicht meine Absicht. Ich bitte einfach alle (inkl. mir selbst), doch mal ihren Ton zu überdenken. Das macht ne Menge aus... Trotz allem hoffe ich das das kleine OS anklang findet, und gern auch für eigene Ideen eingesetzt werden kann. Mal sehn was aus dem Scheduler wird. Ich versuche momentan immer noch zu verstehen, warum es mit ISR() nicht richtig klappt...warum werden da Register überschrieben? Oder hab ich irgendwo nen Denkfehler?
Datum:
Tobias W. schrieb: > Ich bitte einfach alle (inkl. mir selbst), doch mal ihren Ton zu > überdenken. Dann bist Du zu zart besaitet. Der Ton hier ist den Umständen entsprechend, da gibt es wesentlich heftigere Diskussionen (die ich sogar auch noch als "normal" ansehen würde). Wir sind (normalerweise) alles erwachsene Menschen, die nicht mehr im Kindergarten sind. Gewöhn Dich schon mal daran. ;-) > Trotz allem hoffe ich das das kleine OS anklang findet, und gern auch > für eigene Ideen eingesetzt werden kann. Mal sehn was aus dem Scheduler > wird. Ich finde das Thema spannend, deshalb habe ich hier in den letzten Tagen öfter mal reingeschnuppert, ohne aber den Code zu lesen, sondern erstmal zu schauen, wie sich das hier entwickelt. Momentan habe ich selbst eigentlich auch gar keinen Bedarf - aber wer weiß: kommt eine Idee, kann man ja auf so etwas durchaus mal zurückgreifen. > Ich versuche momentan immer noch zu verstehen, warum es mit ISR() nicht > richtig klappt...warum werden da Register überschrieben? Oder hab ich > irgendwo nen Denkfehler? Ich schaue es mir mal am Wochenende in Ruhe an. Wenn ich was finde, melde ich mich dazu.
Datum:
Ich habe mir den Source mal kurz angeschaut. Aus einer ISR darfst Du nicht selbst mit RETI springen, das macht Dein Compiler selbst. Das war auf µC.net schon oft das Thema - und wie ich jetzt hier auch sehe, hat Dich Gast "mar IO" auch schon darauf angesprochen. Du rufst aus der ISR die Funktion scheduler() auf und dort machst Du einen RETI. Damit machst Du den Stack, den sich der Compiler beim Übersetzen der ISR und der Funktion secheduler() selbst gebaut hat, kaputt. Besser gesagt: Du baust den Stack, der bei jedem ISR-Aufruf aufgebaut wird, nicht wieder korrekt ab. Vielleicht schaust Du Dir den vom Compiler erzeugten ASM-Code für die ISR und für scheduler() mal an und prüfst den auf saubere Stackbehandlung. Mein Tipp: Nimm das RETI raus, der Compiler macht das schon für Dich. Wenn Du jedoch befürchtest, dass dann das Task-Switching nicht mehr funktioniert, weil dadurch der Kontext-Wechsel nicht mehr sauber ist, musst Du die ISR selbst mit dem Attribut "naked" versehen (ich hoffe, das geht auch mit ISRs, habe ich noch nie gemacht) und den Code von scheduler() direkt in die ISR reinkopieren, damit da ja nichts mehr mit dem Stack passiert. Dann könntest Du das RETI am Ende der ISR machen - aber nur dann und auch nur dort. Die Funktion scheduler() entfällt dann komplett. Ich glaube "mar IO" hat das Problem schon richtig erkannt - näheres kann ich mir aber auch nur erlauben zu sagen, wenn ich das Ding mal durch den Compiler gejagt und mir den Assembler-Teil näher angeschaut habe.
Datum:
Hi Frank, du hast recht, Mario hatte das auch schon erkannt, und ich hatte es gestern auch schonmal so umgesetzt, aber das hat eben nicht wirklich geklappt. Aber stimmt, das könnte sein, das ich da gestern über das reti gestolpert bin, und das es deswegen nicht funktioniert hat. Werd ich am WE mal testen, danke dir.
Datum:
Frank M. schrieb: > Umschreiben bringt gar nichts. Geistiges Eigentum bleibt auch bei > künstlichem Verfremden des Codes erhalten. Geistiges Eigentum bzw. Urheberrecht setzt eine gewisse Schöpfungshöhe voraus. Dass die in der Formatierung von Code zum pushen und popen von ein paar Registern oder der in der Benennung von Funktionen besteht will ich mal bezweifeln.
Datum:
Andreas Schwarz schrieb: > Geistiges Eigentum bzw. Urheberrecht setzt eine gewisse Schöpfungshöhe > voraus. Dass die beim pushen und popen von ein paar Registern gegeben > ist will ich mal bezweifeln. Das ist natürlich korrekt ;-) Beim zweiten Hinsehen sieht man aber, dass ganze Funktionen und Datenstrukturen identisch sind - es sind nicht 5 Zeilen, es sind garantiert über hundert, vielleicht sogar über 200 Zeilen Code identisch. Da fallen die Pushs/Pops gar nicht mehr ins Gewicht.
Datum:
Hallo ??? Kann mir jetzt einmal jemand sagen, um was es hier eigentlich geht ?? Das herumhacken und herumzicken geht langsam auf dem sack. Geht es jetzt um technische weiter entwicklung oder ob jemand etwas veroeffentlicht unter GNU und dabei wo moeglich einige Code fragmente verwendet hat, die schon unter GNU stehen ?? hmm.. Wie es schon Tobi irgendwo geschrieben hat.. geht es um grundlegende frage von dem Ton "C" oder das was man mit den Ton Musik macht ?? Mal ganz abgesehen davon, das alle taskswitching routinen so ziemlich gleich aussehen !! zb. Die von Linus, ist verdammt aehnlich mit der von BSD oder SVR4 !! weil sie alle so oder so das selbe tun muessen!! Oder Wollt Ihre alle wirklich sagen, das Ihr in euren Codes alle quellen angeben, von wo und von wem Ihr eure Codes habt ?? Stelle ich mein Code in ein Oeffentliches Forum, so kann ich doch nicht wirklich auch noch verlangen von den Usern, das sie mir ein email schicken und copyright meldungen in den code reinschreiben und und und.. und Wollt ihr tatsaechlich zurueck gehen bis zum Donald Knuth und dem TAOCP ?!! Neben bei gesagt.. Wo im Gos, sind semaphoren, wo sind queue's, wo ist memory mgr. !! Wo sind die Hinweise, das im avr basic interpreter auf mein code verwendet wird und meine ideen :) Hoert doch auf euch wie kleine kinder zu benehmen.. lg roman
Datum:
@ Roman65536 Dein Geschreibsel ist kaum zu ertragen, weder Inhalt noch Form genügen der Netiquette.
Datum:
Roman65536 schrieb: > Kann mir jetzt einmal jemand sagen, um was es hier eigentlich geht ?? > Das herumhacken und herumzicken geht langsam auf dem sack. Hättest Du erstmal ruhig bis zum Ende gelesen, hättest Du gemerkt, dass alle Wogen bereits wieder geglättet sind. > Geht es jetzt um technische weiter entwicklung oder ob jemand etwas > veroeffentlicht unter GNU und dabei wo moeglich einige Code fragmente > verwendet hat, die schon unter GNU stehen ?? hmm.. Es geht um Codeteile (hacker-tobi spricht selbst von 100 Zeilen), die eben nicht unter GPL stehen. Da gab es schon im UNIX-Umfeld ziemlich große Streitwerte, die vor Gericht landeten, weil es da gerade mal um 4 (?) Zeilen ging... Außerdem: Es gibt Leute, die verdienen mit Ihrem Code ihr täglich Brot, wie ich zum Beispiel - auch wenn ich ein Verfechter der GPL bin. Programmieren ist harte Arbeit und das Klauen von Code ist kein Kavaliersdelikt. > Mal ganz abgesehen davon, das alle taskswitching routinen so ziemlich > gleich aussehen !! zb. Die von Linus, ist verdammt aehnlich mit der von > BSD oder SVR4 !! weil sie alle so oder so das selbe tun muessen!! Ah, Du hast die Taskwitching-Routinen von SVR4 gesehen? In welchem Umfeld, wenn ich fragen darf? Natürlich ist es klar, dass gleiche Problemstellungen zu ähnlichem Code führen. Hier geht es aber um absolut identischen Code. > Hoert doch auf euch wie kleine kinder zu benehmen.. Die Verwendung der mehrfachen Satzzeichen, wie in "Hallo ???", wie Du z.B. Deinen Beitrag hast beginnen lassen, macht auf mich einen wesentlich unfreundlicheren Ton aus als alle heutigen Beiträge in diesem Thread zusammen. Woran liegt das wohl?
Datum:
So ihr hört jetzt auch auf zu zanken ;) Es bringt doch nix, und macht nur den Thread kapput. gruß tobi
Datum:
Angehängte Dateien:Ich hab mir grad die ASM-Files gezogen, einmal nach meiner Methode und
einmal mit ISR und Attribut (signal, naked).
Anbei beide Files.
Die differenz ist gut erkennbar, und besteht nur im proloque/epiloque.
Baut man das ganze in c nach, und verwendet es als ISR, funktioniert es.
Die Datei "...with..." ist die funktionsfähige Version, die andere eben
die defekte.
Baue ich das ganze in C nach, funktioniert es ebenfalls (ist ja klar):
void TIMER_VECTOR() _attribute_ ( ( signal, naked ) );
ISR(TIMER_VECTOR)
{
asm("push __zero_reg__");
asm("push __tmp_reg__");
asm("in _tmp_reg_,__SREG__");
asm("push __tmp_reg__");
asm("clr __zero_reg__");
asm("push r18");
asm("push r19");
asm("push r20");
asm("push r21");
asm("push r22");
asm("push r23");
asm("push r24");
asm("push r25");
asm("push r26");
asm("push r27");
asm("push r30");
asm("push r31");
scheduler();
asm("pop r31");
asm("pop r30");
asm("pop r27");
asm("pop r26");
asm("pop r25");
asm("pop r24");
asm("pop r23");
asm("pop r22");
asm("pop r21");
asm("pop r20");
asm("pop r19");
asm("pop r18");
asm("pop __tmp_reg__");
asm("out _SREG_,__tmp_reg__");
asm("pop __tmp_reg__");
asm("pop __zero_reg__");
asm("reti");
}
Es gibt 2 Fehlerbilder:
Wenn ich den scheduler direkt einfüge (statt des Aufrufs scheduler() )
ist schicht, es geht gar nichts mehr.
Allerdings wird die ISR komplett abgearbeitet. Eventuell scheitert der
Rückspung oder das wiedereinschalten der Interrupts.
Das selbe gilt auch, wenn ich statt reti nur ein return verwende.
Das interessante in diesem Fall ist, dass schon der Rücksprung aus
Scheduler() in die ISR schiefgeht. Der Scheduler wird bis zu ende
abegarbeitet, aber in die ISR kehrt er nie zurück. Das habe ich mangels
debug-hardware mit nem simplen PORTD = 0x01 (LED an PD1 an) geprüft.
Wenn ich den alles bis auf den aufruf weglasse, läuft es zwar im
prinzip, aber es werden eben Register überschrieben.
Ich bin heut vermutlich einfach zu kaputt, um dahinterzukommen. oder zu
blöd ;)
Jedenfalls werden im proloque / epilog nur einige Register, sowie das
SREG gesichert und wiederhergestellt - eben normale Kontextsicherung und
-wiederherstellung. Irgendwas läuft hier schief.
Any Ideas?
Datum:
Ich habe bis jetzt noch nichts von Hr. Greschenz gehört, aber ich habe mein OS zum teil umgeschrieben, und ihm dies auch mitgeteilt. Ich werde die neue Version veröffentlichen, wenn ich mich mit ihm abgestimmt habe, um Probleme zu vermeiden. gruß tobi
Datum:
Ohne jetzt hier bewerten zu wollen, wer nun von wem abgeschrieben hat
(und ob überhaupt!):
Ich halte es durchaus für möglich, dass beide Autoren eine gemeinsame
Quelle hatten, die durchaus dafür sorgen kann, dass man mit bestimmten
Ideen geimpft wird und in der Folge - gerade bei einer doch ziemlich
weitgehend vorgezeichneten Aufgabe wie hier - verdammt ähnlichen Code
produziert.
Wer weiß, vielleicht hat Schwabl sich von GOS inspirieren lassen... :-)
Viele Grüße,
Simon
Datum:
Denkbar ;) Vor allem da Schwabl und Tanenbaum (das war das 2. Buch, dessen Name fiel mir vorhin nicht ein) auch nicht so ganz unbekannt und auch ziel zitiert sind (legal wie illegal). Na ja, wie auch immer. Ich hab mein OS angepasst, und mit Hr. Greschenz Kontakt aufgenommen. Mehr kann ich zur Zeit eh nicht tun ;) Ich wünsche einen guten Morgen. tobi
Datum:
Frank M. schrieb: > Du rufst aus der ISR die Funktion scheduler() auf und dort machst Du > einen RETI. Damit machst Du den Stack, den sich der Compiler beim > Übersetzen der ISR und der Funktion secheduler() selbst gebaut hat, > kaputt. Besser gesagt: Du baust den Stack, der bei jedem ISR-Aufruf > aufgebaut wird, nicht wieder korrekt ab. > > Vielleicht schaust Du Dir den vom Compiler erzeugten ASM-Code für die > ISR und für scheduler() mal an und prüfst den auf saubere > Stackbehandlung. siehe Beitrag "Re: NeuesOS für AVR Mikrocontroller" war beim AVR-GCC mit Optimierungsstufe 3
//+++++++++++++++++++++Signal-Handler++++++++++++++++++
SIGNAL (SIG_OVERFLOW0)
{
1646: 1f 92 push r1
1648: 0f 92 push r0
164a: 0f b6 in r0, 0x3f ; 63
164c: 0f 92 push r0
164e: 11 24 eor r1, r1
1650: 8f 93 push r24
1652: 9f 93 push r25
1654: ef 93 push r30
1656: ff 93 push r31
//****************************************************
void scheduler()
{
//save R0-31 to current->stack
PUSH(31);PUSH(30);PUSH(29);PUSH(28);PUSH(27);PUSH(26);PUSH(25);PUSH(24);
1658: ff 93 push r31
165a: ef 93 push r30
165c: df 93 push r29
165e: cf 93 push r28
1660: bf 93 push r27
1662: af 93 push r26
1664: 9f 93 push r25
1666: 8f 93 push r24
PUSH(23);PUSH(22);PUSH(21);PUSH(20);PUSH(19);PUSH(18);PUSH(17);PUSH(16);
1668: 7f 93 push r23
166a: 6f 93 push r22
166c: 5f 93 push r21
166e: 4f 93 push r20
1670: 3f 93 push r19
1672: 2f 93 push r18
1674: 1f 93 push r17
1676: 0f 93 push r16
PUSH(15);PUSH(14);PUSH(13);PUSH(12);PUSH(11);PUSH(10);PUSH( 9);PUSH( 8);
1678: ff 92 push r15
167a: ef 92 push r14
167c: df 92 push r13
167e: cf 92 push r12
1680: bf 92 push r11
1682: af 92 push r10
1684: 9f 92 push r9
1686: 8f 92 push r8
PUSH( 7);PUSH( 6);PUSH( 5);PUSH( 4);PUSH( 3);PUSH( 2);PUSH( 1);PUSH( 0);
1688: 7f 92 push r7
168a: 6f 92 push r6
168c: 5f 92 push r5
168e: 4f 92 push r4
1690: 3f 92 push r3
1692: 2f 92 push r2
1694: 1f 92 push r1
1696: 0f 92 push r0
...
POP( 0);POP( 1);POP( 2);POP( 3);POP( 4);POP( 5);POP( 6);POP( 7);
171e: 0f 90 pop r0
1720: 1f 90 pop r1
1722: 2f 90 pop r2
1724: 3f 90 pop r3
1726: 4f 90 pop r4
1728: 5f 90 pop r5
172a: 6f 90 pop r6
172c: 7f 90 pop r7
POP( 8);POP( 9);POP(10);POP(11);POP(12);POP(13);POP(14);POP(15);
172e: 8f 90 pop r8
1730: 9f 90 pop r9
1732: af 90 pop r10
1734: bf 90 pop r11
1736: cf 90 pop r12
1738: df 90 pop r13
173a: ef 90 pop r14
173c: ff 90 pop r15
POP(16);POP(17);POP(18);POP(19);POP(20);POP(21);POP(22);POP(23);
173e: 0f 91 pop r16
1740: 1f 91 pop r17
1742: 2f 91 pop r18
1744: 3f 91 pop r19
1746: 4f 91 pop r20
1748: 5f 91 pop r21
174a: 6f 91 pop r22
174c: 7f 91 pop r23
POP(24);POP(25);POP(26);POP(27);POP(28);POP(29);POP(30);POP(31);
174e: 8f 91 pop r24
1750: 9f 91 pop r25
1752: af 91 pop r26
1754: bf 91 pop r27
1756: cf 91 pop r28
1758: df 91 pop r29
175a: ef 91 pop r30
175c: ff 91 pop r31
asm volatile("reti");
175e: 18 95 reti
scheduler();
}
1760: ff 91 pop r31
1762: ef 91 pop r30
1764: 9f 91 pop r25
1766: 8f 91 pop r24
1768: 0f 90 pop r0
176a: 0f be out 0x3f, r0 ; 63
176c: 0f 90 pop r0
176e: 1f 90 pop r1
1770: 18 95 reti
|
Datum:
So, ich hab jetzt genug drüber nachgedacht, und denke, dass ich das
Rätsel um das reti nun mal aufklären kann:
Ok es ist etwas unsauber, da es ersten Start eines Tasks tatsächlich
dazu kommt, das er nicht mehr in die ISR zurückspringt (daher
funktionierte auch "return" im Scheduler nicht), da er hier den von
task_create() vorgegeben Initialwert des PC für den Rücksprung nutzt.
Aber danach springt er in die ISR, und der Stack wird auch wieder
abgebaut. Der Grund dafür ist der zweistufige Einsprung in den
Scheduler:
Zunächst springt der in die ISR, und die Rücksprungadresse landet auf
dem Stack.
Dann sichert er dort einige Register auf dem Stack, und ruft den
Scheduler auf, wobei jetzt die Rücksprungadresse in die ISR auf dem
Stack landet.
Der Scheduler sichert nun den Kontext und schaltet den Task um, wobei
auch der SP verändert wird.
Das macht aber nichts, denn das eben gesagte gilt für alle Tasks. Somit
findet er nach dem zurücksichern des Kontext wieder den Rücksprung in
die ISR. Für diesen Task werden zusätzlich innerhalb der ISR noch einige
Dinge vom Stack gelesen. Und dann wird wieder in den Task selbst
verzweigt.
Ich hab zwar keinen debugger hier, aber eine simple Zählvariable in der
ISR hinter dem Scheduler-Aufruf, ausgegeben auf PORTC oder sonstwo,
verrät einem, das ich Recht habe ;)
So erzeugt z.B.
SIGNAL (SIG_OVERFLOW0)
{
scheduler();
PORTC++;
}
ein mit der Freuenz der Scheduler-Aufrufe hochzählendes binärlauflicht
;)
Ich hoffe ich hab mich hier verständlich ausgedrückt...
Was ich interessanter finde ist die Tatsache, dass der proloque/epiloque
überhaupt notwendig ist, aber ok...das System ist insgesamt recht
komplex. Ich möchte jetzt nicht den ganzen Code durchforsten, aber da
gibts bestimmt noch irgendwo ein paar Dinge außerhalb der eigentlichen
Tasks, die gesichert werden, wie z.B. Rücksprungadressen und lokale
Variablen.
Aber da ließe sich bestimmt noch optimieren.
Fakt ist, mit dieser Variante funktioniert das System unabhängig vom
Optimierunslevel etc. sehr gut. Ändere ich es, in dem ich den Scheduler
direkt in die ISR packe, und dort "naked" verwende, ist zwar der
proloque/epiloque weg, aber es gibt eben auch massive Probleme mit den
Tasks untereinander. Das Multitasking arbeitet zwar, aber es kommt zu
Interferenzen zwischen den Tasks.
Ich selbst kann mit den paar Befehlen proloque/epiloque zur Zeit leben.
Es ist zwar interessant, mal rauszubekommen, ob es da noch Potential
gibt, aber ich bin zur Zeit dabei, mich in nen neuen Job einzuarbeiten,
und privat will man ja auch nochmal was anderes tun ;)
Wenn mal zeit ist, grabe ich mich da gern durch. Auch jeder der dies
liest, ist dazu eingeladen. Ansonsten bleibt der Scheduler erstmal, wie
er ist.
gruß
tobi
Datum:
... deine letzten Postings lesen sich so, als hättest du den Scheduler nicht geschrieben und müsstest jetzt erst rausfinden, was der überhaupt macht und wie er funktioniert ... Irgendwie glaub ich dir einfach nicht ;-)
Datum:
hi Helli, in C weiß ich wie der funktioniert ;) In Assembler bin ich nicht so der crack. Wie gesagt, manches war trial & error ;) Ich frage mich nur immer noch, warum der proloque/epiloque notwendig ist. aber das schau ich mir echt wann anders in ruhe an, jetzt muss ich erstmal im neuen job ankommen. übrigens...von günther hab ich nichts gehört bis jetzt. ich warte noch etwas und dann werd ich meine geänderte version online stellen. ich denke, ich werde auch romans anregung mit aufnehmen, den stack in ein globales array zu verlagen, und die stackgrößen variabel zu machen. das ist ja nicht soviel arbeit. bis dahin sind weitere anregungen gern wilkomen. gruß tobi
Datum:
hi also für mich als außenstehenden und jemanden der auch hier und da programmiert und versucht ich sehe das so : er hat ein OS gesucht und versucht es zu verstehen wie es arbeitet ihm sind dann einige stellen aufgefallen was man eventuell verbessern könnte bzw erweitern ... das ist lobenswert und würde auch den author von GOS glücklich machen was mir daran so misfällt: er "verkauft" es als sein OS trotz dessen es hunterte zeilen sind die wirklich identisch sind sogar variablen gleich .. ja sogar kommentare ich würde vermuten sogar schreibfehler und groß/kleinschreibung für mich is der typ nen blender der sich hier ma etwas wichtig machen will ich hätte es besser gefunden bei der wahrheit zu bleiben ... er hat GOS erweitert vlt verbessert ... mehr nicht es aber nach so vielen beweisen immernoch abzustreiten ... ist etwas .. naja ... dreist
Datum:
Hi fremder (interessanter name), ich hoffe, du hast auch gelesen, das mein Scheduler älter ist als GOS. Aber es ist schon richtig, ich habe im Rahmen einer Diplomarbeit die Funktionsgrundlagen für ein OS definiert, und daraus ist dann eben Nano OS entstanden. Und es sind ca 100 Zeilen, mal abgesehen davon, dass GOS ein reiner Scheduler ist, und nano os sehr viel mehr Funktionen bietet. Aber ok, ich kann auch jeden verstehen, der da anders denkt. Das die Sachlage aus Sicht des Forums eine andere ist, ist klar, und ich kann es nicht beweisen. Ich will und werde aber auch dem GOS-Author keinen Vorwurf machen, zumal ich denke, dass wir evtl. schlicht die gleichen Quellen benutzt haben. Aber wie auch bereits geschrieben, habe ich den Scheduler nochmal überarbeitet, damit die identischen Teile weg sind. Und ich habe mich auch mit dem Author von GOS in Verbindung gesetzt, der sich aber bis heute nicht gemeldet hat. Ich warte noch etwas ab, weil ich mich eigentlich mit ihm abstimmen möchte, bevor ich die neue Version online stelle. Aber wenn da in nächster Zeit nichts kommt, dann geht das Ding online. Diesmal zur Sicherheit unter GNU GPL. Ansonsten noch "happy coding" und gute n8:) Ich melde mich spätestens wieder, wenn die neue Version online geht.
Datum:
Nochmal was ganz anderes...jetzt wurde hier soviel über den Scheduler geredet...wie siehts denn mit den anderen Teilen aus? Hatte da schonmal jemand gelegenheit, zu testen, und evtl. Anregungen oder Fehler gefunden? Insbesondere würde mich der Bereich der Messages interessieren, denn die Semaphore sind einfach gestrickt, und auch das RAM-Management ist nicht allzu komplex. gruß tobi
Datum:
Eine LETZTE Anmerkung zum Thema der abgeschrieben Scheduler noch: In meiner nano_os.h steht als supported device nur der Mega168. GOS hat da viel mehr devices stehen, den Mega168 übrigens nicht, wenn ich das aktuell richtig im Kopf habe. Ich habs eben auf nem Mega168 getestet und geschrieben, da ich diesen für mein Uhrenprojekt verwendet habe. Ich finde es auch spannend, das in der ganzen Diskussion allein das veröffentlichungsdatum von GOS bzw. nano os und die gemeinsamkeiten zählen. Das ist zwar aus Sicht des Forums verständlich, aber das Veröffentlichungsdatum muss nunmal nicht dem Entwicklungsdatum entsprechen. Und auch die Tatsache, dass der GOS - Author und ich die gleichen Quellen verwendet haben könnten, spielt eine Rolle. Auch wurde scheinbar nur von wenigen zur Kenntnis genommen, das ich hier in die Offensive gegangen bin, und den Author von GOS kontaktiert habe. Ich möchte jetzt auch langsam echt mal wieder zum Ursprung, ergo der technischen Weiterentwicklung zurück. Ich werde den neuen Scheduler in einem neuen Thread veröffentlichen, da ich befürchte, das in diesem Thread keine echte technische Weiterentwicklung mehr entsteht. Damit nicht die Behauptung aufkommt, dass ich hier wegen nem schlechten Gewissen weg will, werde ich auch auf diesen Thread verweisen. Mehr als voll in die Offensive gehen kann ich nicht...und auch aus anderen Gründen möchte ich mich hier zum Thema des Abschreibens nicht mehr äußern. Versteht mich nicht falsch, aber bei mir steht da noch eine Arbeit im Hintergrund, und ich habe mich mit meinem Betreuer über diesen Thread hier ausgetauscht, und darauf geeinigt, dass ich mich hier nicht mehr zu diesem Thema äußern werde. Tut mir leid, aber das hat definitiv Priorität für mich. Technische Anregungen sind weiterhin gerne gesehen, auch im neuen Thread für den neuen Scheduler. Ich poste hier dann den neuen link. so, nun geh ich aber mal ins bett.
Datum:
Hallo Tobias, ich finde es schade, dass einige auf dir herumhacken. Es gibt Leute, die stören sich an jeder Trivialität, selbst an so Dingen wie einem abgeschriebenen "define ...". Da vergeht einem natürlich die Lust, noch irgenndwas zu veröffentlichen. Meine Meinung: Lass Dich nicht von denen entmutigen und gehe Deine Weg einfach weiter. Viele Grüße, Markus
Datum:
Hallo Tobias, bitte, bitte, bitte rücke deinen Code anständig ein. Klar gibt es da verschiedene Stile, aber so bitte nicht. Hier mal einen Auszug, wie man viel lesbarer formatieren könnte:
uint8_t semaphore_free(Semaphor *s)
{
sregsys = SREG;
cli();
if (s->owner != currentTask)
{
SREG = sregsys;
return 0;
}
s->owner = 0;
SREG = sregsys;
return TRUE;
}
//****************************************************
//*semaphore_read(Semaphor *s) *
//* *
//* description: read status of a semaphore *
//* input: Pointer to Semaphore *
//* output: TRUE(free), NULL(error/non free) *
//****************************************************
uint8_t semaphore_read(Semaphor *s)
{
sregsys = SREG;
cli();
if (s->owner)
{
SREG = sregsys;
return 0;
}
SREG = sregsys;
return TRUE;
}
//****************************************************
//*semaphore_wait(Semaphor *s) *
//* *
//* description: wait for a semaphore *
//* input: Pointer to Semaphore *
//* output: TRUE(is free), NULL(error) *
//****************************************************
uint8_t semaphore_wait(Semaphor *s)
{
//enable multitasking to avoid a deadrun
wdt_enable(WDTO_2S);
TIMER_ENABLE |= _BV(TOIE0);
sei();
while (s->owner != 0)
TCNT0 = 0xFF; //Do a task switch if the semaphore is used; ; Do not set this to any other value than 0xFF, it won't work because we are in a loop!
return TRUE;
}
|
Ach ja, es ist bei Kommentaren generell gut, die Zeile nie länger als 80 Zeichen werden zu lassen. Aber das ist auch nur Kosmetik ;-) Gruß, NIco
Datum:
hallo leute :-)
long time no see...
wie ihr gemerkt habe, bin ich schon seit geraumer zeit nicht mehr so
recht aktiv hier :-( mir fehlt einfach momentan die zeit für so ein
tolles hobby... (aber ich habe inzwischen meinen sohn infiziert, mal
schaun... :-)
muss ich das alles jetzt durchlesen ? oje :-)
erstmal meine meinung zu GOS:
-> GOS ist 100% von mir, ohne quellen direkt VHIT !
das kann ich (wenns wirklich unbedingt sein muss, ich müsste heftig
suchen) belegen, da ich entwicklungs-snapshots (zips) habe, die jeder
als authentisch ansehen dürfte !
ich habe es aus reinem interesse geschrieben (damals auf meinem guten
alten palm-pilot) und dann nochmal für den avr...
ich bin dann daran gescheitert eine schöne "sleep(ms)" funktion zu
bauen, da gos ja keinen "festen tick" hat...
die zeitscheibenlänge definiert die priorität, ich hätte dann dafür
einen 2. timer gebraucht (böse ressourcen-verschwendung) und die beiden
dann auch noch irgendwie syncen müssen...
ist das in nano-os drin ? würde mich interressieren wie das gelöst ist /
werden kann. d.h. z.b. wie zeitgenau -> kann ich damit servos steuern ?
und zu nano-os:
-> ich habs mir aus zeitmangel noch nicht angeschaut...
also:
1) "Ich will und werde aber auch dem GOS-Author keinen Vorwurf machen,
..."
-> na danke aber auch ;-)
2) keine ahnung ob tobi nun abgeschrieben hat oder nur inspiriert war
oder was auch immer.
der hintergrund des "(C)" war
a) dass mein name erhalten bleibt (ist grade umso wichtiger, da mein
momentaner arbeitgeber evtl. den standort hier zumacht, und so ne
"google-referenz" ist grade jetzt für mich umso wichtiger, naja, evtl.
hab ich dann ja wieder zeit für GOS&co. !)
b) dass kein kommerz getrieben wird (da will ich dabei sein, kann dann
auch gerne weiterentwickeln :-)
privat habe ich (natürlich !) nichts dagegen
@tobi: have fun damit !
wenn du was schriftliches brauchst / willst mail mich einfach an ! (wenn
nicht dann nicht :-)
ich will und werde dir übrigens auch keinen vorwurf machen :-)
::: aber mal was ganz anderes :::
@alle: mal kurz zu meinem avr-wiz
der läuft immernoch auf weinem wohnzimmer-vdr @home.
da ich aber überhaupt keine zeit habe daran weiter zu bauen oder ihn
auch nur zu warten überlege ich gerade was ich damit mache.
wenn mein vdr nach einer aufnahme runterfährt (was er momentan noch
nicht macht) wäre er in zukunft nur noch zwischen 20:15 und 00:00 zu
erreichen.
ich habe mir nun überlegt, ihn evtl. den "avrfreaks" anzubieten, d.h.
sie könnten ihn in ihre web-präsenz einbauen.
oder ist evtl. "mikrokontroller.net" interessiert (liest hier evtl. ein
admin mit ?) ?
ich will nur nicht, dass er stirbt, die "google-referenz" ist mir auch
hier recht wichtig...
any other ideas ?
bye, gg
Datum:
@Günther: Erstmal danke für die Rückmeldung. Ich habe mit sleep(ms) das selbe Problem. Ist ja auch klar ;). Was ich eingebaut habe ist ein funktion wait_for_laps(), mit der man einen Task eine bestimmte Anzahl von Scheduler-Runden schlafenlegen kann. Ein genaues timing ist damit natürlich nicht möglich, die Funktion dient eher dazu, einen Task "ruhigzustellen", wenn absehbar ist, dass er länger nichts zu tun hat. Zusätzlich gibt es -wie in GOS auch- Funktionen zum Schlafenlegen und Wecken eines Tasks, allerdings mit dem Unterschied, das du ein TaskSignal dafür nutzt, während ich direkt auf den Task selbst arbeite. In meinen Uhrenprojekten habe ich zur Erzeugung des Grundtakts für die Uhr den timer2 genutzt, da ich diesen (beim Mega168) mit einem externem Uhrenquarz betreiben kann. Also auch bei mir kein sleep(ms) oder sonstwas ;( Ansonsten geht die Funktionaliät in nano_os allerdings deutlich weiter, so kann es dynamisch tasks erstellen/verwerfen, und auch Dinge wie Speichermanagement, Semaphore und Message Queues sind dabei. Gerade für diese hätte ich gern noch "Funktionsberichte". Ich habe meinen Scheduler schon neu geschrieben, um die Ähnlichkeiten weg zu bekommen. Dann gibts hier definitiv kein Thema mehr, hoffe ich. Den stelle ich dann in einem neuen thread unter GPL zur Verfügung. Vorher werden noch einiger der hier gesammelten Anforderungen mit aufgenommen, hauptsächlich die Idee, den Stack in ein globales Array zu verlagern. @Nico: Nehme ich mit. Hier hat eben jeder "seinen" Stil. Aber das ist ja kaum Arbeit, und ich denke, da lässt sich was machen. Die Formatierung ist auch in Zusammenhang mit der Diplomarbeit entstanden. Ich gebe dir aber recht, für sich ist sie etwas "schwierig".
Datum:
sorry, muss dich erstmal korrigieren: @Günther: -> @Günter: danke :-) warum ich gos angefangen habe: * ursprünglich wollte ich servos steuern. * "ich kann das, also tu ichs" (1. informatiker-gesetz :-) * einfach mal schaun wie wenig assembler nötig ist (am liebsten hätt ichs ja in c++ gemacht) sollte also von anfang an ein lern/lehr sample werden... warum ich mit gos nicht weitergemacht habe: da ich mit dem verwendeten konzept ein sehr genaues "sleep(ms)" nicht realisieren konnte (die servos flackerten ohne ende) hab es ich dann nicht weiterverfolgt. ich mag es, wenn der unterbau stimmt bevor ich darauf aufbaue, und ein sleep gehört für mich dazu. das wird in recht vielen anwendungen gebraucht... hat evtl jemand ne idee wie man *) ohne 2. timer *) in C :-) einen möglichst genauen timer in gos (oder nano-os :-) einbauen könnte ? da die slice-grössen sich ja verändern müsste man die irgendwie aufsummieren und dann die prio des letzten tasks dynamisch berechnen... hört sich kompliziert an :-(
Datum:
@ Günter Greschenz: Ohne jetzt sehr lange darüber nachgedacht zu haben: Aber wie wäre es, den einen Timer einfach schneller laufen zu lassen und damit dann die anderen Timer "emulieren"? Also wenn ich einen 200-ms-, einen 500-ms- und einen 1000-ms-Timer brauche, dann initialisiere ich einfach einen 100-ms-Timer und kann damit alle anderen Auflösungen emulieren, wenn du verstehst, was ich meine. Gruß, Nico
Datum:
Erstens: Man könnte die Prioritäten weglassen, und einfach alle x
Systemtakte via TimerXX_ovf umschalten.
Dann wäre ein sleep() problemlos machbar, aber es stünden eben auch
keine Prioritäten mehr zur Verfügung.
Man könnte natürlich auch die Task-Umchaltung (in Abhängigkeit von der
Priorität) jeweils erst nach n timerXX_ovf - Interrups auslösen (z.B.
n=1 bei Prio low, 2 bei medium, 3 bei high oder so). Auch dann wäre ein
sleep möglich, auch in Verbindung mit Prioritäten. Aber Priority "low"
wären dan n schon 256*1024 Takte, was dem aktuellen prio high
entspricht. Und vorzeitiges Ausberechen aus den Tasks a la task_switch()
ist ebenfalls tabu, da hier TCNT neu gesetzt wird.
Das ganze sehe dann eben (nur der Kopf) in etwa so aus:
void scheduler()
{
sleep++; //increase variable for sleep-function
act_prio_count++;
if (task->prio <= act_prio_count)
asm volatile("reti");
else
{
akt_prio_count = 0;
//Contextswitch
}
}
Evtl gäbe es auch andere Ideen, z.B. in dem man den Compare-Mode
nutzt...
Datum:
@nico: geht so nicht, denn in beiden OSsen wird das TCNT0 (timer-counter Register) in Abhängigkeit von der aktuellen Priorität verändert. Das ist das Grundproblem.
Datum:
hacker-tobi schrieb: > Evtl gäbe es auch andere Ideen, z.B. in dem man den Compare-Mode > nutzt... hmm, damit kenn ich mich gar nicht (nur seeeeehr grob) aus. evtl. hast du da echt ne heisse spur... wie gesagt hat momentan echt zu wenig zeit das zu verfolgen :-( oder halt doch nen 2. timer spendieren (geht aber gegen mein ego :-)
Datum:
Das Zeitproblem kenne ich....der Compare mode ist einfach: Sobald TCNT0 einen definierten Wert erreicht, gibts nen Interrupt. Den kann man natürlich für nen Scheduler nutzen. Die simpel-Lösung: Mit jedem Timer0_OVF führt man einen Task-Wechsel aus. Jetzt definiert man den Compare-Wert auf: 1 für low, 64 für medium und 255 für high. somit hätten die Tasks 1024, 64*1024 und 255*1024 takte zeit. Das TCNT0 bliebe unverändert, und damit könnte Timer0_OVF auch für ein definiertes sleep() genutzt werden. Wird der Compare-Interrupt ausgelöst, wechselt man (z.B.) in einen Idle-Task der bis zum nächsten Timer0_OVF nichts tut. Das Problem ist folgendes: Was macht man bei low und medium-tasks mit der Zeit bis zum nächsten Timer0_OVF (immerhin 254 bzw. 191 * 1024 Takte)? Die würden nämlich bei dieser simpelst-Lösung einfach ungenutzt verpuffen. Also von Ideal ist das weit entfernt...
Datum:
> Also von Ideal ist das weit entfernt...
zumindest wenn man alles auf einmal erschlagen will.
evtl. reichts ja für "standard" apps mit servo, rs232, midi (ums nicht
zu einfach zu machen)
Datum:
Günter Greschenz schrieb: > da ich mit dem verwendeten konzept ein sehr genaues "sleep(ms)" nicht > realisieren konnte (die servos flackerten ohne ende) hab es ich dann > nicht weiterverfolgt. Verstehe ich das richtig, Du wolltest mittels sleep(ms) mehrere Soft-PWM-Kanäle erzeugen (z.B. fünf Tasks, die jeweils einen anderen Pin ansteuern)?
Datum:
jupp, so in der art, nur halt nicht 5 sondern so viel wie geht, d.h. wie pins als "out" schaltbar sind (wollte mal nen kleinen roboter baun :-) mit richtigen timern hats sehr gut geklappt, die servos waren saustabil, aber halt zu wenig...
Datum:
Angehängte Dateien:So, nun gehts ja hier doch mal mit der Entwicklung und Ideen weiter. Daher habe ich mich entschlossen, auch meinen neuen Scheduler hier zu veröffentlichen. Was ich getan hab: -Code der Taskverwaltung neu geschrieben, -die Stack(s) in ein globales array im RAM verlagert. To Do: Die Stacksizes dynamisch veränderbar machen. Sorry, ich hab zur Zeit einfach zu wenig Zeit. Und wenn dann mach ich das richtig, also inkl. "best-fit"-Algorithmus, um das array möglichst auszureizen. Thema Formatierung: Ich weiß nicht, aber irgendwie ist das mein Stil, code zu schreiben. und das seit Jahren ;) Daher bin ich bis jetzt bei meiner Formatierung geblieben. Wer sich das anders formatieren will, kann das gern tun.
Datum:
Angehängte Dateien:Leute, die Version von eben bitte nicht verwenden. Da ist mir ein grober Fehler in task_control.c unterlaufen, durch den ihr euch beim dynamischen Anlegen von Tasks zur Laufzeit den Stack zerschießt. Nun ists bereinigt. Anbei die funktionierende Variante.
Datum:
Hallo zusammen, bisher habe ich nur ab und zu mitgelesen, weil ich nicht so viel Ahnung von der Programmierung habe. Aber zu dem Thema sleep() ist mir folgendes eingefallen: Soweit ich das (ohne in die Quellen zu schauen) verstanden habe, gibt es ja eine Liste mit Tasks, in der auch die Prioritäten festgelegt werden. Was ist, wenn man die Prioritäten als "Startzeiten" ansieht. Der Task-Timer läuft mit einem konstanten TCNT. Die Tasks laufen solange, bis die nächste Startzeit fällig ist. Im Interrupt müsste dann nur noch ein Zähler mitlaufen, der "Startzeit"-Zähler systick. Ist systick >= "Startzeit" wird der aktive Task gewechselt und der neue Startzeitpunkt des alten Tasks festgelegt. Wenn ein Task jetzt einen Sleep() haben will kann man den Startzeitpunkt für den Task entsprechend anpassen und einen IDLE-Task starten, bis der nächste Task an der Reihe ist. Werden 2 Tasks gleichzeitig zuteilungsreif, entscheidet die Prio. Man könnte das noch soweit erweitern, dass man zu der Startzeit noch eine Laufzeit aufnimmt. Dann kann man mit der Laufzeit die Betriebszeit einer Tasks begrenzen und einen IDLE-Task aufnehmen, welcher Aufgaben niedrigster Priorität übernehmen kann. Ich hoffe, das ergibt einigermaßen einen Sinn.
Datum:
Zu dem Sleep-problem, wie wärs damit: Der Taskswitch wird nicht im Overflow gemacht sondern im Comparematch. Der Timer läuft frei durch. Der Comparematchwert ergibt sich einfach aus dem letzten Comparematchwert und der Priorität des Tasks (einfach zugeteilte Zeit plus aktueller Wert) und wird bei jedem Taskwechsel neu geschrieben. Auf diese Weise bleibt der Overflow frei für eine feste Zeitbasis. Ich hoffe das war jetzt nicht totaler mist. Kenne nämlich weder die Sourcen von GOS noch von nano OS ;) Sebastian
Datum:
Hallo, im neuen Scheduler:
void scheduler() { //to avoid inconsistent state when we have a stack overrun/underrun reset the system via watchdog in this case if (active_task && (SP < (uint16_t) active_task->stack_section || SP >= (uint16_t) active_task->stack_section + STACK_SIZE)) { wdt_enable(WDTO_1S); while(1); } else { TIMER_REGISTER = CLK1024; //save SREG and SP if (active_task_id >= 0) { //save R0-31 to active_task->stack stack_push(31); stack_push(30); |
weden hier die Register ein bischen spät gesichert, oder? Davor sind schon einige Zeilen Code, in denen die Register ja verändert werden. Gut, es funktioniert, weil ja der Compiler dafür sorgt, daß die dort verwendeten Register auch gesichert werden, d.h. aber es werden viele / einige Register unnötigerweise doppelt gesichert. Das brauch nicht nur Stack, sondern auch CPU Zeit. Meiner Meinung nach ist der saubere Ansatz, den Scheduler (oder zumindest Save und Restore der Register) direkt in die Interruptroutine zu setzen und diese als _attribute_ ((naked)); anzulegen. Wenn man aus einer Interrupt einen Funktionsaufruf macht, dann sichert der Compiler üblicherweise einen Haufen Register, deshalb den Scheduler direkt in die "naked" Interruptfunktion. Gruß, Bernhard
Datum:
@Bernhard: Ja das ist im Prinzip richtig. Den scheduler in die ISR zu legen, funktioniert aber nicht ;( Siehe auch Beiträge vom 24.09.2010 20:37 ff. Zum "späten" sichern: Das if-Konstrukt ist ein Test auf eine Stack-Violation, und sollte daher möglichst früh erfolgen. Daher steht es an erster stelle. Hier werden aber ausschließlich volatiles verglichen, daher sind keine Operationen auf dem Stack nötig. Das "TIMER REGISTER =" könnte auch hinter den pushes stehen, aber auch hier wird am Stack nichts geändert. @Martin/Sebastian: Stimmt, so sollte es mit dem Compare Match klappen. Ok wird getestet. gruß tobi
Datum:
Hi, Der Scheduler muß in der ISR funktionieren, da muss man halt mal den erzeugten Assembler-Code analysieren. Selbiges muß man mit der Stack-Prüfung machen, die kann man nur dann vorziehen, wenn der Compiler dabei nicht ans Sichern von Registern geht. Notfalls müsste man das halt mit inline-Assembler erledigen. Was für eine Compiler-Version? Was spricht eigentlich gegen eine ordentliche Programmstruktur, mit C-sourcen und dazugehörigen Headern? Der include von C-sourcen ist normalerweise ein absolutes no-go! Mir persönlich fehlt da auch ein Makefile... Gruß, Bernhard
Datum:
Bernhard M. schrieb: > ... Mir persönlich fehlt da auch ein Makefile... der avrwiz-online (achtung: eigenwerbung :-) erzeugt auch das fehlende makefile :-) nochmal zum thema "perfekter sleep": wenn man einfach statt prio=zeitscheibenlänge die scheibchen kleiner aber fix breit macht und dafür hoch-prio tasks z.b. mehrfach drankommen lässt (d.h. die prio definiert einfach, wie oft nacheinander ein bestimmter task drankommt) hätte man zumindest ein festes raster, das macht die sleeps dann verlässlicher. nachteile: *) mehr interrupts (weil mehr & kleinere scheibchen) *) nicht alle sleep-zeiten würden gehen, nur vielfache schlafzeiten der scheibchen-zeiten. *) bestimmt noch mehr :-)
Datum:
Tobi, was du suchst, glaube ich, zu mindest.. ist die naked isr von avr-libc. <zitat> #define ISR_NAKED # include <avr/interrupt.h> ISR is created with no prologue or epilogue code. The user code is responsible for preservation of the machine state including the SREG register, as well as placing a reti() at the end of the interrupt routine. </zitat> dh. die pushs vor dem scheduler werden nicht mehr gamacht und dann sollte es wieder stimmen mit der stack organization. muss aber zugeben, ich habe die neuste version noch nicht angeschaut.. lg roman
Datum:
Bernhard M. schrieb: > Meiner Meinung nach ist der saubere Ansatz, den Scheduler (oder > zumindest Save und Restore der Register) direkt in die Interruptroutine > zu setzen und diese als _attribute_ ((naked)); anzulegen. deswegen mach ich es ja auch genau so :-)
void TIMER_VECTOR() __attribute__ ( ( signal, naked ) );
ISR(TIMER_VECTOR)
{
...
asm volatile("reti");
}
|
(wieder eigenwerbung, sorry :) schau die das ganze generierte konstrukt einfach mal an (natürlich im avrwiz :-). *) im linken fenster haken "multitasking" setzen *) im rechten dann auf "tasks.c" klicken und anz nach unten mir war wichtig, dass der ctx-switch seeeeehr wenig cyclen braucht. ich hatte das mal ausgerechnet, waren nicht sehr viele ;-) deswegen auch so sachen wie "#ifdef TASK_USE_SIGNAL": wenn mans nicht braucht spart man ein paar cyclen wenns disablet wird... @Roman65536 was macht denn "#define ISR_NAKED" ? ist das nicht das gleich wie "__attribute__ ( ( signal, naked ) )" kenn ich noch gar nicht (wie so vieles) oh mann ich brauch mal wieder zeit für son hobby, die sw die ich beruflich baue hat >1000 source files, sowas hübsches kleines wie gos/nano-os nicht mal 1000 zeilen. seufz...
Datum:
@guenter eigentlich das selbe.. nur anderst definiert :) und sogar fuer den reti gibt es ein define .. reti() wenn die "avr/interrupt.h" included ist.. :) <zitat> oh mann ich brauch mal wieder zeit für son hobby, die sw die ich beruflich baue hat >1000 source files, sowas hübsches kleines wie gos/nano-os nicht mal 1000 zeilen. seufz... </zitat> geht manch einem so.. fuer das haben wir ja so ein hobby... ;) autopilot fuer modelflieger unter 1000 zeilen .. cooles ziel 8D hihihi.. lg roman
Datum:
> > Zum "späten" sichern: Das if-Konstrukt ist ein Test auf eine > Stack-Violation, und sollte daher möglichst früh erfolgen. Daher steht > es an erster stelle. Hier werden aber ausschließlich volatiles > verglichen, daher sind keine Operationen auf dem Stack nötig. > Das "TIMER REGISTER =" könnte auch hinter den pushes stehen, aber auch > hier wird am Stack nichts geändert. > Schon mal das Assembler-Listening angeschaut? Den Stackverbrauch hast Du damit enorm gesteigert! Du legst einige Register doppelt ab, genauso wie SREG. Wie sieht es eigentlich mit den Warnings aus? queue_read_byte schon gefixt?
Datum:
Günter Greschenz schrieb: > jupp, so in der art, nur halt nicht 5 sondern so viel wie geht, d.h. wie > pins als "out" schaltbar sind (wollte mal nen kleinen roboter baun :-) > mit richtigen timern hats sehr gut geklappt, die servos waren saustabil, > aber halt zu wenig.. Ich hab mir auch schon mal überlegt einen Roboter bzw. einen Roboterarm zu bauen. Als Servos hätte ich dann OpenServo verbaut. Die Ansteuerung über I2C finde ich eleganter als über PWM und die Möglichkeit die Position auszulesen, könnte man auch irgendwie zu nutzen. http://openservo.com/
Datum:
@Mar IO: Ich weiß, das hier überflüssige Arbeit entsteht. Aber wie gesagt, mit scheduler in die ISR und "naked" (wie bei GOS) funktioniert es nicht ;( Obwohl es das laut asm-file müsste, denn wie du richtig bemerkt hast, werden im proloque/epiloque nur einige Register doppelt gesichert bzw. wiederhergestellt. Daher bleibt das erstmal so, bis ich mehr zeit habe, mal das "warum" zu finden. Ich kenne mich auch mit assembler nicht so gut aus, daher brauche ich zeit, um das asm-file zu analysieren. Oder hast du da eine Idee, woran das liegen kann? Ich verweise hierzu auf meinen Beitrag vom 24.09.2010 20:37 ff. dort ist das Problem beschrieben. trotz (bzw. gerade wegen) reti wird der Stack auch wieder abgebaut, siehe meinen Beitrag vom 25.09.2010 18:49. Sauber ist das derzeit noch nicht, aber wie gesagt, mir fehlt es zur Zeit an Ideen und Zeit. @Günter: Was ist der avr-wiz? Sagt mir jetzt so erstmal nichts. Aber deinen Quelltext von GOS habe ich mir angesehen. Von daher ist mir klar, worauf du raus willst. Ich weiß nicht, warum der Code bei mir nicht funktioniert. Ist ja ansonsten nahezu identisch ;)
Datum:
Roman65536 schrieb: > geht manch einem so.. fuer das haben wir ja so ein hobby... ;) > autopilot fuer modelflieger unter 1000 zeilen .. cooles ziel 8D hihihi.. wenn du das fertig hast: HER DAMIT :-) mein sohn baut sich grade nen microcopter, der ist bestimmt gut erweiterbar ! mar IO schrieb: > Ich hab mir auch schon mal überlegt einen Roboter bzw. einen Roboterarm > zu bauen. Als Servos hätte ich dann OpenServo verbaut. Die Ansteuerung > über I2C finde ich eleganter als über PWM und die Möglichkeit die > Position auszulesen, könnte man auch irgendwie zu nutzen. naja, mir gings ums selbermachen und ich hatte den anspruch möglicht billige hw zu benutzen. und die pwm-servos hatte ich halt @home ...
Datum:
hacker-tobi schrieb: > @Günter: Was ist der avr-wiz? schau mal auf http://greschenz.dyndns.org/avrwiz vorbei :-) ich hab allerdings grade das problem, dass das mit chrome & ie nicht mehr geht... nimm den firefox und es sollte gehen (zumindest bei mir). hab aber grad keinerlei zeit was zu fixen...
Datum:
@mar io nochmal ;) Ich seh grad, mit dem argument, das die Abfrage der SP-Volation viel Arbeit auf dem Stack verursacht, hast du recht. Ich kann es aber auch nicht hinter die Registersicherung legen, denn dann wäre es definitiv zu spät. Außerdem würde es die Arbeit ja auch nur "verlagern". Mal sehen, ob ich das evtl. vereinfache oder wieder herausnehme. So jetzt arbeite ich erstmal weiter...bis heut abend ;)
Datum:
<zitat> wenn du das fertig hast: HER DAMIT :-) mein sohn baut sich grade nen microcopter, der ist bestimmt gut erweiterbar ! </zitat> http://diydrones.com/profiles/blogs/announcing-ard... btw.. die diskusion mit den servos.. zwar sind wir weg von os.. futaba hat doch auch irgend so ein bus system ?? weiss jemand wie den das geht ?? lg roman
Datum:
Angehängte Dateien:Hi @ all:
Zum Thema sleep()
Folgender Code funktioniert
(nano_os.h)
SIGNAL (SIG_OUTPUT_COMPARE0A)
{
scheduler();
}
(task_control.c)
void task_schedule()
{
cli();
set_sleep_mode(SLEEP_MODE_IDLE);
TCNT0 = 0xFF;
TIMER_REGISTER = _BV(CS00);
//TIMER_ENABLE |= _BV(TOIE0);
TCCR0A=0x00;
OCR0A=TCNT0+1;
TIMER_ENABLE = _BV(TOIE0) | _BV(OCIE0A);
sei();
sleep_mode();
}
Im scheduler() statt
TCNT0 = active_task->priority;
neu
if (TCNT0 + active_task->priority <= 255)
OCR0A = TCNT0 + active_task->priority;
else
OCR0A = TCNT0 + active_task->priority - 255;
Das ist jetzt nur "quick&dirty" geschrieben und kurz angetestet, da ich
die Funktionalität nicht brauche.
Es ist auch nicht unproblematisch, gerade in Verbindung mit den
Wartefunktionen
wait_for_message() und
wait_for_semaphore()
da diese die Taktung des Timers "hochdrehen".
Da ich die Funktionalität nicht benötige, übernehme ich es nicht.
Aber es könnte eine Anregung für Günther sein, wenn er das in GOS
einbauen will.
Die Priorities müssen allerdings angepasst werden (low=1, medium=64,
high=254).
kurze erklärung: Timer0 läuft jetzt im Compare-Mode. Jedes mal, wenn
TCNT0 den in OCR0A definierten Wert erreicht, gibts nen Interrupt.
Dieser ruft über die ISR den Scheduler auf. Im Scheduler wird OCR0A
entsprechend der Prio des aktuellen Task neu gesetzt, und das Spiel
beginnt von vorn.
TIMER0_OVF ist damit frei für anderes...
@mar io Roman Bernhard:
Mein Problem ist nicht, das mir unlar ist, was es mit ISR auf sich hat,
oder warum es besser wäre, den Scheduler in die ISR zu ziehen, und diese
mit atrribut naked laufen zu lassen. Das habe ich im angehängten C-File
schonmal gemacht.
Mein Problem ist, dass es ohne den zusätzlichen Proloque/epiloque zu
Interferenzen zwischen den Tasks kommt, das Scheduling selbst
funktioniert.
Anbei das c-file des Schedulers mit ISR_NAKED, sowie die beiden
Assemblerfiles (einmal original, einmal mit ISR_NAKED).
Mich selber stört es auch nicht so sehr, dass da etwas zusätzliche
Arbeit notwendig ist. Meine Uhren laufen, das reicht mir zur Zeit. Mir
fehlt momentan echt die Zeit und bei Assembler auch das know-how.
@Bernhard:
Thema Struktur: Da spricht nichts dagegen ;) Das war irgendwan mal ne
Notlösung und dann hab ichs schlicht vergessen. Kommt in die nächste
Version mit rein.
Datum:
Ja Tobias, ich denke dort irgendwo ist ja der hund versteckt.. denn, je nach optimierungs level, verschiebt sich der stack verbracht (meinst mehr) den mehr optimierung heisst mehr die register zu nuetzen. das problem ist, der scheduler muss ja den stack vorbereiten fuer den task contex switch, inklusive den was vor dem scheduler auf stack war, sie wie auch danach.. im klar text, im naked, hast du die absolute kontrolle was vorher auf dem stack war und was danach sein wird. (ausser, man deklariert etwas locales) zu dem, der gcc und auch andere compiler, verwenden gewisse register exklusiv fuer sich. da kann man tun was man will, plus sie werden nicht gesichert... siehe r18,19 in der naked version.. meistens findet man dies irgendwo in der compiler beschreibung. daher ist es immer besser beim multitasking, alle register als aller erstes auf den stack zu sicher noch bevor ueberhaupt der scheduler aufgerufen wird (Solaris tut es so) oder gleich in die task struktur (linux) und zwar im assembler. sind ja nicht viele assembler commands.. und.. jenachdem .. muss man dies tun fuer alle interupts. den.. ist das system beschaeftigt mit 1+1 rechnen und es kommt ein interupt das zb. etwas von uart gekommen ist, auf das ein task wartet, will man ja das dieser gleich rescheduled wird und sofort auf die cpu kommt. oder .. man definiert ganz einfach, das kein scheduling waerend einem interrupt statt findet. ein sehr aehnliche ansatz verwendet linux. Die interrupts werden aufgerufen wie sie im system registriert sind, jedoch, die device driver, resp. system setzt ein flag, das ein rescheduling statt finden soll. nach dem alles fertig ist, kurz vor der return from interrupt wird gepruefft ob dieses flag gesetzt ist oder nicht. dh. die reti springt dann gleich in einen anderen task. ein andere weg, ist es ueber den longjmp zu arbeiten.. .irgendwo auf dem net habe ich auch schon solch ein multitasking gesehen. lg roman
Datum:
Angehängte Dateien:Hi, ich hab mal eben ne absolute minimalversion des schedulers gebaut, aus der alles raus geflogen ist, was nicht notwendig ist. aber auch bei dieser version bleibt es dabei...definiere ich ISR und naked, gibt es Probleme mit Interferenzen. Aber ich bin mittlerweile so schlau, dass ich sagen kann, wo die Interferenzen entstehen: "Schuld" ist die Funktion wait_for_message(), denn die wartet jetzt schlicht nicht mehr auf Nachrichten, sondern springt zurück, und zwar unabhängig davon, ob hier eine Nachricht vorliegt oder nicht. Eventuell ist auch die ähnlich konzipierte Funktion wait_for_semaphore() betroffen. Und ich kann auch nicht ganz ausschließen, dass dies nicht der einzige Fehler ist. Na ja, bei zeiten werd ich mir mal das ASM dieser Funktionen ansehen. Anbei der "minimal" Scheduler und das passende .s - File
Datum:
Moinsens Leute, es ist wie verhext...zur Zeit komm ich nicht dazu, an dem OS irgendwas zu machen ;( Ich meld mich, wenns ein update gibt. gruß tobi
Datum:
Angehängte Dateien:Hi, anbei die letzte Version. Aber viel ist nicht passiert. Im Wesentlichen habe ich alle Compiler-Warnings wegbekommen und ein Makefile erzeugt. gruß tobi
Datum:
Angehängte Dateien:Hallo Zusammen, hier ein alternativer Vorschlag für den Scheduler. Der spart den extra PUSH und POP-Block. zusätzlich muss in der task_control.c der Stackpointer korrigiert werden. Statt
t->sp = (uint8_t *)(t->stack_section + STACK_SIZE - 3);
|
muss es
t->sp = (uint8_t *)(t->stack_section + STACK_SIZE - 3 - 32); |
heißen... Gruß Maarten
Datum:
ich hab oben im Post vergessen, dass die zu ändernde Code-Zeile in der Funktion task_insert ist.
Datum:
Angehängte Dateien:Hallo Maarten, gute Idee, das SREG separat zu sichern, und die Bearbeitungsreihenfolge im Scheduler etwas anzupassen. Das hat das Problem mit den Task - Interferenzen gefixed. danke dir. Ich habe noch einige Anpassungen gemacht, damit der Scheduler ins System "passt". Anbei die neue Version. Ich habs eben sowohl mit der "einfachen" user-software als auch mit der komplexeren Variante in allen optimierungsleveln getestet, und es sieht gut aus - bis auf Optimierungslevel 3, da schmeißt der Compiler gut doppelt so großen code (6400 gegenüber 3500 Byte) raus, und das asm-file wird - sagen wir - unaufgeräumt. Aber das ist wohl eher ein Problem meiner Compiler-Installation... gruß tobi
Datum:
@all, die bis jetzt geholfen haben, mal ein danke ;) Wenn ihr wollt erwähn ich euch auch gern in den Kommentaren. Sagt mir einfach bescheid.
Datum:
Gibts noch weitere Ideen/Anregungen/Kommentare zu dem OS? Grad was den Bereich Message Queue / Semaphore angeht wäre ich sehr interessiert.
Datum:
Angehängte Dateien:Hallo Tobias, ich habe mir die letzte Quelldatei vom Datum: 11.10.2010 23:17 geladen und im Makefile alle Pfade gelöscht, da unter Linux der gcc-avr und alle Tools im Pfad liegen. Dann habe ich für spätere Tests einen atMega88 eingebaut, siehe "system/header/nano_os.h". Stimmen die Angaben ?
#elif defined (__AVR_ATmega88__) #define RAMSTART 0x60 #define HEAPSTART 0x02FF #define STACK_SIZE 96 #define TIMER_REGISTER TCCR0B #define TIMER_ENABLE TIMSK0 #define TIMER_VECTOR TIMER0_OVF_vect #define CLK1 _BV(CS00) #define CLK1024 _BV(CS02) |_BV(CS00) #else |
In "nano_os.c" stand noch
#define F_CPU 8000000 |
, das ist zu viel, da im Makefile auch definiert. Ich erhalte nur eine Warnung:
In file included from nano_os.c:27: system/scheduler.c:26: Warnung: Funktionsdeklaration ist kein Prototyp |
Gibt's dafür eine Lösung? Und habe ihr noch Beispiele, wie man etwas Programmieren könnte ? Z.B. könnte man noch eine LCD-Display anschließen und die Ausgabe der Zeichen über eine eigenen Task und die Daten über eine MessageQueue einlesen. Wenn ich richtig gerechnet habe, können maximal 7 Task laufen.
Datum:
Hallo Uwe, Interessant, das dein avr-gcc das bemängelt. Trotz "-Wall" wird das bei mir nicht bemängelt(ich arbeite ebenfalls mit avr-gcc unter Linux). Er sagt damit, dass die Funktionsdeklaration nicht korrekt als Prototyp definiert ist. Probier mal void TIMER_VECTOR(void) _attribute_ ( ( signal, naked ) ); statt void TIMER_VECTOR() _attribute_ ( ( signal, naked ) ); Wie viel Tasks auf dem System laufen können, ist meist nur durch den verfügbaren Speicher begrenzt. Jeder Task benötigt 9 Byte (bei Nutzung aller Features) + STACK_SIZE byte für den Stack. Das System selbst kann max. 255 Tasks verwalten. Zu den werten: Deine Stack_size ist sehr groß gewählt. Du hast vermutlich das "Original" übernommen. Je nachdem, wie viel Stack du brauchst, kannst du sie auch kleiner wählen (minimum sind 32 Byte für die Register). Auch die Werte für RAMSTART und HEAPSTART solltest du nochmal überprüfen (s. Datenblatt). Die Prescaler (CS00 und CS02) stimmen bei beiden Prozessoren überein. Aber im Zweifelsfall verrät dir auch hier das Datenblatt, welche Bits gesetzt sein müssen, um den Timer0 mit Prescaler 1 bzw. 1024 laufen zu lassen. Bei den anderen Zuweisungen handelt es sich lediglich um aliasnamen. Wenn hier etwas falsch ist, gibt der Compiler einen Fehler aus und bricht ab. Aber auch diese stimmen meines Wissens nach beim Mega88 mit dem Mega168 überein. Danke auch für deine Hinweise zum Makefile. Allerdings ist die Konfiguration hier sehr individuell; bei mir liegt der avr-gcc z.B. nicht im Standardpfad und es wird für einen Mega168 übersetzt. Von daher sind die Makefiles eben unterschiedlich. gruß tobi
Datum:
Angehängte Dateien:Hallo Tobias, danke für die Antworten, auf
void TIMER_VECTOR(void) _attribute_ ( ( signal, naked ) ); |
hätte ich selbst kommen sollen. Damit läuft der Compiler durch! Ich hänge Dir das avr-gcc logfile an. /Deine Stack_size ist sehr groß gewählt. Du hast vermutlich das "Original" übernommen. Je nachdem, wie viel Stack du brauchst, kannst du sie auch kleiner wählen (minimum sind 32 Byte für die Register). Auch die Werte für RAMSTART und HEAPSTART solltest du nochmal überprüfen (s. Datenblatt)./ Das verstehe ich noch nicht geschossen, da ich nicht weiß mit RAMSTART und HEAPSTART eingestellt wird. Da würde mir eine Grafik mit der Rambelegung sehr helfen. .
Datum:
RAMSTART ist die erste verfügbare Adresse im RAM, also der Beginn des RAM. HEAPSTART gibt die erste Adresse dews HEAPs an. Die Speicherbelegung bei Atmel AVRs sieht (hier am Besispiel des Atmega 168) wie folgt aus: 0x0000 - 0x005f Regeister 0x0060 - 0x00ff (ext i/o-register) *Typabhängig. 0x0100 - 0x04ff RAM Der Ram teilt sich nochmal in Data-Section, HEAP und STACK: 0X0100 - 0X02FF ram 0X02FF - 0X04FF Heap 0X04FF - 0x02FF Stack Der Stack und Heap teilen sich einen Bereich, wobei der Heap nach oben hin wächst, der Stack nach unten. Die Bereiche werden (grob) wie folgt genutzt: Ram: Ablage von Variablen etc. Heap: allokierter Speicher (malloc) Stack: Stapelspeicher des Prozessors für Register, Rückspungadressen usw. Nun noch ein Wort zu den Makros: HEAPSTART wird in memory.c benutzt, umzu vermeiden, dass versehentlich ein Speicherblock im Heap reserviert wird (das Speichermanagement von nano_os nutzt nur den Ram-Bereich). RAMSTART wird nur für die Berechnung der max. Anzahl an Tasks benötigt. STACK_SIZE gibt die Größe des Stacks an, der für jeden Task reserviert wird. Dies müssen mind. 32 Byte (für die 32 GPIO-Register des AVRs) sein + dem, was man noch selbst für lokale Variablen braucht. Hier lohnt sich ausrechnen oder experimentieren. Ausrechnen ist simpel: -Berechnung des gesamtspeicherbedarfs aller Variablen für jeden Task separat. -Dann nehme man das größte Ergebnis und rechne 32 dazu. Das ist dann schonmal ein guter Richtwert für die STACK_SIZE. -Evtl. ist dann noch etwas experimentieren notwendig, da der Compiler den Stack ebenfalls verwendet. Hier hilft ein Blick in das vom Compiler erzeugte asm-File weiter. gruß tobi
Datum:
Du kannst natürlich auch deinen User-Code mal hier posten, dann kann man dir hier etwas unterstützung beim berechnen der Stack-size geben. Falls es der Originalcode der Binäruhr ist, langt STACK_SIZE 64
Datum:
Angehängte Dateien:So, ich hab noch folgende Änderungen eingepflegt: -ISR-Attribute in void TIMER_VECTOR(void) attribute ( ( signal, naked ) ); geändert und in nano_os.c gepackt -nano_os.c aufgeräumt/altlasten entfernt. Anbei das neue zip-file
Datum:
...der fehlerteufel ...nicht GPIO sondern General Purpose Register GPR ;( danke!
Datum:
Hallo Tobias, ich brauche noch etwas um mich ein zu arbeiten .. stand by..
Datum:
noch was...irgendwie hatte ichs heut mittag: -ISR-Attribute in void TIMER_VECTOR(void) attribute ( ( signal, naked ) ); geändert und in nano_os.h (nicht nano_os.c!) gepackt -nano_os.h aufgeräumt/altlasten entfernt. @Uwe: Mach dir keinen Stress. Ist nur ein Hobby.
Datum:
Angehängte Dateien:Heut überschlagen sich die Entwicklungen ;)
-Funktion "queue_get_mumber_of_messages()" war falsch benannt. Umbenannt
in "queue_get_number_of_messages()"
Viel wichtiger:
Die Funktionen "wait_for_message()" und "wait_for_semaphore()" so
angepasst, das hier keine Takte mehr unnötig mit warten verschwendet
werden. Liegt keine Message/ kein freier Semaphor vor, wird direkt in
den scheduler gesprungen.
Alter code (am Beispiel wait_for_messages):
uint8_t queue_wait_for_message(Queue *qp)
{
...
while (qp->number == 0)
{
TCNT0=0xFF;
}
return TRUE;
}
neuer Code
uint8_t queue_wait_for_message(Queue *qp)
{
...
while (qp->number == 0)
{
TIMER_REGISTER = CLK1;
TCNT0=0xFF;
}
return TRUE;
}
Funktion "shutdown_system()" eingefügt. Diese Funktion fährt das System
bei Bedarf herunter, in dem sie Interrupts und den watchdog abschaltet
und in eine Endlosschleife geht.
Vorher ruft sie noch "shutdown_user_environment()" in "user.c" auf.Hier
kann der user Kommandos festhalten, die vor dem shutdown noch ausgeführt
werden sollen.
Doku hab ich natürlich auch angepasst.
Die Änderungen hab ich mit beiden Varianten der
Binäruhren-Beispiel-Software in allen Optimierungsleveln getestet.
Funktioniert komplett fehlerfrei (jetzt sogar mit Optimierungslevel 3,
obwohl da der Code immer noch sehr groß wird...).
Ich glaub es wird mal Zeit für sourceforge oder ähnliches...Vorschläge?
gruß
tobi
Datum:
Angehängte Dateien:Und noch ne Änderung wieder in "wait_for_message". Diesmal hab ich die
Funktion so angepasst, dass sie auf neue Nachrichten reagiert, nicht
mehr wie bisher auf das bloße verhandensein von Nachrichten.
Aus
{
...
while (qp->number == 0)
{
TIMER_REGISTER = CLK1;
TCNT0=0xFF;
}
return TRUE;
}
wurde
{
uint8_t number_old = qp->number
...
while (qp->number == number_old)
{
TIMER_REGISTER = CLK1;
TCNT0=0xFF;
}
return TRUE;
}
Anbei das neue zip-file
Datum:
Angehängte Dateien:Hallo Tobias, ändere doch bitte die Taktangeben wieder auf das Makefile ab, dann kann man auch weitere externe Objekte mit diesem Makefile mit dem richtigen Takt übersetzen. Auch könntest Du meine Erweiterung um den atMega88 mit einbauen. Danke.
Datum:
Hallo Uwe, ok, fließt in die nächste Version mit ein. Poste hier doch bitte nochmal deine aktuellen Einstellungen für den Mega88 in nano_os.h (ich weiß, weiter oben steht da schon was, aber ist das noch aktuell? Du warst dir ja damals wegen einiger Parameter nicht sicher.)
Datum:
Angehängte Dateien:Was ich bei interesse auch noch anbieten kann, ist die Abgabe von eval-boards, welche auf dem Mega168 basieren, zum Selbstkostenpreis. Aber natürlich können auch andere AVR-basierte Boards für die Entwicklung genutzt werden. Anbei der Schaltplan und die brd-files (egale) des eval-boards. Es beinhaltet einige Taster, LEDs und einen Piezo zur Ausgabe von Signalen, sowie einen ISP-Stecker und einen Erweiterungssteckplatz, auf dem fast alle PINs des Atmega zugänglich sind. Die Stromversorgung sowie ein Uhrenquarz inkl, Bürdekapazitäten sind auch mit an Board. Und nochmal die Frage: Besteht interesse daran, das ich das ganze auf sourcefourge setze? gruß tobi
Datum:
Angehängte Dateien:Hallo Tobias, mein Projekt wird sich um die Ausgabe von Informationen für Sehschwache oder Bilde OM bewegen. Die benötigte Sprachausgabe (1) habe ich schon als PCM-->PWM Soundausgabe mit einem atmega861V getestet und klingt an einem kleine 2-Weg Lautsprecher klasse. Nun soll der nanoOS Kern die Eingabe über Taster/Tastatur, die Ausgabe der TRX-Telegramme an eine LCD-Anzeige und ein Interface für ein CAT-Interface (TRX) bereitstellen. Es gibt viele CAT-Protokolle, so wird es auch eine Voreinstellung für die verbreitetsten geben müssen. Die Ausgabe einer der 255 Sprachdateien ist über 8-Bit möglich, ob nun parallel oder seriell ist noch zu überlegen. Eine Versionsverwaltung wäre zukünftig für alle Dateien wichtig, mehr: http://www.ica1.uni-stuttgart.de/Courses_and_Lectu... Oder einfacher in jede Datei ein Change-Log der Form: // 2010-10-25 <autor> <änderungen>, <kommentare> // Version 1.00 vom 2010-10-25 Quelle : (1) http://elm-chan.org/works/sd20p/report.html .
Datum:
Ein Funkamateur ;) 55+73 de Tobias, DD3AAA Das Projekt klingt sehr interessant, aber auch sehr ambitioniert. Meinst du, du kommst da mit nem Atmega88 hin? Ich mein die CAT-Ausgabe für den Transceiver und die Ein- und Ausgabe über Taster bzw. LCD halte ich für machbar, aber die Sprachausgabe ist denke ich nicht so einfach. Vor allem da das Multitasking die Sprachausgabe unterbricht (wenn sie über den Atmega läuft). Evtl. bietet sich hier ein zweiter AVR oder ein externer Sprachaufzeichnungs-Chip an. Ich werde das ganze Projekt in nächster Zeit auf Sourceforge o.ä. abbilden. Eine Versionshistorie in den Dateien ist auch machbar. Auch cvs ist denkbar, aber erst mittelfristig. Ich gebe ehrlich zu, dass ich so etwas noch nie verwendet habe, und zur Zeit fehlen mir da etwas die Kapazitäten, um mich einzuarbeiten (ein neuer job geht vor). Was ich im Rahmen der Distribution nicht übernehmen kann, sind die verschiedenen Makefiles, da diese einfach zu individuell sind. Aber ein generisches Makefile liegt ja bei. Die einzelnen Treiber bzw. Module (z.B. für das LCD) übernehme ich gern, sofern sie die Mechanismen von Nano OS zur Initialisierung (init_user_environment) und Kommunikation (Message queues) implementieren, und somit auch für andere Nutzer verwendbar sind. Ich denke, ich werde dazu in nächster Zeit mal einen kleinen Guide schreiben, in dem ich meine Vorstellungen davon festhalte, wie Software für nano_os aussehen sollte. Diesen werde ich dann natürlich zur Diskussion stellen. Keine Sorge, nix großes, nur ein paar grundlegende Richtlinien ;)
Datum:
Hallo ich bin an dem neuen nanoos sehr interessiert. Ich habe da noch eine Frage. Läuft dieses OS auch auf dem Atmega8535? Wieviel kb Ram bzs. Rom benötigt dieses OS?
Datum:
Angehängte Dateien:Moin Leo, ich habe das Makefile und einen Eintrag in "nano_os.h" gemacht. Hier sind noch die Stellen im Quellcode, die angepasst werden müssen. Dort findest Du SIG_PIN_CHANGE0 das ist ein Hinweis, dass die PCINTxyy bei deinem älteren µP fehlen. .
Datum:
Danke Uwe. Was ist mit SIG_PIN_CHANGE0 und PCINTxyy genau gemeint?
Datum:
Schau mal in das Datenblatt eines ATmega168 oder ATmega88, dort sind die Pins mit diesen Bezeichnungen vorhanden. D.h. nur jeder Pin kann in seiner Pin-Gruppe einen eigenen Interrupt auslösen.
Datum:
Für das NanoOs brauche ich doch keine Pins vom Atmega. Wenn ja warum denn eigentlich?
Datum:
Was..SIG_PIN_CHANGE0? Sorry, aber das wird im nano_os quelltext nirgendwo verwendet! Was du prüfen musst, sind folgende Parameter in nano_os.h: #define RAMSTART 0x60 Beginn des RAMs (siehe Datenblatt #define HEAPSTART 0x02FF //Beginn des HEAPs (meist genau auf der Hälfte der Adressen im Speicher) #define STACK_SIZE 96 //Die Größe des Stacks jedes Tasks. Muss ggf. individuell angepasst werden #define TIMER_REGISTER TCCR0B //Das Steuer-Register für Timer0 #define TIMER_ENABLE TIMSK0 //Das Interrupt-Mask-Register für Timer0 #define TIMER_VECTOR TIMER0_OVF_vect //Der Overflow-Interrupt für TIMER0 #define CLK1 _BV(CS00) #define CLK1024 _BV(CS02) |_BV(CS00) //die Prescaler-Werte für Timer0 (CLK/1 und CLK/1024) Das ganze packst du dann zusammen und schreibst es in nano_os.h Sieht dann so aus #elif defined (_AVR_ATmega8535_) #define RAMSTART 0x60 #define HEAPSTART 0x02FF #define STACK_SIZE 96 #define TIMER_REGISTER TCCR0B #define TIMER_ENABLE TIMSK0 #define TIMER_VECTOR TIMER0_OVF_vect #define CLK1 _BV(CS00) #define CLK1024 _BV(CS02) |_BV(CS00) Im Code lese ich mehrfach noch das Timer_register TCNT0 aus. evtl. muss das auch angepasst werden, wenn es bei Mega8535 anders heißt. Aber da wird dich der Compiler schon drauf aufmerksam machen ;) Ansonsten müssen evtl. noch Änderungen in scheduler.c gemacht werden, falls die Syntax der "alten" AtmMegas unterschiedlich ist, oder falls die Anzahl der Register nicht simmt (die neueren haben 32 Register, darauf ist nano_os ausgelegt). Sorry für die kurze und sehr technische Einweisung, aber ich habe grad wenig Zeit. Ich mußte jetzt aber mal intervenieren. Am WE hab ich Zeit, das Datenblatt des 8535 zu lesen. Dann kann ich dir die Parameter geben, falls du nicht weiterkommst. Aber lieber ists mir, wenn du das selbst machst, dann lernst noch was dabei ;) gruß tobi
Datum:
kurz nochmal was zur error.txt: Die ganzen PC_INT fehler stammen aus user.c und user.h, also aus dem user code. das hat mit nano_os direkt nichts zu tun. Das einzihe nano_os relevante ist TCCR0B und TIMSK0, also die Einträge #define TIMER_REGISTER TCCR0B #define TIMER_ENABLE TIMSK0 für den Mega8535 in nano_os.h. Diese müssen also nach Datenblatt geändert werden. Ansonsten gilt das oben gesagte.
Datum:
Und nochmal ich ;) Sorry....hab die Frage nach dem Speicherverbrauch überlesen. Beim ROM hängt es von den Features ab. Nutzt du nur den Scheduler, bist du bei ca. 1 kB. Mit allen Features (Message Queues, Semaphore, dynamisches Taskmanagent und Speicherverwaltung) belegt das System ungefähr 4,5 kB. Das bezieht sich jetzt auf eine Übersetzung mit avr-gcc und Optimierungslevel s. Dies sind Richtwerte, da die konkrete Größe von der Zielplattform, dem eingesetzten Compiler, der Größe des Usercodes, den genutzten Features und dem eingestellten Optimierungslevel abhängt. Im RAM ist es ähnlich: Nur der nackte Scheduler belegt wenige Byte. Nutzt du alle Features, sind es etwa 200 Byte (grob). Dazu kommen noch: -9 Byte + STACK_SIZE Byte für jeden Task inkl. des idle-task. -1 Byte für jeden Semaphor bei Nutzung der Semaphore. -7 Byte + n für jede Message Queue (n = MessageQueueDepth * item_size) bei Nutzung der Message Queues. -3 Byte für jeden Speicherbock + (MAX_BLOCKS * BLOCK_SIZE) Byte zur Ablage der Daten im RAM bei Nutzung des Speichermanagements. Noch ein Wort zum Thema Resourcenverbrauch in Bezug auf die vom System verbrauchte Rechenzeit: Je nach Taktfrequenz und Anzahl/Priorität der Tasks sowie genutzten Features bewegt sich der Grundlastverbrauch im Bereich 2% (16 Mhz, 3 high-prio-tasks im System, nur Nutzung des Schedulers) - 35% (1 Mhz Takt, 3 low-prio-Tasks im System, Nutzung der Message Queues und Semaphore). Dies sind allerdings auch nur Richtwerte, Abweichungen nach unten und oben sind möglich, je nach konkreten Bedingungen (Taktfrequenz, Anzahl und Priorität der Tasks, Nutzung der Message Queues/Semaphore usw...)
Datum:
Hi, nano os findet sich ab jetzt unter sourceforge.net: https://sourceforge.net/projects/nanoos/ gruß tobi
Datum:
schieb @Leo: schon weiter gekommen? @Uwe: Was macht dein Projekt?
Datum:
Hallo Tobias, viel QRL und ein langes WE mit lernen und Prüfung, also keine Zeit.
Datum:
Verständlich. Komme auch grad vom QRL heim. Für nicht Amateuerfunker QRL = Arbeit ;) Melde dich, wenn du Hilfe brauchst oder Anregungen/Fragen/ideen hast.
Datum:
Schieb Gibts weitere Anregungen/Ideen/Fragen? Ich sehe etliche downloads aber kaum noch Aktivität in diesem Thread zur Zeit...
Datum:
jaja, geht mir auch so :-) mein avrwiz hat >300000 hits/jahr aber 0.0 feedback...
Datum:
Hallo Tobias, ich hänge noch bei meinem Projekt und komme mit meinen privaten Projekten i.A. nicht weiter. Danke für Deine Unterstützung! .
Datum:
Hallo, ich hab das NanoOs auf meinem at90s8535 zum laufen gebracht. Dafür habe ich zunächst nur mal zwei Tasks erzeugt, in der jeweils eine LED zum blinken gebracht wird. Ich muss sagen, dieses OS lässt sich echt einfach auf einen anderen AVR portieren. Gibt es für dieses OS eine Dokumentation ?
Datum:
hi leo, welche aenderungen musstest du durchfuehren? bitte sende sie mir damit ich sie einarbeiten kann. eine einfache apidoku liegt im Verzeichnis software/doku.eine vollstaendige doku folgt wenn ich zeit hab. gruss tobi
Datum:
Hallo hacker-tobi, ich kann dir meine Änderungen erst heute Abend sagen. Ich habe eigentlich nur in der Headerdatei nano_os.h Änderungen durchgeführt. Den Timer für den Time Tick habe ich in der user.c Datei entfernt. Hat dieses OS auch einen Pool Mechanismus? So wie es aussieht nicht.
Datum:
Hallo Leo, dann poste hier einfach mal deine Änderungen in nano_os.h Die user.c ist hier unwichtig, denn dass ist dein user-code bzw. der Beispielcode, und hat nichts mit dem OS selbst zu tun. Pool: Du meist doch nicht etwa resourcenpools, oder? So etwas auf dem AVR umzusetzen ist nach meiner Ansicht unnötig, da man die wenigen Resourcen gut "von Hand" verwalten kann, und Art und Anzahl der Tasks von Anfang an bekannt sind. Das OS verfügt über: -preemptives Multitasking inkl. Prioritäten, -binäre Semaphore (Mutex), -Message Queues, -ein einfaches Speichermanagement (basiert auf einem array im RAM) sowie -Funktionen zur Task-Kontrolle (anhalten, löschen usw...) nicht weniger aber auch nicht mehr ;) gruß tobi
Datum:
Ich muss sagen, das NanoOs macht einen echt guten Eindruck. Besser wie z.B. das femtoos.
Datum:
Danke ;) Mich würde mal interessieren, wo genau nach deiner Ansicht die stärken/schwächen von nano_os im Vergleich zu FemtoOS liegen. Kannst du das mal kurz zusammenschreiben?
Datum:
Angehängte Dateien:Im Anhang befindet sich das Beispiel für den at90s8535. Das femoos konnte ich bis jetzt nicht auf meinem at90s8535 zum laufen bringen. Mit dem nanoos bin ich viel schnell zum Ziel gekommen.
Datum:
Hallo Leo, danke dir. Ich werd die Änderungen übernehmen, und dann ein neues File hochladen. gruß tobi
Datum:
Hi Leo, deine Angaben stimmen nicht mit dem Datenblatt überein. Lt. deinen Angaben beginnt der Speicher bei 0x060 und endet irgendwo oberhalb von 0x02FF Das kann aber nicht sein, denn 0x02ff = 767 Byte dezimal. Der Prozessor hat aber nur 512 Byte RAM. Rechnet man noch die 0x60 (96 Dezimal) für Register etc dazu, kommt an auf 512 Byte + 96 Byte - 1 = 607 Byte gesamter Adressraum = 0x025F hex. Das entspricht dann auch dem Datenblatt, nach dem der RAM bei 0x25F endet. Ergo ist dein HEAPSTART verkehrt. HEAPSTART berechnet sich aus: (letzter Adresse im RAM (hier: 0x025F) - erster Adresse im RAM (0x060) / 2) + erster Adresse im RAM = (0x025F - 0x060 / 2) + 0x060 = 0x015F. Zur Erklärung: Der Datenspeicher teilt sich bei den Atmels nochmal auf in: -DATA-Bereich: hier liegen die meisten Variablen etc -HEAP: Dies ist ein Bereich für reservierten Speicher (z.B. malloc()) -STACK: Der Stack wird für Rücksprungadressen und teils auch für Variablen genutzt. Der HEAP beginnt dabei in der Regel genau ab der Hälfte des verfügbaren Speichers, und wächst nach oben hin; Der Stack beginnt am Ende des verfügbaren Speichers, und wächst nach unten hin. Und genau hier kommt HEAP_START ins Spiel; Dieser Wert wird vom Ram-Manager genutzt, um zu prüfen, ob allokierter Speicher den HEAP verletzt (das Speichermanagement von Nano_OS arbeitet im Data-Bereich, nicht im HEAP). Das System funktioniert grad bei zu hoch angesetztem HEAP_START, aber die Kontrollmechanismen versagen. Bitte prüf mal, ob die unten angebenen Einstellungen hier funktionieren; Ich habe keinen 8535 hier. Darüber hinaus hast du deine Stack_Size sehr groß gewählt, mit 96 Byte pro Task wirst du kaum mehr als 3-4 Tasks im System unterbringen können. Bitte prüfe doch mal, ob auch kleinere Stacksizes funktionieren. Da ich davon ausgehe, das es funktioniert, habe ich die geänderte Version bei sourceforge hochgeladen. #define RAMSTART 0x060 #define HEAPSTART 0x015F #define STACK_SIZE 96 #define TIMER_REGISTER TCCR0 #define TIMER_ENABLE TIMSK #define TIMER_VECTOR TIMER0_OVF_vect #define CLK1 _BV(CS00) #define CLK1024 _BV(CS02) |_BV(CS00)
Datum:
Hallo *.*, hat schon einer von Euch die Software von Tobias im AVR Studio (4.18 SP3) zum "Laufen" gebracht? Eine Erfahrungsaustausch wäre für mich hilfreich (ggf. außerhalb des Forums) schneereiche Grüße Bernd
Datum:
Für was benötigt man das AVR Studio? ich verwende den avr-gcc-4.3.4 in der Bash-Shell mit einem makefile. und alles ist gut !
Datum:
ich ebenso. was genau ist denn das probmem beim avr studio? gruss tobi
Datum:
Hallo Tobi, hallo Olli und *.*, DANKE Euch für die Anteilnahme.... Das Problem ist nicht gelöst - jedoch umgangen. Die *.c-Datei - bis auf nano_os.c - habe ich einfach von der Liste der Sourcedateien in die Liste der Headerdateien verschoben, und schwupp, dann werden diese *.c-Dateien auch nicht compiliert. Keine Ahnung, ob das der eleganteste Weg ist, er funktioniert. schneereicher werdende Grüße Bernd PS Offensichtlich werden alle Sourcedateien in der obengenannten Source-Liste kompiliert und dann fehlen einige Deklarationen, da einige notwendige Headerdateien nicht gelesen worden sind.
Datum:
es sollte reichen wenn du nur nano_os.c in der liste der zu kompilierenden dateien hast, und die liste der header leer ist, da die abhaengigkeiten in nanoos.c selbst aufgeloest werden. gruss tobi
Datum:
Hallo Tobi, DANKE für Deine Nachfrage und meine Antwort ist JA. Einige Ideen habe ich noch zum NanoOS. Wenn ich damit fertig bin, mag ich mit Dir gerne darüber diskutieren. Deine E-Mail kenne ich ja bereits. DANKE und noch eine schöne Adventszeit... jetzt hier leider ohne Schnee Bernd
Datum:
ps. nano os entstand ja mal aus einer diplomarbeit. diese wurde mit 1.3 benotet :) damit bin ich jetzt dipl.-inf. ;) !
Datum:
Angehängte Dateien:Guten Abend, ich habe angefangen den Code für den atMega32 an zu passen. "system/header/nano_os.h"
#elif defined (__AVR_ATmega32__) #define RAMSTART 0x60 #define HEAPSTART 0x085f #define STACK_SIZE 54 // immer Timer0 ! #define TIMER_REGISTER TCCR0 #define TIMER_ENABLE TIMSK #define TIMER_VECTOR TIMER0_OVF_vect #define CLK1 _BV(CS00) #define CLK1024 _BV(CS02) |_BV(CS00) |
Das Makefile reflektiert nun meine Hardware. Mit einem Dummy
user.c |
void init_user_environment()
{
asm("nop"); //only placebo
}
void shutdown_user_environment()
{
asm("nop"); //only placebo
} |
Liegt der Speicherbedarf bei text data bss dec hex filename 2682 8 249 2939 b7b nano_os.elf .
Datum:
Hallo Tobi, da ist noch ein Fehler:
HEAPSTART 0x085f |
Habe ich gegen
HEAPSTART 0x085f-0x0100 |
ersetzt, den 0x085f ist das Ende des SRAM, sorry.
Datum:
Hab grad mal nachgesehen..Heapstart müsste 0x0460 sein, korrekt? Der RAM beginnt ja bei 0x0060 = 96 Dez, und endet bei 0x85F = 2143 Dez. Berücksichtigt man den offset, ist HEAPSTART = 2143 -1024 = 0x0460 Hex. Merke HEAPSTART ist in der Regel genau SRAM/2. gruß tobi
Datum:
@Uwe: Hast du meine Änderung bezüglich HEAP_START mal testen können?
Datum:
Zur Info: Ich arbeite grad an ner Displayansteuerung für Graphic Displays (basierend auf KS-Kontroller). Ich melde mich, wenn ich da was habe. gruß tobi
Datum:
Hallo Tobias, ich habe Dein OS mit win-gcc nach Anpassung der Pfade am makefile und den "only placebo" Userfunktionen für ein mega32 mit allen Fähigkeiten übersetzen können. Jetzt möchte ich das natürlich mit Leben füllen... Dazu 2 verwandte Fragenkomplexe. 1. hat sich mit der Timerproblematik noch was ergeben? Ich meine damit, wie man genaue Timer z.B. für Servos hinbekommt, die Idle- oder Task tauglich sind. Ich hätte auch nichts dagegen, einen 2.ten Timer dafür zu "verschwenden" wenn dieser flexibel nutzbar ist. Ich weis nur leider nicht, wie man das passend für das OS anstellt. Schön wäre natürlich, wenn man dem OS sagen kann: "Wecke mich alle 20ms auf" oder "wecke Task x in 3ms" und der Task dann z.B. in Tiefschlaf geht, also auch nicht im normalen Scheduler geweckt wird. Eine Art Timeralarmfunktion für Tasks also, gefüttert z.B. durch eine Eventliste. Irgendwie sowas... 2. ich möchte ein TWI Treiber für das OS bauen, der per ISR Slave mode macht. Kann ich mir da jetzt einfach ne ISR basteln oder muss ich in Bezug auf das OS was beachten? Wenn ja, was? Gibt es vielleicht ein Template für ISRs so wie das User File? Ist das Messagesystem geeignet um es für die Zeichenübertragung an/von TWI bzw. an die ISR zu flanschen? Wie löst man hier überhaupt systemnahe oder zeitkritische Aufgaben am besten? Als Usertask? Und dann TASK_ENTER_CRITICAL;/TASK_LEAVE_CRITICAL; ? Ein paar Beispiele wie man das OS mit der Hardware zusammen bringt wären nicht schlecht, und vielleicht noch ein paar Taskhandling Funktionen bei/für Event Steuerung würden mir helfen. LG Rolf
Datum:
Hi Rolf, ich bin grad auf Arbeit aber werde dir bis zum WE antworten! gruß tobi
Datum:
So, jetzt die versprochenen Antworten: 1.) Du kannst einen 2. timer benutzen; Das OS selbst belegt ja lediglich timer0. Auch gibt es eine Funktion task_sleep_for_laps(), welche einen Task für eine definierte Anzahl an aufrufen aus dem Scheduling nimmt. Die länge einer solchen Aufrufrunde ist fest, wenn nicht irgendwo das Multitasking (z.b. mit TASK_ENTER_CRITICAL) unterbrochen wird. 2.) Du kannst mit einer ISR arbeiten. Dabei musst du allerdings bedenken, das die ISR Interrupts und damit das Multitasking unterbricht, während sie abgearbeitet wird. Die abgefragten Daten kannst du in eine Message Queue schreiben und sie von dort später wieder auslesen. Genau dafür ist das Queuing ja da. 3.) Die Programmierung jeder Art von Aufgaben erfolgt genauso, wie bei der Programmierung ohne Multitasking, mit dem unterschied, dass der Code hier in einen Task verlagert wird. Sind Aufgaben zeitkritisch, kann das Multitasking mit TASK_ENTER_CRITICAL (unterbricht alle Interrupts) oder MULTITASKING_DISABLE (unterbricht nur das Multitasking) unterbrochen werden. Im nano_os quelltext (https://sourceforge.net/projects/nanoos/ ) ist in user.c ein Beispiel für eine Binäruhr enthalten, welche Tasten per ISR abfragt, LEDs über separate Tasks steuert und Timer2 zur Zeitberechnung nutzt. gruß tobi
Datum:
Hallo Tobias, das ist mir soweit klar, trotzdem suche ich eine Möglichkeit bestimmte Tasks eventgesteuert (per Timer,INT) sofort zu wecken bzw. schlafen zu legen wie es RT-OSe üblicher Weise anbieten - und nicht abzuwarten bis der Scheduler den richtigen Task irgendwann weckt. Ich sehe meine Anfrage auch als Vorschlag das OS in dieser Richtung weiter zu entwickeln. Ich hatte mir den Source und das Uhrenbeispiel bereits angesehen. Aber Danke für die Antwort, ich werde sehen ob ich mit den jetzt vorhandenen Möglichkeiten mein Ziel erreichen kann. Evtl. geht es mit der ISR und den Queues auch. LG Rolf
Datum:
Hallo Rolf, Dafür gibt es die Funktionen task_sleep() bzw. task_wake(), welche einen Task schlafen legen bzw. wecken, und auch einen Taskwechsel auslösen. Diese Funktionen sind Interrupt-fest, d.h. du kannst sie z.B. in deiner ISR verwenden, um Tasks schlafen zu legen bzw wieder zu aktivieren. Allerdings beeinflusst task_wake() die Reihenfolge des Schedulings selbst nicht. Ergo kannst du einen Task sofort schlafenlegen, aber nicht sofort wieder aufwecken. Ich habs damals nicht gebraucht, und von daher nicht implementiert. Dies wäre aber recht einfach implementierbar, z.B. über eine globale Variable, in der man dem Scheduler vorgibt, welchen Task er als nächstes anzusteuern hat. Im Grunde müsste es sogar funktionieren, einfach active_task_id selbst zu manipulieren, in der art active_task_id = t-> ID -1; innerhalb von task_wake(); Aber ich bin müde und daher ist das nur als Anregung zu sehen. Wenn ich Zeit hab, implementier ich das gern mal. Oder du darfst es auch gern implementieren, und ich würde es dann übernehmen, wenn du magst. Hilft dir das weiter? gruß tobi
Datum:
Hallo Tobias, Danke, das hilft mir sicherlich aber ich werde Zeit brauchen um das umzusetzen. Ich denke doch, das es dem OS viel bringen würde auch wenn Du es vielleicht nicht selbst brauchst. Wenn man schnell auf Daten reagieren muss (Uart mit hohen Baudraten, Encoderauswertung usw.), macht es Sinn den betreffenden Task von der ISR aus direkt zu wecken oder man müsste die ISR quasi "am Scheduler vorbei" viel erledigen lassen - was wohl nicht im Sinne von ISR's und Taskswitching ist. Ich will versuchen das OS auf einem Bot einzusetzen und da gibts erst mal jede Menge anderer Baustellen. Danke also erst mal für die Tips. Sollte ich es wider Erwarten vor Dir umsetzen, geb ich Dir den Code natürlich. LG Rolf
Datum:
Angehängte Dateien:Hi, ich habe die Funktionalität implementiert und getestet. task_wake() schaltet jetzt direkt zum aktiven task um und aktiviert diesen. Zusätzlich gibt es eine neue Funktion task_switch(), welche zu einem bereits aktiven Task umschaltet. Die neue Version liegt auf Sourceforge bereit. Anbei ein Beispiel der Binäruhr, welches task_wake() und task_sleep() unter Einbeziehung von ISR implementiert. gruß tobi
Datum:
Das freut mich sehr, da kann man ja echt nur den Hut ziehen. Der Compiler nimmt es auch wie ich grade getestet habe. Damit ist das OS nun auch echtzeitfähig. Wau... SUPER! Danke. LG Rolf
Datum:
Kein Thema ;) Bitte alles testen, ich freu mich über feedback! gruß tobi
Datum:
Aktuell leider nicht. Wenn du mir sagst, was du genau brauchst, kann ichs aber ermitteln (RAM-Verbrauch?, Flash?, ...).
Datum:
Mit:
void init_user_environment(){
asm("nop"); //only placebo }
void shutdown_user_environment() {
asm("nop"); //only placebo }
und
#define TASK_USE_SLEEP
#define TASK_USE_ANHILATE
#define TASK_USE_MESSAGE
#define TASK_USE_SEMAPHORE
#define TASK_USE_MEM
komme ich auf einem mega32 zu:
Size after:
nano_os.elf :
section size addr
.text 3198 0
.data 8 8388704
.bss 419 8388712
LG Rolf
Datum:
Da übersetzt du aber unoptimert, oder? Und die user.c muss im Grunde komplett leer sein, mal abgesehen von den Funktionsaufrufen selbst. Ich meine, der reine Scheduler waren so 1200 Byte auf nem Mega168. Ich werd demnächst mal alle footprints ermitteln, und auch den Speicherverbrauch neu berechnen. PS. Ich habe task_wake() nochmal geändert. Es gibt jetzt einen zusätzlichen Parameter realtime, der steuert, ob sofort zu dem task umgeschaltet werden soll, oder ob das Scheduling normal weiterlaufen soll. Ich habs auf Sourceforge hochgeladen.
Datum:
Angehängte Dateien:Hallo Tobi,
ich habe deine aktuellen Quellen bei mir übersetzt und eine (fast) leere
user.c/.h verwendet.
Das Makefile hat noch weitere optimierungs Parameter erhalten !
atmega168
$ avr-size nano_os.hex
text data bss dec hex filename
0 744 0 744 2e8 nano_os.hex
atmega88
$ avr-size nano_os.hex
text data bss dec hex filename
0 692 0 692 2b4 nano_os.hex
atmega32
$ avr-size nano_os.hex
text data bss dec hex filename
0 712 0 712 2c8 nano_os.hex
Datum:
Hallo Tobi,
den atTiny861, habe ich auch eben noch eingebaut.
Die Quelldateien sende ich Dir noch zu.
atTiny861
$ avr-size nano_os.hex
text data bss dec hex filename
0 526 0 526 20e nano_os.hex
Datum:
Ich hatte -Os bzw. OPT = s und MCU = atmega32 und sonst nur die Pfade im makefile angepasst, eine quasi leere user.c und alle Funktionen in der nano_os.h angeschlatet. Wie eben beschrieben. Allerings übersetzt mit der aktuellen winavr bzw. gcc. Mich wundern etwas eure .text Segmente mit 0 byte da bei mir dort der Code drin liegt. Wenn ich nicht alles einschalte wie im Beispiel vorgegeben, komme ich so auf 2,7k codesegemt. Ihr habt wohl bischen doll optimiert oder? *lach LG Rolf
Datum:
Mit den extra Flags aus dem Makefile da, und allen bisherigen Einstellungen komme ich auf: Size after: nano_os.elf : section size addr .text 796 0 .data 2 8388704 .bss 404 8388706 Ob der Code so stramm gezogen noch lauffähig ist, kann ich grade nicht testen. Da aber quasi kein Usercode da ist, könnte das passen wenn der gcc gut optimiert. Nur ist das eben auch kein realistischer Usercode. Das Hex hat 2272 byte. LG Rolf
Datum:
Achso.. das Codesegmet liegt dort scheinbar in Data... Sachen gibts... ## Zusatz Flags CFLAGS += -fno-inline-small-functions CFLAGS += -fno-split-wide-types CFLAGS += -fno-tree-scev-cprop CFLAGS += -fno-move-loop-invariants CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections CFLAGS += -Wl,--relax ## -- ende -- Was ist von den Flags im OS zu halten? Spricht was gegen die Nutzung? LG Rolf
Datum:
Hallo Uwe, ich brauche eigentlich nur die Einstellungen in nano_os. h für den tiy861. Wie viel RAM/FLASH hat der denn? Kurz zum footprint:da dies ja den reinen Bedarf des OS angeben soll, bitte nur ohne usercode und mit verwendeten Optimizations angeben. Ich komme mit gcc opt-level 3 auf etwa 900-2500 Byte, je nach Anzahl der aktivierten features. RAM-Bedarf habe ich jetzt nur grob nachgerechnet und ist auch stark von der Anzahl der Tasks und der Feature-nutzung abhängig, aber grob lässt sich von max. 250 Byte (alle features aktiv) + 9 Byte und STACK_SIZE für jeden task + 1 Byte für jeden Semaphor + 7 Byte pro Message Queue + x Byte für Speicherböcke, Messages usw. ausgehen. Der Bedarf an Rechenzeit ist natürlich vom Prozessortakt, der Anzahl und Nutzung der Features sowie Priorität und Anzahl der Tasks abhängig. Er bewegt sich gerechnet (also geschätzt g) im Bereich von 1% (16 MHz, keine Featurenutzung) bis 25% (1 MHz, Features werden massiv genutzt). gruß tobi
Datum:
Hallo Rolf
ich habe bei meine Atmel Projekten lange mit den Compiler- und
Linker-Flags gespielt, bis ich eine minimale Codegröße erreichte.
Der Link kann nun Daten und Codesegmente löschen, die nicht benötigt
werden.
Somit ist bei meinem Angaben einer Codegröße nur wirklich der Code
aufgeführt, der auch aufgerufen wird.
Hier zum Vergleich die Angaben für den atTiny861:
$avr-size nano_os.elf
text data bss dec hex filename
516 2 402 920 398 nano_os.elf
$avr-size nano_os.hex
text data bss dec hex filename
0 518 0 518 206 nano_os.hex
Hier die Makefile Erweiterung zur Optimierung:## Zusatz Flags CFLAGS += -fno-inline-small-functions CFLAGS += -fno-split-wide-types CFLAGS += -fno-tree-scev-cprop CFLAGS += -fno-move-loop-invariants CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections CFLAGS += -Wl,--relax ## -- ende -- |
Datum:
Hallo Tobias, also per default sind im include 4 Tasks eingetragen... (aber nicht angelegt.. egal), dann hab ich meine Einstellungen schon genannt, -Os , mega32 , alle Funktionen enabled, als "usercode" die Nops aus dem Beispiel-Template wie gepostet, und die Size wie sie dem Linker bekannt sind mit text/bss Segmentangabe. Und dann einmal ohne Uwes Optionen und einmal mit. Der Code ist ungetestet. Jetzt auch mit der letzten Version incl. realtime == 1 Abfrage. Da Du nach -O3 fragst, noch mal meine Werte für O3 statt -Os, alles andere wie vorher. Ohne Uwes CFLAGS Size after: nano_os.elf : section size addr .text 3720 0 .data 8 8388704 .bss 419 8388712 Mit Uwes CFLAGS Size after: nano_os.elf : section size addr .text 856 0 .data 2 8388704 .bss 404 8388706 LG Rolf
Datum:
Nachtrag: zum Thema Options bzw. Uwes Flags hab ich hier noch was gefunden... http://www.tty1.net/blog/2008-04-29-avr-gcc-optimi... LG Rolf
Datum:
@Rolf/Uwe: Ich wär sehr daran interessiert zu erfahren, ob der optimierte Code noch lauffähig ist. Mein aktueller Code für einen atmega168 ist für die Binäruhr mit den Features -"Message Queue", -"dynamic task management" und -"Speichermanagement" also #define TASK_USE_ANHILATE #define TASK_USE_MESSAGE #define TASK_USE_MEM mit dem original makefile genau 3608 byte groß: section size .text 3600 .data 8 .bss 0
Datum:
Hi Tobias, Ich warte auf ein Ersatzteil aber hoffe das ich gegen Ende der Woche mit Tests beginnen kann. Ich werde auf jeden Fall meine Ergebnisse zum Thema Optionen posten. Bedenke aber, das man für -fno-tree-scev-cprop min. den GCC 4.3.0. braucht. Ich könnte mir vorstellen, das mancher noch ältere gcc Versionen preferiert. Ich nutze den gcc version 4.3.3 (WinAVR 20100110) Da der Parameter aber NO-tree-scev-cprop heisst, denke ich das es eher negativen Einfluß hat wenn man ihn nutzt... weil er offensichtlich was abschaltet. Aber das nur nebenbei. Die Compileroptionen von Uwe scheinen mir also nicht optimal zu sein. Wenn man -fno-split-wide-types weg lässt, spart man noch mal 4 Byte im text Segment. Lässt man -fno-inline-small-functions weg, spart man noch mal ganze 96 byte - vermutlich schnöde pushs/pops die ggc sonst anlegt. Weglassen von -Wl,--relax und Anderen erhöht den Code um 6 Byte - das einzige was wirklich entscheidend auf die Codegröße einwirkt ist: -ffunction-sections -fdata-sections -Wl,--gc-sections, das wäre also mal genauer zu hinterfragen. Die -OS und -O3 machen dabei auch nur Unterschiede einiger weniger Bytes aus. Das auch nur nebenbei. LG Rolf
Datum:
Noch mal ich... --gc-sections auf AVRs scheint kritisch zu sein. Da gibts wohl nen Bug im Linker. Last Post ist von Feb 25, 2011, also aktuell. http://www.avrfreaks.net/index.php?name=PNphpBB2&f... Ich glaube nicht, das man das dem OS antuen sollte... Weiteres erst gegen Ende der Woche. LG Rolf
Datum:
Und jetz wieder ich ;) Habe die Anpassungen für den Tiny861 überprüft und mit aufgenommen. Damit sind wir bei Version 0.05 und supporten folgende Prozessoren: Atmega32, AtMega88, AtMega168 At90s8535 AtTiny861 Das neue File liegt wie immer auf Sourceforge.net http://sourceforge.net/projects/nanoos/ Die Compiler-Optimierungen kann ich selbst auch frühestens am WE testen. So lange hier nicht geprüft ist, dass der Code unter allen Umständen funktioniert, übernehme ich sie noch nicht ins Makefile. Noch mal zum Tiny861. Ich hab mir mal das Datenblatt angesehen. Reich bestückt mit Timern ist er ja nicht grad...da das OS einen Timer braucht, stellt sich die Frage, ob es sinnvoller ist, beim 861 den Timer0 oder Timer1 zu nutzen: -Timer 0 ist 16 Bit-fähig, aber bietet weniger Features und weniger Compare Register -Timer1 ist ein reiner 8-Bit-Timer (was für nano_os reicht), bietet aber mehr features (die bei Nutzung für nano_os verloren gehen). Wie seht ihr das? gruß tobi BTW: Wer hat lust auf sourceforge einen review zu schreiben... ;)
Datum:
Hallo Tobias, danke für die Umsetzung, der atTiny861 hat eine PLL für die PWM-Kanäle und drei PWM, die sollten erhalten bleiben. Keine Angst mit den Linkeroptionen, ich arbeite nur damit und bisher läuft jeder Code und alle Programme die ich damit übersetze ! Siehe: Beitrag "Jumbo-LED Uhr" .
Datum:
Hallo Tobias, hab noch mal bischen wegen der Linkeroptions recherchiert. Da ist im Prinzip nichts gegen einzuwenden, allerdings ist grade in Bezug auf ISRs, Handler (anspringen über selbstgestrickten Pointer) zu beachten, das diese nicht fälschlicher Weise vom Compiler entfernt werden. Siehe auch: http://www.mikrocontroller.net/articles/GCC:_unben... D.h. die Flags entfernen Code auf Linkerlevel, der nicht direkt angesprungen wird. Da der Code eh per #define configuriert wird, macht das wenig Sinn mit den Linkerflags. Will sagen, die Fehler die man damit provoziert und ggf. debugen muss, stehen für den normalen Anwender in keinem Verhältnis zum Gewinn an Bytes da man denn unbenutzten Code auch anders und risikoärmer entfernen kann. Es würde nur was bringen wenn man aus einem Funktionspaket wie Messaging zwar eine Funktion nutzt aber den Rest raus haben will. In Einzelfällen mag das angebracht sein, allgemein würde ich das strikt ablehnen zumal es auch um so weniger bringt, je mehr Funktionen man aktiv nutzt. Eine feinere Granulierung von #define würde da ohne die Fehlerquote anzuhheben mehr nutzen aber selbst da ist fraglich ob sich der Aufwand wegen ein paar Byte lohnt. Ich sehe das nicht so. Selbstgeschriebene Programme enthalten auch selten unbenutzen Code, aber wers braucht... wirds sich schon selbst ins makefile einbauen können :) Das einzige was ich für mich gern nutzen würde ist CFLAGS += -Wl,--relax aber auch das scheint avr-ld wie bei -Wl,--gc-sections zumindest nach avrfreaks.net nen Bug zu haben. @Uwe, deine Beteuerung in Ehren...aber nen einzelnes Programm ist was anderes als ein OS - das Leute ggf. nutzen ohne sowas noch mal zu verifizieren. Tobias tut gut daran, sowas konservativ zu sehen. Da Du den Mega32 schon drin hast, kannst du glaube ich auch den Mega16 noch direkt einbauen, so weit mir bekannt hat der nur einfach bissel weniger Speicher. 16k Flash, Ramstart ist 0x60 und Ramend 0x45F, also 1KB Ram, sonst baugleich zum mega32. Ob das OS auf nem mega8 Sinn macht... keine Ahnung. LG Rolf
Datum:
Hallo @all, Ich denke auch, das ich das Makefile zunächst einmal so lasse wie es ist. Zusätzlich zu den von rolf angeführten Bedenken frage ich mich auch, inwieweit Funktionen, welche über Pointer addressiert werden (wie z.B. die Tasks selbst) "wegoptimiert" werden, da der Compiler deren Aufruf schlicht nicht erkennt, und sie somit für überflüssige Funktionen hält. gruß tobi
Datum:
Ups...vergessen: Ich muss auch ehrlich gestehen, dass ich mich mit den Optimierungen des gcc nicht so gut auskenne, auch von daher bin ich damit lieber erstmal vorsichtig. Zum Mega16...kannst du das in Hardware verifizieren? Ich habe aktuell leider keine Mega16 da. Der Mega8 ist auch sehr interessant! gruß tobi
Datum:
Hallo Tobi, nein ich hab leider kein Mega16 zum testen. Aber die Mega Serie unterscheidet sich zwischen den 3 Typen nicht so dramatisch - sagt zumindest das Datenblatt. Aber vielleicht ists besser zu warten bis einer es wirklich austestet. Der mega8 ist arg klein mit 8k Flash... der Unterschied dürfte eher im Pinout wirken (DIP 28 / 40 Pin) aber das ist für das OS ohne Bedeutung. Der mega8 und mega16 haben je 1k Ram. Laufen müsste das OS auch da. http://www.atmel.com/dyn/resources/prod_documents/... / mega8 http://www.atmel.com/dyn/resources/prod_documents/... / mega16 http://www.atmel.com/dyn/resources/prod_documents/... / mega32 Hier die Datenblätter. Als Vergleich der Mega644 http://www.atmel.com/dyn/resources/prod_documents/... mit einer etwas anderen Memory Map. LG Rolf
Datum:
Hi, habe den Mega8/16 mit aufgenommen und auf sourceforge hochgeladen. Auch gibts jetzt eine Fehlermeldung, wenn ein unbekanntes device verwendet wird, und ich habe den Parameter "STACK_SIZE" ausgelagert, da er vom verwendeten Device unabhängig ist. Ab jetzt gibt es dort auch ein changelog und die "alten" releases als Historie. Damit sind wir bei Version 0.06 gruß tobi
Datum:
@Rolf/Uwe/anybody ;) Gibts news? Wie weit sind eure Entwicklungen? Wird noch irgend was benötigt oder gibts bugs?
Datum:
hacker-tobi schrieb: > [..] Wird noch irgend was benötigt [..] Benötigt nicht unbedingt, aber eine Portierung auf die AVR-XMega-Serie fände ich echt gut.
Datum:
hi, gern. habe leider zur zeit keine xmegas. aber soweit mir bekannt ist, sind die unterschiede ja nicht so gross. gruss tobi
Datum:
hacker-tobi schrieb: > @Rolf/Uwe/anybody ;) > > Gibts news? Wie weit sind eure Entwicklungen? Wird noch irgend was > benötigt oder gibts bugs? Vielleicht könnte man mal das includieren von *.c files rausnehmen. Oder gibt es einen vernünftigen Grund dafür?
Datum:
Hallo @all Hm... neues gibts wenig - mir fehlt etwas die Zeit aber das gibt sich hoffentlich. Zum Thema .c includieren, ich hab da kein Problem mit und hätte ich eins, würd ich mir vielleicht die includierten c-files nach .h umbenennen und gut is. Was ich jedoch anregen möchte ist eine kleine Internetpräsenz für das OS. Muss ja nicht mal umfangreich sein aber es würde sicherlich mehr Aufmerksamkeit geben und man kann auch besser die "Fan-Gemeinde" betreuen und bei Bedarf ausbauen. Sich die Facts hier in dem Thread zusammen zu suchen ist zwar auch ok aber besser ginge das sicherlich strukturiert auf einer Webseite. Is aber nur eine Idee denn ich hab keine Ahnung, wie viel Dir an der Verbreitung des OS gelegen ist bzw. wieviel Zeit Du da investieren kannst/willst. Ich hoffe, ich komme in den nächsten 2 Wochen dazu, das i2c an das OS zu flanschen. LG Rolf
Datum:
Hi, das Thema c-Files includieren gab es oben irgendwo schonmal. Ich lasse das bis zum nächsten major Release so wie es ist, denn es funktioniert problemlos, und ich hab momentan ehrlich gesagt keine Lust, da jedes File nochmal anfassen zu müssen. Wenn nochmal ein major Release ansteht, nehm ich es in dem Zug aber mit auf. Eine Internetpräsenz gibt es doch: http://sourceforge.net/projects/nanoos/ Dort findet man alle Files, eine kurze Erläuterung sowie die Features, einen Bugtracker und release Notes. Auch Erfahrungsberichte können dort hinterlassen werden, worum ich jeden herzlich Bitte!
Datum:
Ach ja...noch ein update zum Display Treiber für Grafikdisplays. Meine Testboards habe ich heute aufgebaut, jetzt kann da die Entwicklung losgehen ;)
Datum:
Schieb Wie ist der aktuelle Status? Bei mir gibts noch nichts neues, melde mich, wenn der Grafiktreiber fertig ist. gruß tobi
Datum:
Angehängte Dateien:Zum Thema mit den c Files Includieren, das hab ich gelöst. siehe Anhang Wenn ihr es verwenden wollt ok, der svn ist ja noch leer ;-) sonst weg damit. Compilieren tut es mit WinAVR (gcc 4.3.3) und auch MVHTools (gcc 4.5.2) viel spass
Datum:
Hallo, Ich sehe mir gerade die Änderungen von Achill an. Ich bekomme hier 2 Warnungen, das init_user_environment() und shutdown_user_environment() keine Prototypen wären, durch ein #include "nano_os.h" #include "user.h" in user.c lässt sich das umgehen. Dann hab ich in nano_os.h die Zeilen: //+++++++++++++++++++++GLOBAL DEFINE+++++++++++++++++++ /* set in Makefile ! ... */ gefunden, im Makefile werden sie nicht gesetzt, auch im Makefile von Sourceforge tauchen sie nicht auf. Es leuchtet mir zwar der Sinn ein, die Defines projektabhängig ins eigene Makefile zu packen aber dann sollten die auch im Beispiel makefile - ggf. auskommentiert - auftauchen, oder? Ich hab mir das Ganze jetzt noch im AVR Studio 4 geladen und es scheint alles gut. Leider bin ich mit meinem Projekt noch nicht viel weiter gekommen. Ich bin auf den Grafiktreiber gespannt LG Rolf
Datum:
Kurzes update: Ehrlich gesagt noch nichts neues. Zur Zeit haben andere Dinge priorität. Vergessen ists aber nicht! gruß tobi
Datum:
Hi, ich wolltemal hören,wie der Stand der NanoOS-Projekte so ist. Zwischendurch bin ich etwas weitergekommen; Das Display-board ist fertig. Aktuell sitze ich grad an dem Treibermodul. gruß tobi
