Forum: Projekte & Code NeuesOS für AVR Mikrocontroller


von hacker-tobi (Gast)


Angehängte Dateien:

Lesenswert?

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

: Verschoben durch User
von Tom M. (tomm) Benutzerseite


Lesenswert?

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. ;)

von Olaf (Gast)


Lesenswert?

>  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

von hacker-tobi (Gast)


Lesenswert?

@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

von mar IO (Gast)


Lesenswert?

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:
1
void scheduler() __attribute__ ((naked));
2
void scheduler()
3
{
4
    ...
5
}

GCC Function-Attributes
http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

von hacker-tobi (Gast)


Lesenswert?

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

von mar IO (Gast)


Lesenswert?

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
1
#define PUSH(r) asm volatile("push r"#r)
2
#define POP(r) asm volatile("pop r"#r)
3
4
// ...
5
6
void scheduler()
7
{
8
//save R0-31 to current->stack
9
PUSH(31);PUSH(30);PUSH(29);PUSH(28);PUSH(27);PUSH(26);PUSH(25);PUSH(24);
10
PUSH(23);PUSH(22);PUSH(21);PUSH(20);PUSH(19);PUSH(18);PUSH(17);PUSH(16);
11
PUSH(15);PUSH(14);PUSH(13);PUSH(12);PUSH(11);PUSH(10);PUSH( 9);PUSH( 8);
12
PUSH( 7);PUSH( 6);PUSH( 5);PUSH( 4);PUSH( 3);PUSH( 2);PUSH( 1);PUSH( 0);
13
14
// ...

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"

von Tobias W. (hacker-tobi)


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

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

von Roman65536 (Gast)


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

Hallo Roman,

prinzipiell eine gute Idee. Ich nehme an, du meinst ein Konstrukt a la

if (SP >= (current->sp + STACK_SIZE))
 task_anhilate(&current);

?

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(&current)

Bitte korrigiert mich, wenn ich falsch liege.

PS. task_anhilate ist jetzt natürlich nur ein Beispiel; hier könnten 
auch andere Aktionen stehen.

von hacker-tobi (Gast)


Lesenswert?

166 downloads... weitere Ideen/Anregungen?

von Lernender (Gast)


Lesenswert?

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ß

von hacker-tobi (Gast)


Lesenswert?

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...

von Lernender (Gast)


Lesenswert?

Hallo hacker-tobi,

danke für die schnelle Info.

Gruß

von bachelor (Gast)


Lesenswert?

Hi,

das ganze klingt sehr interresant. Wird deine Diplomarbeit noch anders 
veröffentlicht. (z.B. von der Uni)

grüße

von mar IO (Gast)


Lesenswert?

1
//+++++++++++++++++TASK Control Structure+++++++++++++++
2
typedef volatile struct Task
3
{
4
  volatile uint8_t ID;
5
  volatile unsigned char sreg;
6
  volatile unsigned char *sp;
7
  volatile TaskPrio prio;
8
#ifdef TASK_USE_SIGNAL
9
  volatile TaskState state;
10
  volatile uint8_t laps;
11
#endif
12
  volatile unsigned char stack[STACK_SIZE];
13
} 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
1
 if (SP < current->stack) ...
und ein StackUNTERlauf triff auf, wenn SP größer als höchste Adresse vom 
Array current->stack[]
1
 if (SP >= &(current->stack[STACK_SIZE]) ...

von mar IO (Gast)


Lesenswert?

1
// Ausschnitt nano_os.h
2
// ...
3
//+++++++++++++++++++++Signal-Handler++++++++++++++++++
4
SIGNAL (SIG_OVERFLOW0)
5
{
6
scheduler();
7
}
8
// ...

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).
1
void scheduler()
2
{
3
//save R0-31 to current->stack
4
PUSH(31);PUSH(30);PUSH(29);PUSH(28);PUSH(27);PUSH(26);PUSH(25);PUSH(24);
5
PUSH(23);PUSH(22);PUSH(21);PUSH(20);PUSH(19);PUSH(18);PUSH(17);PUSH(16);
6
PUSH(15);PUSH(14);PUSH(13);PUSH(12);PUSH(11);PUSH(10);PUSH( 9);PUSH( 8);
7
PUSH( 7);PUSH( 6);PUSH( 5);PUSH( 4);PUSH( 3);PUSH( 2);PUSH( 1);PUSH( 0);
8
TIMER_REG = CLK1024;
9
//save SREG and SP
10
if (currentTask >= 0)
11
  {
12
  current = tasks[currentTask];     // // // // die Zeile
13
  current->sreg = SREG;
14
  current->sp = (unsigned char *)(SP + 32);
15
  }
16
//switch to next task
17
do
18
  {
19
  currentTask++;
20
  if (currentTask >= NUMBER)
21
    {
22
    currentTask = 0;
23
    }
24
  current = tasks[currentTask];
25
26
  #ifdef TASK_USE_SIGNAL
27
  if (current && current->state == TaskStateWaitForLaps)
28
    {
29
    if (current->laps > 0)
30
      current->laps--;
31
    else
32
      current->state=TaskStateActive;
33
    }
34
  #endif
35
36
  }
37
38
#ifdef TASK_USE_SIGNAL
39
while (!(current && current->state==TaskStateActive));
40
#else
41
while (!current);
42
#endif
43
44
//restore this task (SREG, SP and R0...31)
45
if (current)
46
  {
47
  TCNT0 = current->prio;
48
  SREG = current->sreg;
49
  SP = (unsigned int)(current->sp - 32);
50
  }
51
POP( 0);POP( 1);POP( 2);POP( 3);POP( 4);POP( 5);POP( 6);POP( 7);
52
POP( 8);POP( 9);POP(10);POP(11);POP(12);POP(13);POP(14);POP(15);
53
POP(16);POP(17);POP(18);POP(19);POP(20);POP(21);POP(22);POP(23);
54
POP(24);POP(25);POP(26);POP(27);POP(28);POP(29);POP(30);POP(31);
55
asm volatile("reti");     // // // // das reti
56
}

von mar IO (Gast)


Lesenswert?

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__avr__interrupts.html#ga67cd0dea412157775c2f2a3ffe9fb8ff

von Roman65536 (Gast)


Lesenswert?

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

von mar IO (Gast)


Lesenswert?

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

von mar IO (Gast)


Angehängte Dateien:

Lesenswert?

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

von hacker-tobi (Gast)


Angehängte Dateien:

Lesenswert?

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.

von hacker-tobi (Gast)


Lesenswert?

@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 ;)

