Difference between revisions of "Cron"
(→Add jobs via ecmd) |
(→Mark job as persistent via ecmd) |
||
Line 67: | Line 67: | ||
=== Mark job as persistent via ecmd === | === Mark job as persistent via ecmd === | ||
− | '''cron persistent N 1''' | + | '''cron persistent N 1''' mark job N as persistent |
− | '''cron persistent N 0''' | + | '''cron persistent N 0''' remove persistent flag |
− | '''cron persistent N''' | + | '''cron persistent N''' show current state |
=== Write persistent jobs to VFS/EEPROM via ecmd === | === Write persistent jobs to VFS/EEPROM via ecmd === |
Revision as of 13:09, 6 April 2012
Cron daemon | |
---|---|
Status | Stable
|
menuconfig | Applications->Cron daemon |
Pinning | no |
Ecmd | yes |
Depends on | ECMD, Clock |
Code | https://github.com/ethersex/ethersex/tree/master/services/cron |
Cron daemon manage cron jobs. This rules define repeated or unique events that call certain commands.
Cron jobs are implemented in two flavors: a static list that is defined at compile time and not changeable at runtime, and a dynamic approach, which loads the joblist to the RAM at statup. Jobs can be added and removed at runtime.
Contents
- 1 Preconditions
- 2 Menuconfig
- 3 Static Cron Daemon
- 4 Dynamic Cron Daemon
- 4.1 View jobs via ecmd
- 4.2 Remove jobs via ecmd
- 4.3 Add jobs via ecmd
- 4.4 Mark job as persistent via ecmd
- 4.5 Write persistent jobs to VFS/EEPROM via ecmd
- 4.6 Mark job for UTC time via ecmd
- 4.7 Mark job as anacron job via ecmd
- 4.8 Define cronjob in source code: callback function
- 4.9 Define cronjob in source code: ecmd command
Preconditions
Both approaches have in common that you need to define a function that is called from the con daemon at a appropriate time. The function signature, however, varies dependend on the choosen implementation.
Menuconfig
The module needs the current time to function properly. So you have to select at least one time source. To enable crontabs in ethersex select
│ │ Load a Default Configuration ---> │ │ ... │ │ Applications ---> │ │ ... │ │ [*] Cron daemon ---> │ │ [ ] Cron daemon (static jobs)
Static Cron Daemon
The function to be called from the daemon has to have the signature void func(void) and has to be defined in cron_static/cron_static.c.
Furthermore you have to insert a rule of the type cron_static_event_t to the structure array events. The meaning of the values are minute, hour, day, month, days of week, callback function and a flag if UTC or local time is used (in that order).
A value of -1 is a wildcard. The entries are checked every minute, so an entry with all wildcards will be executed every minute.
Values less than -1 mean "every x-th minute/hour/etc.". So in case of -4 in the minute field the job will be executed every 4th minute.
Dynamic Cron Daemon
View jobs via ecmd
Simply execute the ecmd command cron list i.e. in your browser. All jobs will be displayed, two lines for each job. The first line contains the job attributes (position, repeats, ecmd/callback job, use UTC, etc.), the second line shows the timing data (MIN HOUR DAY MONTH DAYOFWEEK) and the ecmd command/address of the callback function to be executed.
Remove jobs via ecmd
cron rm N removes the Nth job (start counting at 0) from the cron list. Caution! cron rm without paramater removes ALL jobs without confirmation request!
Add jobs via ecmd
cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD
MIN HOUR DAY MONTH and DAYOFWEEK can be -1 (as wildcard).
ECMD: The ecmd command to be executed.
After creating the new job it's position in the list will be displayed.
Mark job as persistent via ecmd
cron persistent N 1 mark job N as persistent
cron persistent N 0 remove persistent flag
cron persistent N show current state
Write persistent jobs to VFS/EEPROM via ecmd
cron save alle als persistent markierten Jobs werden im VFS/EEPROM abgespeichert.
Mark job for UTC time via ecmd
cron utc N 1 setzt den Nten Job auf UTC
cron utc N 0 löscht das UTC flag
cron utc N zeigt den aktuellen Status an
Mark job as anacron job via ecmd
Dieses Flag bietet eine Art anacron-Funktion. Gedacht ist dies für Jobs, die bestimmte Stati setzen. Ein Beispiel wäre die Zirkulationspumpe einer Heizung. Angenommen die Pumpe soll um 6.00 Uhr eingesaltet und um 9.00 wieder ausgeschaltet werden, könnte das natürlich auch mit normalen Jobs erledigt werden. Sollte der Controller allerdings um 7.00 neu booten (z.B. wg. Stromausfall) bliebe Pumpe bis zum nächsten Tag 6.00 ausgeschaltet. Ähnliches gilt für grössere Zeitsprünge durch NTP-Updates.
Um das Problem zu lösen, werden alle anacron-Jobs nachgezogen, die innerhalb des übersprungenen Zeitraums (also vom 1.1.1970 bis zur aktuellen Zeit im Falle das Boots) hätten ausgeführt werden müssen, wobei jeder Job nur einmal ausgeführt wird und auch in der korrekten Reihenfolge (jüngstes Ausführungsdatum zählt). Damit die Schleife zum Ermitteln der Jobs nicht unnötig lange dauert, ist der Startzeitpunkt in der Vergangenheit auf <Aktuelle Zeit> - CRON_ANACRON_MAXAGE Sekunden beschränkt. Voreingestellt ist hier ein Tag (86400 Sekunden).
cron anacron N 1 markiere den Nten Job als anacron Job
cron anacron N 0 löscht das UTC flag
cron anacron N zeigt den aktuellen Status an
Define cronjob in source code: callback function
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird. Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:
- Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)
- Du kannst zur Laufzeit den cronjob auch wieder entfernen.
- Du kannst Extradaten an die Callback Funktion übergeben
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben void func(char* data) und sollte nicht in der cron/cron.c Datei definiert werden, sondern in dem jeweiligen Modul, welche die Cron Funktionalität nutzen will.
- Binde in dein Modul die Datei 'cron/cron.h' ein.
- Nutze die Callback Variante des Cron-Einfügen Befehls cron_jobinsert_callback in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.
- Die Funktionsparameter haben die folgende Semantik:
- Minute, -1 für ignorieren, -2 für jede 2te Minute etc
- Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc
- Tag, -1 für ignorieren, -2 für jeden 2te Tag etc
- Monat, -1 für ignorieren, -2 für jeden 2te Monat etc
- Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus
- Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc
- Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)
- Callback Funktion
- Größe von Extradaten
- Extradaten
Beispiel aus der Test Einträge Datei:
void test(void* data) { /* tu was */ } // in init cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert. Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben und diese stehen direkt zur Verfügung. Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss, sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden. (Beispiel: char* extra = malloc(2); für 2 Bytes auf dem Heap)
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern. Dies erledigt der Cron daemon bereits.
Define cronjob in source code: ecmd command
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen (z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");