Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - FAQ - Zum CC1-Forum - Zum CC-Pro-Forum

Re: Funktions/Thread-Definitionen Kategorie: Programmierung (von AndrĂ© H. - 11.05.2008 21:46)
Als Antwort auf Funktions/Thread-Definitionen von Herbert P. - 27.04.2008 16:43
Ich nutze:
C-Control II Unit, C164CI-ControllerBoard, C-Control II Station, CC2-Application-Board, CC2-StarterBoard, CC2-ReglerBoard, OSOPT V3.1
Hallo Herbert,
> nachdem es keine Vorab-Definitionen von Funktionen oder Threads gibt,
> habe ich Schwierigkeiten, wenn sich zwei Funktionen oder
> Threads gegenseitig aufrufen oder starten/stoppen möchten. Die vordere
> kennt die hintere noch nicht und so verweigert der Compiler.
>
> Gibt es da einen Trick, oder geht das einfach nicht?

Der jetzige C2-Compiler ist leider ein Single-Pass-Compiler. Somit können nur Resourcen
angesprochen werden, die vorher auch bekannt sind.
Ein rekursiver Aufruf von Funktionen ist möglich, solange dies bedeutet, da� sich eine Funktion
ohne eine weitere selbst aufruft.
Allerding muĂ? man bei rekursiven Aufrufen sehr vorsichtig sein, da es hier sehr schnell
zu einem Stack-Overflow kommen kann, wenn man's ĂĽbertreibt. :-)
Ich hatte allerdings erst einen Fall, bei dem man nicht durch geschicktes
Sortieren der Funktionen ans Ziel kam.

Bei Threads gilt prinzipiell dasselbe.
Allerdings gibt es hier eine direkte Möglichkeit auf die Threads einzuwirken, ohne explizit
mit "run", "halt" und "resume" arbeiten zu mĂĽssen.
Ich hatte hier schon vor längerem eine Lösung erstellt, aber bisher nicht in system.c2 eingebaut.
Ich habe es mal aus den Tiefen meiner Festplatten geholt:

//Anzahl der Threads im Projekt abfragen
inline function ThreadCnt() returns int
{
 inline vmcodes.VM_LOAD_CONST_BYTE;
 inline 0;
}

//Thread-Nr. des aufrufenden Threads (0-254)
inline function TID() returns int
{
 inline vmcodes.VM_LOAD_ABSOLUTE_BYTE;
 inline 0xF91A;
}

inline function loadByte(int offset) returns int
{
 inline vmcodes.VM_LOAD_REF_BYTE;
}

inline function storeByte(byte Data, int offset)
{
 inline vmcodes.VM_STORE_REF_BYTE;
}

//Priorität des Threads (0-254) stetzen
function setPrio(int ThreadID, byte Prio)
{
 ThreadID=(20*ThreadID)+16;//Offset fĂĽr Datenzeiger
 storeByte(loadByte(ThreadID),ThreadID+1);// Backup der Thread-Prio (fĂĽr resume)
 storeByte(Prio,ThreadID); //Priorität festlegen.
}

Hiermit lassen sich die Prioritäten der Threads explizit anhand der Thread-Nr.(0-254) ändern.
Die Threadnummer mu� man entweder durch Zählen im Projekt oder durch
die Funktion TID() ermitteln und in einer entsprechenden Globalen Variable speichern.
Dazu mĂĽssen alle Threads aber zumindest einmal laufen.
Wenn diese das aber nicht sollen, kann man folgendes Konstrukt verwenden:
thread xyz
{
 IDThread_xyz=TID();
 halt;
 loop
 {
 //....
 }
}

So kann man alle Threads beim Init kurz starten, um die IDs zu erhalten, ohne den Thread
beim ersten Aufruf wirklich auszufĂĽhren.
Bei einem erneuten "run" bzw. setPrio() macht der Thread ab der Schleife weiter.
Der Vorteil bei setPrio ist auch, da� man einen Thread auch gleich mit einer anderen Priorität
statt der Standard-Prio von 32 starten kann.
setPrio(IDThread_xyz, 45); //Thread xyz mit Prio 45 starten bzw. Prio auf 45 ändern
setPrio(IDThread_xyz, 0); //Thread xyz anhalten


Ich hoffe, das hilft ein wenig fĂĽr die Threads weiter.
Aber meist, wie gesagt, kommt man auch ohne solche Tricks aus.
Und bei Threads immer daran denken: Nur so viele, wie nötig.

MfG André H.



Antworten bitte nur ins Forum!
Fragen per EMail auf Forum-Postings werden nicht beantwortet!

Das macht meine Heizung gerade


    Antwort schreiben


Antworten: