Forum: Mikrocontroller und Digitale Elektronik dspic33ep welche register müssen bei Kontextwechsel gesichert werden


von Thomas S. (daimonion)


Lesenswert?

Hallo Community

Für mein aktuelles Projekt (Motorsteuerung) nutze ich einen dsPIC der 
mittels kooperativen Multitasking Betriebssystem gut unterwegs ist. Nun 
kommt die Anforderung dazu, dass ein zusätzlicher Task laufen soll, der 
aber unterbrechbar sein muss. Innerhalb dieses Tasks soll eine while(1) 
Schleife dafür sorgen dass der Code "permanent laufen" kann.

D.h. ich möchte diesen einen Task in der Idle Zeit des Betriebssystems 
aufrufen indem der Taskkontext (Variablen, Stack + CPU Register) 
wiederhergestellt wird und sobald ein Interrupt kommt, soll der Kontext 
dieses Tasks wieder gesichert werden und alle anderen Tasks sollen 
lauffähig sein können.

Ideen wollte ich mir bei FreeRTOS holen, welches ja komplett präemptiv 
arbeitet, doch das ist durch seine beachtliche Größe gar nicht so leicht 
zu Überblicken. Man kann diesen Eingriff ähnlich sehen, wie einen 
Interrupt in bei diesem Controller. Da wird ja der Kontext "automatisch" 
gesichert.

Daher mal die Frage in die Runde hier, ob schon mal jemand "händisch" 
den Kontext eines Tasks gesichert hat und mir sagen kann welche Register 
gesichert werden müssen und auf was ich noch achten sollte.


Grüße
Daimonion

von c-hater (Gast)


Lesenswert?

Thomas Schm schrieb:

> Für mein aktuelles Projekt (Motorsteuerung) nutze ich einen dsPIC der
> mittels kooperativen Multitasking Betriebssystem gut unterwegs ist. Nun
> kommt die Anforderung dazu, dass ein zusätzlicher Task laufen soll, der
> aber unterbrechbar sein muss. Innerhalb dieses Tasks soll eine while(1)
> Schleife dafür sorgen dass der Code "permanent laufen" kann.

Es gibt aus einem logisch zwingenden Grund bei jedem kooperativen OS 
bereits eine Idle-Schleife. Der Grund ist: Es kann theoretisch und 
praktisch die Situation auftreten, daß alle Tasks mal der Meinung sind, 
genug am ihrem jeweiligen Werk getan zu haben und ein neues Ereignis für 
einen von ihnen auch weit und breit nicht in Sicht ist. In dieser 
Situation muß das OS irgendwas machen und was es macht, ist, sich in 
eben dieser Idle-Schleife zu drehen, bis diese mal wieder von einem 
Interrupt unterbrochen wird.

Du mußt also nur im Code des OS diese Idle-Schleife suchen und 
entsprechend deinen Wünschen ergänzen. Typischerweise gibt es allerdings 
genau für diesen Zweck bereits eine vorbereitete "Schnittstelle" zu 
dieser Schleife, an der man eigenen Code andocken kann. Aber auch die 
mußt du natürlich im Code des OS suchen. Oder auch in der Doku, falls 
eine solche existiert...

> Daher mal die Frage in die Runde hier, ob schon mal jemand "händisch"
> den Kontext eines Tasks gesichert hat

Das kann dir sowieso niemand sagen, solange du nicht gesagt hast, um 
welches kooperative OS es sich denn handeln mag. Außerdem ist die Frage 
am Thema vorbei, denn daß was du willst, ist ja gerade kein kooperativer 
Task, sondern eine Erweiterung der Idle-Schleife. Bei einem kooperativen 
Task sind typischerweise der PC, alle CPU-Register (zumindest alle 
irgendwo im Task benutzten) und der SP zu retten, bei der Idle-Schleife 
hingegen braucht normalerweise garnix gerettet zu werden außer dem 
aktuellen PC und das passiert bei Interruptauslösung von alleine.

Gelegentlich wird allerdings das Andocken an diese Schleife vom OS auch 
als ein Task abstrahiert, der funktioniert wie alle anderen, mit dem 
einzigen Unterschied, daß er yield() nicht aufrufen darf (oder der 
Aufruf der Funktion aus diesem Task abgefangen wird und einfach nichts 
bewirkt). Dann gibt es aber auch für die Funktion zum Start eines Tasks 
einen entsprechenden Parameter, der klarstellt, daß es sich um DEN (es 
kann nur einen geben) Idle-Task handeln soll.