von hacker-tobi (Gast)


Angehängte Dateien:

Lesenswert?

@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

von Roman65536 (Gast)


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

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.

von hacker-tobi (Gast)


Lesenswert?

Ich seh grad, ich hab gestern versehentlich ne alte Version 
hochgeladen...korigiere ich nacherher.

von mar IO (Gast)


Angehängte Dateien:

Lesenswert?

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__avr__interrupts.html#ga67cd0dea412157775c2f2a3ffe9fb8ff

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"

von Tobias W. (hacker-tobi)


Angehängte Dateien:

Lesenswert?

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

von Helli (Gast)


Lesenswert?

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:
1
#define PUSH(r) asm volatile("push r"#r);
2
#define POP(r) asm volatile("pop r"#r);
3
4
[...]
5
void TIMER_VECTOR() __attribute__ ( ( signal, naked ) );
6
ISR(TIMER_VECTOR)
7
{
8
  PUSH(31);PUSH(30);PUSH(29);PUSH(28);PUSH(27);PUSH(26);PUSH(25);PUSH(24);
9
  PUSH(23);PUSH(22);PUSH(21);PUSH(20);PUSH(19);PUSH(18);PUSH(17);PUSH(16);
10
  PUSH(15);PUSH(14);PUSH(13);PUSH(12);PUSH(11);PUSH(10);PUSH( 9);PUSH( 8);
11
  PUSH( 7);PUSH( 6);PUSH( 5);PUSH( 4);PUSH( 3);PUSH( 2);PUSH( 1);PUSH( 0);

Deins:
1
#define PUSH(r) asm volatile("push r"#r)
2
#define POP(r) asm volatile("pop r"#r)
3
4
//****************************************************
5
//*scheduler()                                       *
6
//*                                                  *
7
//*      !!!INTERNAL FUNCTION!!!                     *
8
//*                                                  *
9
//* description: does the task switching             *
10
//* input: none                                      *
11
//* output: none                                     *
12
//****************************************************
13
14
void scheduler()
15
{
16
//save R0-31 to current->stack
17
PUSH(31);PUSH(30);PUSH(29);PUSH(28);PUSH(27);PUSH(26);PUSH(25);PUSH(24);
18
PUSH(23);PUSH(22);PUSH(21);PUSH(20);PUSH(19);PUSH(18);PUSH(17);PUSH(16);
19
PUSH(15);PUSH(14);PUSH(13);PUSH(12);PUSH(11);PUSH(10);PUSH( 9);PUSH( 8);
20
PUSH( 7);PUSH( 6);PUSH( 5);PUSH( 4);PUSH( 3);PUSH( 2);PUSH( 1);PUSH( 0);
21
TIMER_REG = CLK1024;

Etwas Ehrlichkeit, bitte!

von hacker-tobi (Gast)


Lesenswert?

@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?

von Helli (Gast)


Lesenswert?

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 ...

von hacker-tobi (Gast)


Lesenswert?

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.

von hacker-tobi (Gast)


Lesenswert?

@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

von Helli (Gast)


Lesenswert?

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):
1
void scheduler()
2
{
3
//save R0-31 to current->stack
4
PUSH(31);PUSH(30);PUSH(29);PUSH(28);PUSH(27);PUSH(26);PUSH(25);PUSH(24);
5
PUSH(23);PUSH(22);PUSH(21);PUSH(20);PUSH(19);PUSH(18);PUSH(17);PUSH(16);
6
PUSH(15);PUSH(14);PUSH(13);PUSH(12);PUSH(11);PUSH(10);PUSH( 9);PUSH( 8);
7
PUSH( 7);PUSH( 6);PUSH( 5);PUSH( 4);PUSH( 3);PUSH( 2);PUSH( 1);PUSH( 0);
8
TIMER_REG = CLK1024;
9
//save SREG and SP
10
if (currentTask >= 0)
11
  {
12
  current = tasks[currentTask];
13
  current->sreg = SREG;
14
  current->sp = (unsigned char *)(SP + 32);
15
  }
16
//switch to next task
17
do
18
  {
19
  currentTask++;
20
  if (currentTask >= NUMBER)
21
    {
22
    currentTask = 0;
23
    }
24
  current = tasks[currentTask];
25
26
  #ifdef TASK_USE_SIGNAL
27
  if (current && current->state == TaskStateWaitForLaps)
28
    {
29
    if (current->laps > 0)
30
      current->laps--;
31
    else
32
      current->state=TaskStateActive;
33
    }
34
  #endif
35
36
  }
37
38
#ifdef TASK_USE_SIGNAL
39
while (!(current && current->state==TaskStateActive));
40
#else
41
while (!current);
42
#endif
43
44
//restore this task (SREG, SP and R0...31)
45
if (current)
46
  {
47
  TCNT0 = current->prio;
48
  SREG = current->sreg;
49
  SP = (unsigned int)(current->sp - 32);
50
  }
51
POP( 0);POP( 1);POP( 2);POP( 3);POP( 4);POP( 5);POP( 6);POP( 7);
52
POP( 8);POP( 9);POP(10);POP(11);POP(12);POP(13);POP(14);POP(15);
53
POP(16);POP(17);POP(18);POP(19);POP(20);POP(21);POP(22);POP(23);
54
POP(24);POP(25);POP(26);POP(27);POP(28);POP(29);POP(30);POP(31);
55
asm volatile("reti");
56
}

und das hier ist aus einem hochgeladenen Archiv von 2007 von hier:
Beitrag "Re: GOS: einfacher preemptive multitasking scheduler"
1
void TIMER_VECTOR() __attribute__ ( ( signal, naked ) );
2
ISR(TIMER_VECTOR)
3
{
4
  PUSH(31);PUSH(30);PUSH(29);PUSH(28);PUSH(27);PUSH(26);PUSH(25);PUSH(24);
5
  PUSH(23);PUSH(22);PUSH(21);PUSH(20);PUSH(19);PUSH(18);PUSH(17);PUSH(16);
6
  PUSH(15);PUSH(14);PUSH(13);PUSH(12);PUSH(11);PUSH(10);PUSH( 9);PUSH( 8);
7
  PUSH( 7);PUSH( 6);PUSH( 5);PUSH( 4);PUSH( 3);PUSH( 2);PUSH( 1);PUSH( 0);
8
  TIMER_REG = CLK1024;
9
  Task *current = 0;
10
  if (currentTask >= 0)
11
  {
12
    current = tasks[currentTask];
13
    current->sreg = SREG;
14
    current->sp = (unsigned char *)(SP + 32);
15
  }
16
  do
17
  {
18
    currentTask++;
19
    if (currentTask >= MAX_TASKS)
20
      currentTask = 0;
21
    current = tasks[currentTask];
22
  }
23
#ifdef TASK_USE_SIGNAL
24
  while (!(current && current->state==TaskStateActive));
25
#else
26
  while (!current);
27
#endif
28
  if (current)
29
  {
30
    TCNT0 = current->prio;
31
    SREG = current->sreg;
32
    SP = (unsigned int)(current->sp - 32);
33
  }
34
  POP( 0);POP( 1);POP( 2);POP( 3);POP( 4);POP( 5);POP( 6);POP( 7);
35
  POP( 8);POP( 9);POP(10);POP(11);POP(12);POP(13);POP(14);POP(15);
36
  POP(16);POP(17);POP(18);POP(19);POP(20);POP(21);POP(22);POP(23);
37
  POP(24);POP(25);POP(26);POP(27);POP(28);POP(29);POP(30);POP(31);
38
  asm volatile("reti");
39
}

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

von Helli (Gast)


Lesenswert?

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 ...

von Helli (Gast)


Lesenswert?

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 ...

von hacker-tobi (Gast)


Lesenswert?

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

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von hacker-tobi (Gast)


Lesenswert?

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.

von mar IO (Gast)


Angehängte Dateien:

Lesenswert?

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

1
147 unsigned char queue_read_byte(Queue *qp, uint8_t position, uint8_t delete_message)
2
148 {
3
149 sregsys = SREG;
4
150 cli();
5
151 uint8_t i;
6
152 unsigned char tempmsg;
7
153 if (qp->number == 0 || qp->number <= position || qp->item_size != 1)
8
154  {
9
155   SREG = sregsys;
10
156   return;
11
157   }
12
158 //read message
13
159 tempmsg = qp->message[position];
14
160 if (delete_message)
15
161   {
16
162   //re-organize message queue (FIFO)
17
163   for (i=position;i<(qp->number)-1;i++)
18
164     qp->message[i] = qp->message[i+1];
19
165   qp->number--; 
20
166   }
21
167 SREG = sregsys;
22
168 return tempmsg;
23
169 }

von hacker-tobi (Gast)


Lesenswert?

@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

von Helli (Gast)


Lesenswert?

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 ...

von hacker-tobi (Gast)


Lesenswert?

@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?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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:
1
void taskCreate(Task *t, TaskFunction f, TaskPrio prio)
2
{
3
  cli();
4
        ...
5
  sei();
6
}

Deine Version:
1
void task_create(Task *t, TaskFunction f, TaskPrio prio)
2
{
3
sregsys = SREG;
4
cli();
5
...
6
SREG = sregsys;
7
return;
8
}

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?

von mar IO (Gast)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von mar IO (Gast)


Lesenswert?

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.

von hacker-tobi (Gast)


Lesenswert?

@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

von hacker-tobi (Gast)


Lesenswert?

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?

von mar IO (Gast)


Angehängte Dateien:

Lesenswert?

Ü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???

von mar IO (Gast)


Lesenswert?

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"

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von hacker-tobi (Gast)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Mampf (Gast)


Lesenswert?

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

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

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

von hugo (Gast)


Lesenswert?

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!

von hacker-tobi (Gast)


Lesenswert?

SREG wird in eine globale Struktur vom Typ task gesichert, die mit 
deklaration volatile versehen ist. und wo liegt die? im RAM oder?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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...

von hacker-tobi (Gast)


Lesenswert?

@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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von hacker-tobi (Gast)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von hugo (Gast)


Lesenswert?

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.

von hacker-tobi (Gast)


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

@Frank: Ja kann man so machen. Ich gebe ehrlich zu, dass war reine 
bequemlichkeit. mal sehen, ob ich sreg/sregsys nicht lokal anlege.

von hacker-tobi (Gast)


Lesenswert?

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?

von hugo (Gast)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von hacker-tobi (Gast)


Lesenswert?

@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.

von Tobias W. (hacker-tobi)


Lesenswert?

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).

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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:
1
/*---------------------------------------------------------------------
2
 * FILENAME
3
 *
4
 * Copyright (c) 2010 NAME - MAIL ADDRESS
5
 *
6
 * This program is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 2 of the License, or
9
 * (at your option) any later version.
10
 *------------------------------------------------------------------------
11
 */

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

von Tobias W. (hacker-tobi)


Lesenswert?

@Frank: ok, danke

von hugo (Gast)


Lesenswert?

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!

von hugo (Gast)


Lesenswert?

... Frank war schneller :-)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von hugo (Gast)


Lesenswert?

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

von Tobias W. (hacker-tobi)


Lesenswert?

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....

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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. 
;-)

von Tobias W. (hacker-tobi)


Lesenswert?

@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?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Tobias W. (hacker-tobi)


Lesenswert?

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.

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Tobias W. (hacker-tobi)


Lesenswert?

Es sind etwa 100 Zeilen, habs grad mal grob überflogen.

von Roman65536 (Gast)


Lesenswert?

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

von Martin (Gast)


Lesenswert?

@ Roman65536

Dein Geschreibsel ist kaum zu ertragen, weder Inhalt noch Form genügen 
der Netiquette.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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?

von Tobias W. (hacker-tobi)


Lesenswert?

So ihr hört jetzt auch auf zu zanken ;)

Es bringt doch nix, und macht nur den Thread kapput.


gruß

tobi

von Tobias W. (hacker-tobi)



Lesenswert?

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?

von Tobias W. (hacker-tobi)


Lesenswert?

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

von Simon B. (nomis)


Lesenswert?

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

von Tobias W. (hacker-tobi)


Lesenswert?

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

von man IO (Gast)


Lesenswert?

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
1
//+++++++++++++++++++++Signal-Handler++++++++++++++++++
2
3
SIGNAL (SIG_OVERFLOW0)
4
{
5
    1646:  1f 92         push  r1
6
    1648:  0f 92         push  r0
7
    164a:  0f b6         in  r0, 0x3f  ; 63
8
    164c:  0f 92         push  r0
9
    164e:  11 24         eor  r1, r1
10
    1650:  8f 93         push  r24
11
    1652:  9f 93         push  r25
12
    1654:  ef 93         push  r30
13
    1656:  ff 93         push  r31
14
//****************************************************
15
16
void scheduler()
17
{
18
//save R0-31 to current->stack
19
PUSH(31);PUSH(30);PUSH(29);PUSH(28);PUSH(27);PUSH(26);PUSH(25);PUSH(24);
20
    1658:  ff 93         push  r31
21
    165a:  ef 93         push  r30
22
    165c:  df 93         push  r29
23
    165e:  cf 93         push  r28
24
    1660:  bf 93         push  r27
25
    1662:  af 93         push  r26
26
    1664:  9f 93         push  r25
27
    1666:  8f 93         push  r24
28
PUSH(23);PUSH(22);PUSH(21);PUSH(20);PUSH(19);PUSH(18);PUSH(17);PUSH(16);
29
    1668:  7f 93         push  r23
30
    166a:  6f 93         push  r22
31
    166c:  5f 93         push  r21
32
    166e:  4f 93         push  r20
33
    1670:  3f 93         push  r19
34
    1672:  2f 93         push  r18
35
    1674:  1f 93         push  r17
36
    1676:  0f 93         push  r16
37
PUSH(15);PUSH(14);PUSH(13);PUSH(12);PUSH(11);PUSH(10);PUSH( 9);PUSH( 8);
38
    1678:  ff 92         push  r15
39
    167a:  ef 92         push  r14
40
    167c:  df 92         push  r13
41
    167e:  cf 92         push  r12
42
    1680:  bf 92         push  r11
43
    1682:  af 92         push  r10
44
    1684:  9f 92         push  r9
45
    1686:  8f 92         push  r8
46
PUSH( 7);PUSH( 6);PUSH( 5);PUSH( 4);PUSH( 3);PUSH( 2);PUSH( 1);PUSH( 0);
47
    1688:  7f 92         push  r7
48
    168a:  6f 92         push  r6
49
    168c:  5f 92         push  r5
50
    168e:  4f 92         push  r4
51
    1690:  3f 92         push  r3
52
    1692:  2f 92         push  r2
53
    1694:  1f 92         push  r1
54
    1696:  0f 92         push  r0
55
 
56
...
57
58
POP( 0);POP( 1);POP( 2);POP( 3);POP( 4);POP( 5);POP( 6);POP( 7);
59
    171e:  0f 90         pop  r0
60
    1720:  1f 90         pop  r1
61
    1722:  2f 90         pop  r2
62
    1724:  3f 90         pop  r3
63
    1726:  4f 90         pop  r4
64
    1728:  5f 90         pop  r5
65
    172a:  6f 90         pop  r6
66
    172c:  7f 90         pop  r7
67
POP( 8);POP( 9);POP(10);POP(11);POP(12);POP(13);POP(14);POP(15);
68
    172e:  8f 90         pop  r8
69
    1730:  9f 90         pop  r9
70
    1732:  af 90         pop  r10
71
    1734:  bf 90         pop  r11
72
    1736:  cf 90         pop  r12
73
    1738:  df 90         pop  r13
74
    173a:  ef 90         pop  r14
75
    173c:  ff 90         pop  r15
76
POP(16);POP(17);POP(18);POP(19);POP(20);POP(21);POP(22);POP(23);
77
    173e:  0f 91         pop  r16
78
    1740:  1f 91         pop  r17
79
    1742:  2f 91         pop  r18
80
    1744:  3f 91         pop  r19
81
    1746:  4f 91         pop  r20
82
    1748:  5f 91         pop  r21
83
    174a:  6f 91         pop  r22
84
    174c:  7f 91         pop  r23
85
POP(24);POP(25);POP(26);POP(27);POP(28);POP(29);POP(30);POP(31);
86
    174e:  8f 91         pop  r24
87
    1750:  9f 91         pop  r25
88
    1752:  af 91         pop  r26
89
    1754:  bf 91         pop  r27
90
    1756:  cf 91         pop  r28
91
    1758:  df 91         pop  r29
92
    175a:  ef 91         pop  r30
93
    175c:  ff 91         pop  r31
94
asm volatile("reti");
95
    175e:  18 95         reti
96
scheduler();
97
}
98
    1760:  ff 91         pop  r31
99
    1762:  ef 91         pop  r30
100
    1764:  9f 91         pop  r25
101
    1766:  8f 91         pop  r24
102
    1768:  0f 90         pop  r0
103
    176a:  0f be         out  0x3f, r0  ; 63
104
    176c:  0f 90         pop  r0
105
    176e:  1f 90         pop  r1
106
    1770:  18 95         reti

von Tobias W. (hacker-tobi)


Lesenswert?

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

von Helli (Gast)


Lesenswert?

... 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 ;-)

von hacker-tobi (Gast)


Lesenswert?

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

von fremder (Gast)


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

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.

von hacker-tobi (Gast)


Lesenswert?

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

von Tobias W. (hacker-tobi)


Lesenswert?

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.

von Markus (Gast)


Lesenswert?

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

von Nico22 (Gast)


Lesenswert?

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:
1
uint8_t semaphore_free(Semaphor *s)
2
{
3
        sregsys = SREG;
4
        cli();
5
        if (s->owner != currentTask) 
6
  {
7
          SREG = sregsys;
8
          return 0;
9
  }
10
11
        s->owner = 0;
12
        SREG = sregsys;
13
        return TRUE;
14
}
15
16
//****************************************************
17
//*semaphore_read(Semaphor *s)                       *
18
//*                                                  *
19
//* description: read status of a semaphore          *
20
//* input: Pointer to Semaphore                      *
21
//* output: TRUE(free), NULL(error/non free)         *
22
//****************************************************
23
24
uint8_t semaphore_read(Semaphor *s) 
25
{
26
        sregsys = SREG;
27
        cli();
28
        if (s->owner)
29
  {
30
          SREG = sregsys;
31
          return 0;
32
  }
33
        SREG = sregsys;
34
        return TRUE;
35
}
36
37
//****************************************************
38
//*semaphore_wait(Semaphor *s)                       *
39
//*                                                  *
40
//* description: wait for a semaphore                *
41
//* input: Pointer to Semaphore                      *
42
//* output: TRUE(is free), NULL(error)               *
43
//****************************************************
44
45
uint8_t semaphore_wait(Semaphor *s) 
46
{ 
47
        //enable multitasking to avoid a deadrun 
48
        wdt_enable(WDTO_2S); 
49
        TIMER_ENABLE |= _BV(TOIE0); 
50
        sei();
51
52
        while (s->owner != 0)
53
          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!
54
        return TRUE;
55
}


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

von Nico22 (Gast)


Lesenswert?

haha, toll, die Bordsoftware hats verkackt :-D

von Günter G. (tcg)


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

@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".

von Günter G. (tcg)


Lesenswert?

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 :-(

von Nico22 (Gast)


Lesenswert?

@ 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

von hacker-tobi (Gast)


Lesenswert?

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...

von hacker-tobi (Gast)


Lesenswert?

@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.

von Günter G. (tcg)


Lesenswert?

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 :-)

von hacker-tobi (Gast)


Lesenswert?

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...

von Günter G. (tcg)


Lesenswert?

> 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)

von mar IO (Gast)


Lesenswert?

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)?

von Günter G. (tcg)


Lesenswert?

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...

von hacker-tobi (Gast)


Angehängte Dateien:

Lesenswert?

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.

von hacker-tobi (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Maarten J. (quirk)


Lesenswert?

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.

von Sebastian .. (zahlenfreak)


Lesenswert?

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

von Bernhard M. (boregard)


Lesenswert?

Hallo,

im neuen Scheduler:
1
void scheduler()
2
{
3
  //to avoid inconsistent state when we have a stack overrun/underrun reset the system via watchdog in this case
4
  if (active_task && (SP < (uint16_t) active_task->stack_section || SP >= (uint16_t) active_task->stack_section + STACK_SIZE)) 
5
  {
6
    wdt_enable(WDTO_1S);
7
    while(1);
8
  }
9
  else
10
  {
11
    TIMER_REGISTER = CLK1024;
12
    //save SREG and SP
13
    if (active_task_id >= 0)
14
    {
15
      //save R0-31 to active_task->stack
16
      stack_push(31);
17
      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

von hacker-tobi (Gast)


Lesenswert?

@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

von Bernhard M. (boregard)


Lesenswert?

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

von Günter G. (tcg)


Lesenswert?

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 :-)

von Roman65536 (Gast)


Lesenswert?

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

von Günter G. (tcg)


Lesenswert?

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 :-)
1
void TIMER_VECTOR() __attribute__ ( ( signal, naked ) );
2
ISR(TIMER_VECTOR)
3
{
4
...
5
  asm volatile("reti");
6
}

(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...

von Roman65536 (Gast)


Lesenswert?

@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

von mar IO (Gast)


Lesenswert?

>
> 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?

von mar IO (Gast)


Lesenswert?

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/

von hacker-tobi (Gast)


Lesenswert?

@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 ;)

von Günter G. (tcg)


Lesenswert?

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 ...

von Günter G. (tcg)


Lesenswert?

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...

von hacker-tobi (Gast)


Lesenswert?

@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 ;)

von Roman65536 (Gast)


Lesenswert?

<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-arducopter-the



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

von Tobias W. (hacker-tobi)


Angehängte Dateien:

Lesenswert?

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.

von Roman65536 (Gast)


Lesenswert?

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

von hacker-tobi (Gast)


Angehängte Dateien:

Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

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

von Tobias W. (hacker-tobi)


Angehängte Dateien:

Lesenswert?

Hi,

anbei die letzte Version. Aber viel ist nicht passiert. Im Wesentlichen 
habe ich alle Compiler-Warnings wegbekommen und ein Makefile erzeugt.

gruß

tobi

von Maarten J. (quirk)


Angehängte Dateien:

Lesenswert?

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
1
t->sp = (uint8_t *)(t->stack_section + STACK_SIZE - 3);
muss es
1
t->sp = (uint8_t *)(t->stack_section + STACK_SIZE - 3 - 32);
heißen...

Gruß
  Maarten

von hacker-tobi (Gast)


Lesenswert?

Hallo Martin,

probiere ich gern aus.

gruß

tobi

von Maarten J. (quirk)


Lesenswert?

ich hab oben im Post vergessen, dass die zu ändernde Code-Zeile in der 
Funktion task_insert ist.

von Tobias W. (hacker-tobi)


Angehängte Dateien:

Lesenswert?

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

von Tobias W. (hacker-tobi)


Lesenswert?

@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.

von hacker-tobi (Gast)


Lesenswert?

Gibts noch weitere Ideen/Anregungen/Kommentare zu dem OS?

Grad was den Bereich Message Queue / Semaphore angeht wäre ich sehr 
interessiert.

von Uwe S. (de0508)


Angehängte Dateien:

Lesenswert?

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 ?
1
#elif defined (__AVR_ATmega88__)
2
#define RAMSTART   0x60
3
#define HEAPSTART  0x02FF
4
#define STACK_SIZE  96
5
#define TIMER_REGISTER  TCCR0B
6
#define TIMER_ENABLE  TIMSK0
7
#define TIMER_VECTOR  TIMER0_OVF_vect
8
#define CLK1    _BV(CS00)
9
#define CLK1024    _BV(CS02) |_BV(CS00)
10
#else

In "nano_os.c" stand noch
1
#define F_CPU 8000000
, das ist zu viel, da im Makefile auch definiert.

Ich erhalte nur eine Warnung:
1
In file included from nano_os.c:27:
2
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.

von Tobias W. (hacker-tobi)


Lesenswert?

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

von Uwe S. (de0508)


Angehängte Dateien:

Lesenswert?

Hallo Tobias,

danke für die Antworten, auf
1
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.

.

von Tobias W. (hacker-tobi)


Lesenswert?

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

von Tobias W. (hacker-tobi)


Lesenswert?

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

von Tobias W. (hacker-tobi)


Angehängte Dateien:

Lesenswert?

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

von mar IO (Gast)


Lesenswert?

Tobias W. schrieb:
> (für die 32 GPIO-Register des AVRs)

Ohne GPIO, sind ja nur Register.

von Tobias W. (hacker-tobi)


Lesenswert?

...der fehlerteufel ...nicht GPIO sondern General Purpose Register GPR 
;( danke!

von Uwe S. (de0508)


Lesenswert?

Hallo Tobias,

ich brauche noch etwas um mich ein zu arbeiten ..
stand by..

von Tobias W. (hacker-tobi)


Lesenswert?

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.

von Tobias W. (hacker-tobi)


Angehängte Dateien:

Lesenswert?

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

von Tobias W. (hacker-tobi)


Angehängte Dateien:

Lesenswert?

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

von Uwe S. (de0508)


Angehängte Dateien:

Lesenswert?

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.

von Tobias W. (hacker-tobi)


Lesenswert?

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.)

von Tobias W. (hacker-tobi)


Angehängte Dateien:

Lesenswert?

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

von Uwe S. (de0508)


Angehängte Dateien:

Lesenswert?

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_Lectures/C++/script/node34.html

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

.

von Tobias W. (hacker-tobi)


Lesenswert?

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 ;)

von Leo (Gast)


Lesenswert?

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?

von Uwe S. (de0508)


Angehängte Dateien:

Lesenswert?

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.

.

von Leo (Gast)


Lesenswert?

Danke Uwe.
Was ist mit SIG_PIN_CHANGE0 und PCINTxyy genau gemeint?

von Uwe S. (de0508)


Lesenswert?

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.

von Leo (Gast)


Lesenswert?

Für das NanoOs brauche ich doch keine Pins vom Atmega. Wenn ja warum 
denn eigentlich?

von Tobias W. (hacker-tobi)


Lesenswert?

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

von Tobias W. (hacker-tobi)


Lesenswert?

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.

von Tobias W. (hacker-tobi)


Lesenswert?

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...)

von Tobias W. (hacker-tobi)


Lesenswert?

Hi,

nano os findet sich ab jetzt unter sourceforge.net:

https://sourceforge.net/projects/nanoos/

gruß

tobi

von Tobias W. (hacker-tobi)


Lesenswert?

schieb

@Leo: schon weiter gekommen?

@Uwe: Was macht dein Projekt?

von Uwe S. (de0508)


Lesenswert?

Hallo Tobias,

viel QRL und ein langes WE mit lernen und Prüfung, also keine Zeit.

von Tobias W. (hacker-tobi)


Lesenswert?

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.

von Tobias W. (hacker-tobi)


Lesenswert?

Schieb

Gibts weitere Anregungen/Ideen/Fragen?

Ich sehe etliche downloads aber kaum noch Aktivität in diesem Thread zur 
Zeit...

von gg (Gast)


Lesenswert?

jaja, geht mir auch so :-)
mein avrwiz hat >300000 hits/jahr aber 0.0 feedback...

von Uwe S. (de0508)


Lesenswert?

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!


.

von Leo (Gast)


Lesenswert?

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 ?

von hacker-tobi (Gast)


Lesenswert?

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

von Leo (Gast)


Lesenswert?

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.

von hacker-tobi (Gast)


Lesenswert?

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

von Leo (Gast)


Lesenswert?

Ich muss sagen, das NanoOs macht einen echt guten Eindruck.
Besser wie z.B. das femtoos.

von hacker-tobi (Gast)


Lesenswert?

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?

von Leo (Gast)


Angehängte Dateien:

Lesenswert?

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.

von hacker-tobi (Gast)


Lesenswert?

Hallo Leo,

danke dir. Ich werd die Änderungen übernehmen, und dann ein neues File 
hochladen.

gruß

tobi

von Tobias W. (hacker-tobi)


Lesenswert?

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)

von Bernd R. (inrfb)


Lesenswert?

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

von Olli K. (Gast)


Lesenswert?

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 !

