PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Stack bei Interrupt verändern



Hand
11.09.2007, 15:01
Hallo, ich möchte für einen AT90s2313 kleine Multitasking Funktionen erstellen.

Vorgestellte habe ich es mir so das ein Timer läuft und nach Überlauf
im Stack der ProgrammCounter verändert wird so dass ein anderer Task an anderer Programmstelle abgearbeitet wird.

Der zeiger zum Stack steht ja in der Variable SP aber wie verändere ich Daten indirekt im SRAM?

also wenn z.b. in SP der wert 100 steht möchte ich den Stack im SRAM bei adresse 100 lesen/schreiben hab aber keine Ahnung wie das geht in C :-s

In Asm währs kein Thema, bin aber eben gerade auf C umgestiegen

mantis.
11.09.2007, 15:12
hi!

also für mich klingt das nicht unbedingt wie multitasking sondern wie Process scheduling!

und da gibts einige möglichkeiten!
in deinem fall das Zeitscheiben verfahren!

jeder prozess bekommt eine gewisse zeit auf der CPU bzw. im Speicher!
dazu brauchst du aber nicht im Stack herumzurühren!

mfg
MaX

SprinterSB
12.09.2007, 10:02
Den Stack manipulieren muss man IIMHO schon.

Das eigentliche Problem besteht darin, daß gcc in einer ISR schon Register sichert, bevor dein ISR-Code dran kommt. Du darfst also nicht direkt über den SP zugreifen, sondern musst einen unbekannten Offset berücksichtigen, um den Kontext der alten/neuen Task zu sichern/wiederherzustellen.

Prinzipiell gibt's mehrere Ansätze: Schreiben der ISRs in (Inline) Assembler. Bei Inline Assembler muss die Funktion naked sein und man muss sich selber um RETI und verwendete Register und das SREG kümmern.

https://www.roboternetz.de/wissen/index.php/Avr-gcc#ISR_mit_eigenem_Prolog.2FEpilog
Wenn man komplett in C bleiben will, wird's schweirig und man muss zumindest wissen, was gcc mit dem Stapel angestellt hat. An diese Info ranzukommen ist recht tricky und wird leider in avr-gcc nicht korrekt unterstützt (__builtin_return_address(0)). Ein Ansatz wie man an die Info kommen kann findest du in

https://www.roboternetz.de/wissen/index.php/Avr-gcc#__builtin_return_address.280.29
Dieser Workaround ist abhängig von der avr-gcc Version und davon, ob es sich um eine Funktion, eine ISR handelt. Auf jeden Fall ist das generierte asm zu kontrollieren, zB auf korrekte Offsets!

https://www.roboternetz.de/wissen/index.php/Avr-gcc/Interna#Attribute_von_avr-gcc

Hand
12.09.2007, 11:46
Habe ein gutes Beispiel gefunden:

http://codeviewer.org/view/code:e

Bin gerade dabei den Code zu verstehen und zu säubern

Funktioniert mit 50% Speicherverbauch auf meinem 2313 O:)

SprinterSB
12.09.2007, 12:59
Also über diese Brücke würde ich nicht gehen ... oder mich in ein Auto reinsetzen, wenn ich wüsste, daß darin so ein Code zu Ausführung kommt.

Für diese simplen Beispiel (Tasks) mag es hinhauen, aber bei komplexeren Beispielen wird dir alles um die Ohren fliegen!

Hand
12.09.2007, 13:30
Ich brauche 3 Tasks

Task 1 PWM Regelung (evtl über Software)
Task 2 Bedienung + Visualisierung (2 Taster + 2 LED)
Task 3 Kommunikation (LIN-Slave)

Kennst du ein konkretes Beispiel für Scheduling ohne den Stack zu verändern?

SprinterSB
12.09.2007, 21:46
Für ein richtiges Scheduling wirst du an einer Stack-Manipulation nicht vorbei kommen, ebensowenig wie an einer korrekten Sicherung/Restaurierung der Register.

Im Beispielcode werden nicht alle Regs gesichert! Was, wenn ne Task R2 oder R28 verwendet?! Zudem kümmern sich die "Tasks" offenbar selber um das Scheduling :-k

Eine andere Möglichkeit wäre, in einer ISR bestimmte Jobs abzunudeln. Das ist dann aber kein Scheduling und setzt voraus, daß die einzelnen Jobs kooperativ sind; die Jobs sollten linear sein und dürfen keine Endlosschleifen enthalten (im Gegensatz zu einer Task, die ja *immer* in einer Endlosschleif laufen *muss*).