Forum: Projekte & Code Wartezeiten effektiv (Scheduler)


von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

Gerade Anfänger haben oft das Problem, das erstmal alles wunderbar
läuft, aber plötzlich muß noch irgendwo gewartet werden.

Und ruchzuck ist die Performance im Eimer, aber der MC soll doch noch
so viele andere Sachen auch erledigen.

Wie macht man das also, Warten ohne Rechenzeitverschwendung ?

Eine mögliche Lösung ist der hier vorgestellte Scheduler.

Das Programm wurde mit WINAVR auf einem ATMega8 compiliert und belegt
etwa 900 Byte.

In dem Zip-File ist die Beschreibung und alle Source-Files.

Viel Spaß damit.


Peter

von Peter D. (peda)


Lesenswert?

Nachtrag:

So ein Scheduler hat natürlich auch seine Einschränkungen.

Im Beispiel wird er alle 65536 Zyklen ausgeführt, d.h. die Main-Loop
sollte in der Regel in dieser Zeit mindestens einmal durchlaufen worden
sein. Dauert sie manchmal länger ist das meist auch kein Beinbruch.
Exakte Zeiten, wie z.B. Uhrzeit+Datum, Frequenzmessung sollte man
deshalb nicht im Scheduler sondern direkt im Timerinterrupt machen.


Wichtig ist also voher eine grobe Abschätzung der maximalen und
minimalen Zeitintervalle zu machen.
Im Beispiel ist die minimale Zeit: 1 / (11,0592MHz  256  256) =
5,9ms.
Das ist relativ schnell (das Beispiel hat ja fast nichts zu tun),
meistens sollten aber Zeiten von 100ms...500ms ausreichend sein.

Die maximale Zeit ergibt sich daraus, daß der Delayzähler 16-Bittig
ist, zu 65536 * 5,9ms = 6,4min.

Im main.h kann der Delayzähler als 8-, 16- oder 32-Bittig festgelegt
werden. Das hat dann Einfluß auf die Codegröße sowie die Größe der
Liste im RAM.

Für ein ordnungsgemäßes Funktionieren des Schedulers ist zu beachten,
daß man auch versteckte Wartezeiten vermeiden sollte.
Z.B. ist zu empfehlen, für die UART Sende- und Empfangspuffer
anzulegen, die dann im UART-Interrupt gefüllt bzw. geleert werden.

Das hängt aber immer auch von der konkreten Anwendung ab. Z.B. je 10
Bytes bei 115200Baud im Pollingmode zu senden, dürfte kaum einen
kritischen Zeitverbrauch bewirken.


Ein Scheduler ist also auch kein Zaubermittel, aber für komplexe
Zeitsteuerungen (z.B. Lichteffekte) fast unschlagbar einfach.


Peter

von AxelR. (Gast)


Lesenswert?

Hallo Peter,

muss man erst hingelinkt werden...
http://www.mikrocontroller.net/forum/read-1-155162.html#155495
Klasse Idee, hatte ich schon mal aufm AVR Seminar was von gehört.
Sehe ich mir gerne mal an.

Danke
(876ter DL)
AxelR.

von Tina Kohler (Gast)


Lesenswert?

Hallo Peter,

da ich auf der Suche nach einer Guten Entprell variante in C Suche bin
ich auf diese Seite gestossen!

Leider bin ich noch anfänger um komme mit dem Code überhaupt nicht
zurecht er ist halt einfach zu komplex!

Im Prinzip möchte ich nur einen Port als Eingschalten bzw. Port B und
dann mit den Einzelnen Pins bei Betätigung einen Funktion aufrufen oder
variablen um 1 erhöhen, leider geliegt es mir nicht den Code so aus
einander zu nehmen das ich ihn benutzen kann! Ich wäre dir echt dankbar
wenn du gerade für anfänger dieses Thema nochmal bearbeiten könntest da
das entprellen ja fast das wichtigste ist was man am anfang benötigt!

Vielen Dank Tina

von Peter D. (peda)


Lesenswert?

@Tina

die Schedulerfunktion laß einfach links liegen.


if( get_key_press( 1<<LED0 ) )

testet ein Bit (gedrückte Taste) und löscht es.


Zur Funktion der Tastenerkennung und Entprellung steht hier was:

http://www.mikrocontroller.net/forum/read-4-20549.html#new


Peter

von Hartmut Semken (Gast)


Lesenswert?

Hallo,

vielen Dank für ds wirklich schöne Codestück - schon die
Entprellroutine ist toll, die Timer sind ebenfalls sehr nützlich.

Dennoch ein Verbesserungsvorschlag: der Code initialisiert den PortC
nicht, schaltet also auch die Pullups nicht ein.
Out-of-the-zip hat das bei mir sehr schöne Random-Muster zur Folge
gehabt - gegen völlig wild schwingende Eingänge hilft eben auch 4-fach
Abtastung noch nicht.

Aber kaum macht man es richtig, da funktioniert es auch.

hase

von 900ss (900ss)


Lesenswert?

Moin Peter,
nachdem ich den Scheduler (also die Timer) auch schon erfolgreich 
eingesetzt habe, wollte ich auch mal Danke sagen. Die Idee ist nicht 
neu, aber funktionierend und effektiv fertig vorzufinden ist natürlich 
schön :-)

Vielen Dank Peter.

900ss

von Bene J. (terfagter)


Lesenswert?

Hallo Peter,

ich versuche gerade deinen Scheduler auf einem Atmega16 zum laufen zu 
kriegen (16Mhz). Aber es tut sich irgendwie nichts. Als Beispiel sollen 
drei LEDs eingeschaltet werden. Wenn ich test() ausführe passiert dies 
auch. Mit timmeradd passiert aber nichts.
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <avr/interrupt.h>
4
#include <avr/pgmspace.h>
5
#include "MAIN.h"
6
  
7
int main (void) 
8
{
9
  //Für Scheduler
10
  TCCR0 = 1<<CS02;                    //divide by 256 * 256; Timereinstellungen für Scheduler
11
  TIMSK = 1<<TOIE0;                    //enable timer interrupt
12
13
  timerinit();                      //Initialisierung Timertick für Scheduler
14
  
15
  sei();                          
16
17
  timeradd( test, SECONDS( 1 ) );        
18
  
19
  for(;;)                          // main loop
20
  {                            
21
    if( f_timer_tick )
22
    {
23
      f_timer_tick = 0;
24
      timertick();
25
    }
26
  }
27
}
28
29
void test(void)
30
{
31
  DDRC = 0b00000111;
32
  PORTC = 0b00000000;
33
}

Die SCHEDULE.c habe ich nicht verändert und die MAIN.c sieht so aus:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
//#include <signal.h>
4
5
#define XTAL 16e6
6
7
#define TIMERTICK  (XTAL / 256 / 256)  // timer ticks per second
8
9
#define SECONDS(x)  ((uint)(TIMERTICK * x + 0.5))
10
11
#define uchar unsigned char
12
#define uint unsigned int
13
#define bit uchar
14
#define idata
15
#define code
16
17
typedef void (code *funcp)(void);
18
19
//#define t_res    uchar    // define time resolution  8 bit
20
#define t_res    uint    // define time resolution 16 bit
21
22
23
extern uchar key_state;    // debounced and inverted key state:
24
        // bit = 1: key pressed
25
extern uchar key_press;    // key press detect or repeat
26
27
extern uchar f_timer_tick;  // timer flag
28
29
30
extern uchar get_key_press( uchar key_mask );
31
32
void timertick(void);
33
34
bit timeradd( funcp func, t_res delay );
35
36
bit timerremove( funcp func );
37
38
void timerinit(void);
39
40
extern void test(void);

Woran könnte das liegen? Schonmal danke für deine Hilfe!

von 900ss (900ss)


Lesenswert?

Hmmm.... mal sehen.... polier die Glaskugel ;-)

Da du den Code nicht vollständig gepostet hast, kann man nur raten.

Die ISR fehlt zum Beispiel.

Aber hier:
extern uchar f_timer_tick;  // timer flag

Hier fehlt das volatile. Die Variable sollte natürlich auch als volatile 
definiert sein. Das könnte der Fehler sein.

Hast du geprüft, ob deine ISR überhaupt anläuft?
Wird der Zweig in

if( f_timer_tick ) {...}

aufgerufen? Kannst du doch einfach prüfen (Leds einschalten).

von Bene J. (terfagter)


Lesenswert?

Doch ich habe meinen ganzen Code gepostet. Meine main.c und meine 
main.h. der Rest ist der scheduler von Peter Dannegger. Da habe ich ja 
nichts verändert.

von 900ss (900ss)


Lesenswert?

Bene Jan schrieb:
> Doch ich habe meinen ganzen Code gepostet.

Stimmt, hab mal nachgesehen in dem Code von Peter. Vorher
fehlte mir dir ISR. Die ist dann im Modul TOV0.C

1) Setze mal volatile für die oben angegebene Variable.
2) Prüfe, ob die ISR anläuft.
3) Prüfe ob if( f_timer_tick ) {...} durchlaufen wird.

von dunno.. (Gast)


Lesenswert?

Bene Jan schrieb:
> void test(void)
> {
>   DDRC = 0b00000111;
>   PORTC = 0b00000000;
> }

ääähm... wierum genau hast du denn deine leds angeschlossen..?

könnte dein problem vielleicht einfach nur sein, das du portC auf 0x00 
stehen lässt...?

von 900ss (900ss)


Lesenswert?

dunno.. schrieb:
> könnte dein problem vielleicht einfach nur sein

Bene Jan schrieb:
> Als Beispiel sollen
> drei LEDs eingeschaltet werden. Wenn ich test() ausführe passiert dies
> auch

@dunno: alles klar?

@Bene Jan: Wenn es funktioniert dann schreib es.

von Uwe (de0508)


Lesenswert?

Hallo,

ich verwende schon lange den Taskscheduler von PEDA und habe hier eine 
Beispiel mit kompletten Code veröffentlicht.

Beitrag "Re: 3fach Timer (einschaltverzögerung)"

Damit solltest Du zum Erfolg kommen !

Es gibt auch von mir einige Anpassungen, aber damit komme ich immer 
sicher ans Ziel bei meiner Projekte.
1
utimer_t delta;
 kann 16-Bit oder 32-Bit je nach Problem haben und mit der Nutzung i.a. 
von GPIOR0 - GPIOR2; siehe |main.h|:
1
#ifdef GPIOR0
2
# define f_timer_tick  SBIT(GPIOR0,0)
3
#endif
wird der Code kleiner und schneller.

.

von Bene J. (terfagter)


Lesenswert?

Also mit oder ohne volatile ändert sich leider nichts.

Habe mal versucht in der if( f_timer_tick ) die LEDs einzuschalten. 
Funktioniert nicht! Also wird f_timer_tick nicht 1. Was wiederrum heißt, 
dass die ISR in TOV0.c nicht ausgeführt wird. Ich weiß aber noch nicht 
warum?!?

von 900ss (900ss)


Lesenswert?

Bene Jan schrieb:
> Also mit oder ohne volatile ändert sich leider nichts.

Du mußt das volatile in zwei Modulen einsetzen, in dem ISR-Modul und in 
main.h, überall wo eine Deklaration oder Definition von f_timer_tick 
steht.

Um zu prüfen, ob die ISR durchlaufen wird, brauchst du doch nur dort 
(also in der ISR die LEDs einschalten.

Ansonsten die Timerinitialisierung prüfen.

SIGNAL(...) für die Interrupttoutine ist alt. Evtl. liegt es daran, was 
ich aber nicht glaube. Siehe avrlibc-Doku.

von Bene J. (terfagter)


Lesenswert?

Ich hab jetzt nochmal volatile benutzt und auf einmal geht es!
Ich bin mir 100%-sicher das ich es eben genauso gemacht habe und da hat 
es nicht funktioniert...

von 900ss (900ss)


Lesenswert?

Bene Jan schrieb:
> Ich hab jetzt nochmal volatile benutzt und auf einmal geht es!

Das ist doch schön :-)

> Ich bin mir 100%-sicher das ich es eben genauso gemacht habe und da hat
> es nicht funktioniert...

Daran hab ich meine Zweifel und die darfst du auch haben ;-)

von Bene J. (terfagter)


Lesenswert?

Hallo zusammen,

ich benutze den Scheduler in verschiedenen Projekten und dieser 
funktioniert auch super. Jetzt würde ich gerne auch die Entprellfunktion 
nutzen, diese funktioniert aber leider noch nicht bei mir:

Eingelesen werden sollen PE4 und PE5. Dort sind zwei Kurzhubtaster gegen 
GND angeschlossen. Für dieses Beispiel werte ich aber nur PE5 aus!
In meinem Beispiel soll ein kleiner Text über die UART ausgegeben 
werden. Ausgaben über die UART funktionieren einwandfrei, daran kann es 
also nicht liegen.
Wenn ich den Controller starte wird 1x der Text ausgegeben, ohne das ich 
den Taster drücke. Das kann ja auch schon nicht normal sein?!
Wo liegt mein Fehler?
Vielen Dank für eure Hilfe.
Hier mein Code:
getkey.c
1
#include "../main.h"
2
3
uchar get_key_press( uchar key_mask )
4
{
5
  cli();
6
  key_mask &= key_press;      // read key(s)
7
  key_press ^= key_mask;      // clear key(s)
8
  sei();
9
  return key_mask;
10
}
tov0.c
1
#include "../main.h"
2
3
uchar f_timer_tick;
4
5
uchar key_state;      // debounced and inverted key state:
6
              // bit = 1: key pressed
7
uchar key_press;      // key press detect or repeat
8
9
SIGNAL (SIG_OVERFLOW0)
10
{
11
  static char ct0, ct1;
12
  char i;
13
14
  i = KEY_INPUT & (1<<KEY4^1<<KEY5);
15
  i ^= ~key_state;          // key changed ?
16
17
  ct0 = ~( ct0 & i );      // reset or count ct0
18
  ct1 = ct0 ^ (ct1 & i);      // reset or count ct1
19
  i &= ct0 & ct1;      // count until roll over ?
20
  key_state ^= i;      // then toggle debounced state
21
  key_press |= key_state & i;    // 0->1: key press detect
22
23
  f_timer_tick = 1;
24
}
Veränderungen in der main.h:
1
#define KEY_INPUT  PINE
2
#define KEY4  4
3
#define KEY5  5
main.c
1
  TCCR0B = 1<<CS02;                    //divide by 256 * 256; Timereinstellungen für Scheduler
2
  TIMSK0 = 1<<TOIE0;                    //enable timer interrupt
3
  key_state = 0;
4
  key_press = 0;
5
6
  while(1)
7
  {
8
    if( f_timer_tick )
9
    {
10
      f_timer_tick = 0;
11
      timertick();
12
    }
13
    if( get_key_press( 1<<KEY5 ) )
14
    {  
15
      //0xFF ^= 1<<PG0;                // toggle LED2 on key press
16
      uputs0("Taste gedrueckt!");
17
    }
18
    
19
  }

von Peter D. (peda)


Lesenswert?

Hast Du externe Pullups oder schaltest Du sie ein?


Bene Jan schrieb:
> Hier mein Code:

Das ist kein Code, sondern Bröckchen, wie man sie einem Hund hinwirft.
Was soll damit jemand anfangen?
Er müßte ein neues Projekt machen und die Änderungen mühsam eintragen.
Und dabei können Fehler passieren.

Hänge das komplette compilierfähige Programm (als Zip) an. Es darf keine 
Warnungen und Fehlermeldungen geben.

Willst Du Änderungen markieren, kommentiere die Originalzeile aus und 
schreibe die neue darunter.
Oder nimm #ifdef, #else, #endif zum Unterscheiden.


Peter

von Markus B. (markus_b77)


Lesenswert?

@Peter: dein Text im ersten Post klingt wie ein Werbetext ;)

Hab den Beitrag erst jetzt entdeckt. Werde ich mir mal anschauen.

von Florian G. (stromflo)


Lesenswert?

Hallo Peter,

habe den Scheduler auch für den XMEGA umgeschrieben.
Leider habe ich in deinem Code keine Hinweise zu einer bestimmten Lizenz 
gefunden. Unter welcher Lizenz steht der Code? Soll der Autor angegeben 
werden?

Gruß Flo

von Peter D. (peda)


Lesenswert?

Florian G. schrieb:
> Soll der Autor angegeben
> werden?

Das ist o.k.

von GTM (Gast)


Lesenswert?

Hallo zusammen,

hattet ihr das auch mal, dass in timeradd 'funcp func' außer für -O0 
komplett wegoptimiert worden ist, und damit das Ganze bei aktivierten 
Optimierungen kaputt gegangen ist (während es ohne Optimierungen so 
funktioniert hat wie erwartet)?

Nachdem ich alles probiert habe, was ich kannte, um das Problem zu 
beseitigen, und es mir nicht gelang, hab ich mich letztlich von der Idee 
inspirieren lassen und das Ganze komplett neu geschrieben - allerdings 
mit Pointerarithmetik. Jetzt läufts auch optimiert und braucht sogar ein 
bisschen weniger Speicher im Flash.

Danke für die Vorlage! :)

Tom

von Peter D. (peda)


Lesenswert?

@GTM (Gast)

Welchen Compiler und welche Optionen benutzt Du?
Ich benutze WINAVR und -Os.
Hast Du mal ein Beispiel als Anhang.

von Tim H. (rettungstim)


Angehängte Dateien:

Lesenswert?

Servus zusammen,

Ich versucht die original Dateien von Peter zum laufen zu bringen.

Ich habe den Code nur an folgenden Punkten angepasst.
In TOV0.c

SIGNAL (SIG_OVERFLOW0)

wurde geändert in:
SIGNAL (TIMER0_OVF_vect)

und signal.h habe ich rausgeschmissen.

Benutze dazu Atmel Studio 6 (Version 6.1.2730- SP2).

Leider bekomme ich nun eine Warnung die ich nicht ganz verstehe.

Warning  1  suggest parentheses around arithmetic in operand of '^' 
[-Wparentheses]

Kann mir einer sagen was da falsch läuft?

Viele Grüße
Tim

von 900ss (900ss)


Lesenswert?

Die Warnung sagt doch exakt, was dort moniert wird. Der Compiler spricht 
eine Empfehlung aus. Versuche die Warnung zu übersetzen, dann wirst du 
es auch wissen.

von Tim H. (rettungstim)


Lesenswert?

Ähm ja,

auf die Idee es mal zu übersetzen hätte ich auch kommen können. Sorry!

Aber vielen Dank für die schnelle Antwort.

Jetzt hangle ich mich mal an dem Code entlang um diesen genau zu 
verstehen. Ich hoffe das nicht noch mehr so dumme Fragen von mir kommen 
:-(

Viele Grüße
Tim

von Tim H. (rettungstim)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich stelle mich mal wieder zu Blöd an. Ich bekomme den Code nicht ans 
laufen.

Ich habe zwei Taster an PC2 und PC3 und zwei LEDs an PC4 und PC5.

Ich bekomme den Code nicht so abgeändert das dieser läuft.
Ich habe auch noch nicht kapiert welchen Taster er in dem Code benutzt, 
vielleicht kann mir das einer erklären. Ich würde den Code so gerne 
verstehen...

Ich habe mir einen Mega8 mit 16Mhz.

Viele Grüße
Tim

: Bearbeitet durch User
von Tim H. (rettungstim)


Lesenswert?

Hallo zusammen,

mein Code läuft nun. Der Code von Peter (UART mit FIFO) läuft auch.

Peter schreibt aber so Knackig das ich Schwierigkeiten habe alles zu 
versehen.

Hat jemand von euch den Scheduler und UART Code verheiratet und kann mir 
mal ein Codebeispiel schicken bzw. hier ablegen.

Das würde mir vielleicht auch helfen, beide Codes ein wenig mehr zu 
verstehen.

Vielen Dank und Grüße
Tim

von Uwe (de0508)


Lesenswert?

Tim,

sag mal was soll man da verheiraten ?

Das sind zwei C Module ohne gemeinsame Schnittstellen.

Sind vielleicht die C Grundlagen, bzw. das C Projektmanagement das 
Problem ?

von Tim H. (rettungstim)


Lesenswert?

Da ich mir C mehr oder weniger selber beigebracht habe, fehlt es hier 
und da auch an den Grundlagen.

Ich möchte gerne mehrere Prozesse gleichzeitig laufen lassen.

Sprich ich möchte ein Rollo von der Taste aus fahren lassen bzw. diese 
Rollo über eine RS232 Schnittstelle Steuern können.

Deshalb muss ich in den Scheduler auch die UART einbinden.
Es ist ja Theoretisch möglich das während eines Schaltbefehl (Empfang am 
Rollo)  einer die Taste für Rollo hoch oder runter drückt.

Ich versuche bestehenden Code zu verstehen um in meinem Code weiter zu 
kommen.

Viele Grüße
Tim

von Tim H. (rettungstim)


Lesenswert?

Wie ich oben schon schrieb habe ich den Code nicht  ganz verstanden.

Kann mir einer sagen wie ich die Zeitschleife abbreche?

Also durch Drücken der zweiten Taste.  LED ausmachen ist kein Problem 
aber wie "lösche" ich die Zeit? Die Zeit läuft im Hintergrund natürlich 
weiter.

Danke uns schönes WE
Tim

von Peter D. (peda)


Lesenswert?

Tim H. schrieb:
> Kann mir einer sagen wie ich die Zeitschleife abbreche?

bit timerremove( funcp func );

von Peter D. (peda)


Lesenswert?

Tim H. schrieb:
> Deshalb muss ich in den Scheduler auch die UART einbinden.

In den Scheduler eher nicht, sondern in die Mainloop:
1
  for(;;){
2
    if( taste_gedrueckt )
3
      mache_was();
4
    if( byte_empfangen )
5
      mache_auch_was();
6
  }

Sind mehrere Byte für ein Kommando nötig, ist das kein Beinbruch.
Die Behandlungsroutine sammelt dann eben die Bytes in einen Puffer, bis 
sie das Paketende erkennt und parst es dann.

von Tim H. (rettungstim)


Lesenswert?

Peter Dannegger schrieb:
> Tim H. schrieb:
>> Kann mir einer sagen wie ich die Zeitschleife abbreche?
>
> bit timerremove( funcp func );

Danke Peter, hätte ich selber sehen können. Das ist ein super Sache, 
vielen dank fürs einstellen des Codes. Hoffentlich verstehe ich ihn auch 
irgendwann zu mehr als 50%...

Peter Dannegger schrieb:
> Tim H. schrieb:
> Sind mehrere Byte für ein Kommando nötig, ist das kein Beinbruch.
> Die Behandlungsroutine sammelt dann eben die Bytes in einen Puffer, bis
> sie das Paketende erkennt und parst es dann.

Das mit empfangen von 1 Byte habe ich hinbekommen. Also mit Auswertung 
in einer IF-Abfrage. Aber wie mache ich das mit mehreren Bytes, ich habe 
das in deinem Beispiel nicht verstanden wie du den Puffer verwendest. Da 
ich ja zum Beispiel den String "Test1" auswerten will. Wenn aber "Test2" 
kommt soll er natürlich nix tun, bis der "Test1" sieht.

Entschuldigt bitte die blöden Fragen, aber ich möchte den Code 
wenigstens ein bisschen verstehen, da ich ihn in meinem Haus noch ein 
paar mal einsetzen will.

Viele Grüße
Tim

von Peter D. (peda)


Lesenswert?

Pseudo-Code:
1
void rec_cmd()
2
{
3
  static char buff[20];
4
  static uint8_t idx = 0;
5
6
  if( byte_avail() == 0 )
7
    return;
8
  buff[idx] = get_byte();
9
  if( idx < sizeof(buff)-1 )
10
    idx++;
11
  if( cmd_end( buff ) == 0 )
12
    return;
13
  parse_cmd( buff ); // Kommando erkennen und was machen
14
  idx = 0;
15
}

Das Parsen kann man z.B. mit sscanf machen, ist zwar nicht sonderlich 
effizient.

: Bearbeitet durch User
von Martin J. (bluematrix) Benutzerseite


Lesenswert?

Hallo,
muss ich bei einem ausgeführten Task jedesmal den Task mit "timerremove" 
entfernen?
1
main()
2
{
3
   timeradd( task_gui, SECONDS( 0.5 ) );
4
}
5
6
7
void task_gui(void)
8
{
9
  gui_update(&gui);
10
  timerremove( task_gui );
11
  timeradd( task_gui, SECONDS( 0.5 ) );
12
}

von Karl M. (Gast)


Lesenswert?

Ja, wenn er wieder "eingestellt" werden soll.
Sonst läuft er einmalig und wird dann aus dem Scheduler ausgetragen.

von Martin J. (bluematrix) Benutzerseite


Lesenswert?

warum muss ich den extra austragen?
Sollte das nicht auch bei sich wiederholenden tasks, wie dem update_gui 
selber geschehen?

von Karl M. (Gast)


Lesenswert?

Ups Martin,

mein Fehler, ich habe das übersehen.

Der Task muss sich nicht selbst austragen, wenn er aufgerufen wird, 
wurde er vorher ausgetragen.

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.