von hacker-tobi (Gast)


Lesenswert?

ich ebenso.

was genau ist denn das probmem beim avr studio?

gruss tobi

von Bernd R. (inrfb)


Lesenswert?

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.

von hacker-tobi (Gast)


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

@Bernd: funktioniert jetzt alles?

von Bernd (Gast)


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

immer her mit den ideen ;)

von hacker-tobi (Gast)


Lesenswert?

ps. nano os entstand ja mal aus einer diplomarbeit. diese wurde mit 1.3 
benotet :)

damit bin ich jetzt dipl.-inf. ;) !

von Uwe S. (de0508)


Angehängte Dateien:

Lesenswert?

Guten Abend,

ich habe angefangen den Code für den atMega32 an zu passen.

"system/header/nano_os.h"
1
#elif defined (__AVR_ATmega32__)
2
#define RAMSTART   0x60
3
#define HEAPSTART  0x085f
4
#define STACK_SIZE  54
5
// immer Timer0 !
6
#define TIMER_REGISTER  TCCR0
7
#define TIMER_ENABLE  TIMSK
8
#define TIMER_VECTOR  TIMER0_OVF_vect
9
#define CLK1    _BV(CS00)
10
#define CLK1024    _BV(CS02) |_BV(CS00)

Das Makefile reflektiert nun meine Hardware.

Mit einem Dummy
1
user.c
1
void init_user_environment()
2
{
3
asm("nop"); //only placebo
4
}
5
6
void shutdown_user_environment() 
7
{
8
asm("nop"); //only placebo
9
}

Liegt der Speicherbedarf bei
   text     data      bss      dec      hex  filename
   2682        8      249     2939      b7b  nano_os.elf


.

von hacker-tobi (Gast)


Lesenswert?

Danke dir, Uwe.

Hab die Änderungen in nano_os.h übernommen und es auf sourceforge 
hochgeladen.

Damit sind wir jetzt bei Version 003, und supporten folgende Hardware:

Atmega32,
AtMega88,
AtMega168
At90s8535

gruß

tobi

von Uwe S. (de0508)


Lesenswert?

Hallo Tobi,

da ist noch ein Fehler:
1
HEAPSTART  0x085f

Habe ich gegen
1
HEAPSTART  0x085f-0x0100
ersetzt, den 0x085f ist das Ende des SRAM, sorry.

von hacker-tobi (Gast)


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

Habs hochgeladen.

von hacker-tobi (Gast)


Lesenswert?

@Uwe: Hast du meine Änderung bezüglich HEAP_START mal testen können?

von Tobias W. (hacker-tobi)


Lesenswert?

Uwe hat mir per Mail mitgeteilt, dass die Änderungen funktionieren.
Damit läuft Nano OS jetzt auf folgenden yC's:

Atmega32,
AtMega88,
AtMega168
At90s8535

Ich habs auch mal in der Code-Sammlung verlinkt.

gruß

tobi

von hacker-tobi (Gast)


Lesenswert?

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

von Rolf (Gast)


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

Hi Rolf,

ich bin grad auf Arbeit aber werde dir bis zum WE antworten!

gruß

tobi

von Tobias W. (hacker-tobi)


Lesenswert?

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

von Rolf (Gast)


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

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

von Rolf (Gast)


Lesenswert?

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

von Tobias W. (hacker-tobi)


Angehängte Dateien:

Lesenswert?

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

von Rolf (Gast)


Lesenswert?

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

von Tobias W. (hacker-tobi)


Lesenswert?

Kein Thema ;)

Bitte alles testen, ich freu mich über feedback!

gruß

tobi

von tobi (Gast)


Lesenswert?

Hast Du noch Infos zum Footprint?

von Tobias W. (hacker-tobi)


Lesenswert?

Aktuell leider nicht.

Wenn du mir sagst, was du genau brauchst, kann ichs aber ermitteln 
(RAM-Verbrauch?, Flash?, ...).

von Rolf (Gast)


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

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.

von Uwe S. (de0508)


Angehängte Dateien:

Lesenswert?

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

von Uwe S. (de0508)


Lesenswert?

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

von Rolf (Gast)


Lesenswert?

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

von Rolf (Gast)


Lesenswert?

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

von Rolf (Gast)


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

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

von Uwe S. (de0508)


Lesenswert?

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:
1
## Zusatz Flags
2
CFLAGS += -fno-inline-small-functions
3
CFLAGS += -fno-split-wide-types
4
CFLAGS += -fno-tree-scev-cprop
5
CFLAGS += -fno-move-loop-invariants
6
CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections
7
CFLAGS += -Wl,--relax
8
## -- ende --

von Rolf (Gast)


Lesenswert?

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

von Rolf (Gast)


Lesenswert?

Nachtrag:
zum Thema Options bzw. Uwes Flags hab ich hier noch was gefunden...
http://www.tty1.net/blog/2008-04-29-avr-gcc-optimisations_en.html
LG Rolf

von hacker-tobi (Gast)


Lesenswert?

@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

von Rolf (Gast)


Lesenswert?

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

von Rolf (Gast)


Lesenswert?

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&file=printview&t=103231&start=0
Ich glaube nicht, das man das dem OS antuen sollte... Weiteres erst 
gegen Ende der Woche.
LG Rolf

von Tobias W. (hacker-tobi)


Lesenswert?

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... ;)

von Uwe S. (de0508)


Lesenswert?

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"


.

von Rolf (Gast)


Lesenswert?

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:_unbenutzte_Funktionen_entfernen

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

von hacker-tobi (Gast)


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

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

von Rolf (Gast)


Lesenswert?

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/doc2486.pdf / mega8
http://www.atmel.com/dyn/resources/prod_documents/doc2466.pdf / mega16
http://www.atmel.com/dyn/resources/prod_documents/doc2503.pdf / mega32

Hier die Datenblätter.

Als Vergleich der Mega644