Vielleicht liest du einfach mal selber die verschissene Doku zu diesem 
scheinbar so hochgeheimen OS, dass du uns nichtmal dessen Namen verraten 
kannst, du Depp?

von Thomas S. (daimonion)


Lesenswert?

Naja. Ich ignoriere erst mal den letzten Absatz da du ja doch so 
überzeugend an meiner Frage vorbei geantwortet hast.

Laut Definition ist ein kooperatives Multitaskingsystem ein System wo 
ein Thread/Task oder wie auch immer man es nennen mag die Hoheit 
behalten, wann sie die CPU an das System zurückgeben. Ergo, sie sind 
nicht unterbrechbar.

Mein Betriebssystem ist nicht geheim. Es ist von mir als einfaches 
System selbst programmiert und arbeitet, im Gegensatz zu vielen anderen 
embedded Systemen eben noch nicht mit den da üblichen Methoden die 
Prozesskontexte komplett zu sichern. Es ruft lediglich nach Prioritäten 
die entsprechenden Prozesse/Tasks/Threads auf. Viele größere bzw. 
kommerzielle Systeme sichern natürlich auch bei einem kooperativem 
System schon den Kontext. Hier eben noch nicht.

Da die neue Anforderung, einen unterbrechbaren, also präemptiven Task 
einzubauen lautet, stelle ich mir nun die Frage welcher Kontext alles 
gesichert werden muss, wenn ich den neuen präemptiven Task sichern, bzw. 
wiederherstellen muss.

Grüße

von Andreas H. (ahz)


Lesenswert?

c-hater schrieb:
> Vielleicht liest du einfach mal selber die verschissene Doku zu diesem
> scheinbar so hochgeheimen OS, dass du uns nichtmal dessen Namen verraten
> kannst, du Depp?

Muss sowas sein ?

Die simple FRage "Welches RTOS benutzt Du" hätte es doch auch getan.

/regards
Andreas

von Klaus (Gast)


Lesenswert?

Thomas Schm schrieb:
> Da die neue Anforderung, einen unterbrechbaren, also präemptiven Task
> einzubauen lautet, stelle ich mir nun die Frage welcher Kontext alles
> gesichert werden muss, wenn ich den neuen präemptiven Task sichern, bzw.
> wiederherstellen muss.

Wenn die unterbrechende Task ein Interrupthandler ist, regelt das der 
Compiler von alleine, die unterbrechbare muß nur den Interrupt freigeben

MfG Klaus

von Purzel H. (hacky)


Lesenswert?

Ohne automatismen ... es muessen alle Register und Variablen gesichert 
werden, die sich veraendern, und die wieder gleich sein muessen, wie 
ohne Unterbrechung.

von Thomas S. (daimonion)


Lesenswert?

@Klaus.

Stimmt, der Task wird IMMER von einem Interrupt unterbrochen. D.h. da 
kann ich mich erst mal auf den Interrupthandler verlassen, dass die 
Daten gesichert werden. Also brauche ich mir dann nur den Kontext aus 
der Sicherung wegsichern und wenn der Task später wieder aufgerufen 
wird, schreibe ich den Kontext zurück ins die CPU Register. Dann 
verändere ich noch den PC auf den Scheduler und der sollte nach dem 
Interrupt weiter laufen und der Task ist unterbrochen

Vielleicht ließt ein dsPIC Spezi noch mit.
Reicht die Sicherung der Register W0-W15 + PC oder sind noch andere 
Register notwendig?
Ich schau mir gleich nochmal an was im Interrupt alles gesichert wird.

Dann ist mir beim Lesen des FreeRTOS Handbuches aufgefallen, dass der 
taskspezifische Stack ja auch gesichert werden muss. Aber ich denke, das 
löse ich indem ich dem Task einen dedizierten Stack zuweise, der nur von 
diesem Task genutzt wird. Somit brauche ich diesen nicht "händisch" zu 
sichern.

Grüße
Daimonion

: Bearbeitet durch User
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.