http://www.atmel.com/dyn/resources/prod_documents/doc2593.pdf

mit einer etwas anderen Memory Map.

LG Rolf

von hacker-tobi (Gast)


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

@Rolf/Uwe/anybody ;)

Gibts news? Wie weit sind eure Entwicklungen? Wird noch irgend was 
benötigt oder gibts bugs?

von Anonym (Gast)


Lesenswert?

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.

von hacker-tobi (Gast)


Lesenswert?

hi,

gern. habe leider zur zeit keine xmegas.

aber soweit mir bekannt ist, sind die unterschiede ja nicht so gross.

gruss tobi

von Bernhard M. (boregard)


Lesenswert?

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?

von Rolf (Gast)


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

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!

von hacker-tobi (Gast)


Lesenswert?

Ach ja...noch ein update zum Display Treiber für Grafikdisplays. Meine 
Testboards habe ich heute aufgebaut, jetzt kann da die Entwicklung 
losgehen ;)

von Tobias W. (hacker-tobi)


Lesenswert?

Schieb

Wie ist der aktuelle Status?

Bei mir gibts noch nichts neues, melde mich, wenn der Grafiktreiber 
fertig ist.

gruß

tobi

von Achill (Gast)


Angehängte Dateien:

Lesenswert?

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

von Rolf (Gast)


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

Kurzes update: Ehrlich gesagt noch nichts neues. Zur Zeit haben andere 
Dinge priorität. Vergessen ists aber nicht!

gruß

tobi

von hacker-tobi (Gast)


Lesenswert?

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

von hacker-tobi (Gast)


Lesenswert?

Hi,

wir solltes mal wieder aufleben lassen.

gruß

tobi

von Max (Gast)


Lesenswert?

Welchen Vorteil bringt ein solches Multitasking-OS auf so kleinen 
Controllern, welche Art von Anwendungen sollen es sein die ein solches 
voraussetzen? Ist die klassische Programmierung via Interrupts nicht 
viel effektiver? Ein Timer-Interrupt für periodische Aufgaben und 
diverse Geräteschnittstellen-Interrupts sind sehr viel sparsamer und 
auch schneller, ersparen oft genug sogar ein eigenes Hauptprogramm als 
dritter Arbeitsebene. Der große Overhead eines solchen OS, die ständigen 
Datenkopieraktionen zur Registersicherung erzeugen vor allem eines: 
Wärme...

von hacker-tobi (Gast)


Lesenswert?

Hallo Max,

entschuldige die späte Antwort. Ich hab das OS damals geschrieben, um zu 
beweisen, das es geht. Praktische Anwendung hat es bei mir z.B. in Form 
von Multifunktionsuhren gefunden, bei denen mehrere Tasks gleichzeitig 
abgearbeitet werden (z.B. Erfassung der Position, Auslesen von 
Infrarotdaten usw für eine Propelleruhr).

Da das OS auch cooperative Multitasking beherrscht, kann ein Task bei 
Bedarf auch beliebig lang laufen, oder Rechenzeit vorzeitig abgeben, was 
es sehr flexibel macht.

Zusätzlich bestehen Kommunikationsmöglichkeiten, wie z.B. Semaphore. 
Auch komplexere Architekturen, wie z.B. Treiber mit einheitlicher 
Schnittstelle wären denkbar.

gruß

tobi

von hacker-tobi (Gast)


Lesenswert?

Nach langer Zeit geht es weiter.

Zunächst einmal habe ich den Code nur auf die aktuelle AVR-LIBC 
angepasst.

Dafür waren nur wenige Anpassungen notwendig.

Derzeit denke ich über weitere Funktionen nach, z.B. counting Semaphore.

Besteht denn von anderer Seite Interesse oder Badarf?
Falls ja schreibt einfach.

gruß

tobi

von hacker-tobi (Gast)


Lesenswert?

Hi,

ich habe 2 neue Funktionen zur Abfrage des Status und der Priorität 
eines Tasks eingearbeitet.

gruß

tobi

von Matthias K. (bartimaeus)


Lesenswert?

Hey!

Hab jetzt in der Vielzahl der Threads keinen Download oder Link zur 
Veröffentlichung deiner Diplomarbeit gefunden. Gibt es diesen schon, 
hast du deine Diplomarbeit bereits veröffentlichen können?

Würde mich sehr freuen, wenn ich deine Arbeit lesen könnte!
Grüße
M

von Bernd K. (prof7bit)


Lesenswert?

hacker-tobi schrieb:
> Die user - Software ist hiervon
> ausgenommen.

Das geht nicht. Wenn die lib GPL ist dann muss alles was dagegen gelinkt 
wird ebenfalls unter die GPL fallen.

Nimm lieber die LGPL mit zusätzlicher static linking exception Klausel 
(zum Beispiel so wie die Runtime von FreePascal lizenziert ist, denn die 
wird auch statisch gelinkt, aber die damit gelinkten Anwendungsprogramme 
sollen in jedem Falle unberührt von jeglicher Lizenz bleiben.

Lizenzwahl ist nicht ganz ohne und Du solltest das genau bedenken um 
nicht den potentiellen Anwendern unnötige Steine in den Weg zu legen, 
ihnen Rechtsunsicherheiten oder andere Kopfschmerzen zu bereiten.

von hacker-tobi (Gast)


Lesenswert?

Hi zusammen,

das Thema ist 6 Jahre alt.

@Mathias: Ich wüßte nicht mal mehr, ob ich die Arbeit veröffentlichen 
dürfte. Die habe ich vor etwa 5 Jahren abgegeben. Das müßte ich erst bei 
der Hochschule erfragen und der Aufwand erscheint mir etwas zu hoch, 
zumal ich dort keinerlei Kontakte mehr habe.

@Bernd:
"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."
Das bezog sich glaube ich darauf, das er mir nicht mitteilen braucht, 
wenn er die User Software anpasst. Ansonsten hast du aber recht .

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.