Difference between revisions of "Cron"

From Ethersex_Wiki
Jump to: navigation, search
(Define cronjob in source code: ecmd command)
 
(7 intermediate revisions by the same user not shown)
Line 48: Line 48:
 
== Dynamic Cron Daemon ==
 
== Dynamic Cron Daemon ==
 
=== View jobs via ecmd ===
 
=== View jobs via ecmd ===
Simply execute the ecmd command '''cron list''' i.e. in your browser. All jobs will be displayed, two lines
+
Simply execute the ecmd command '''cron list''' in your browser for instance. 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.),
 
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
 
the second line shows the timing data (MIN HOUR DAY MONTH DAYOFWEEK) and the ecmd command/address of the
Line 74: Line 74:
  
 
=== Write persistent jobs to VFS/EEPROM via ecmd ===
 
=== Write persistent jobs to VFS/EEPROM via ecmd ===
'''cron save''' alle als persistent markierten Jobs werden im VFS/EEPROM abgespeichert.
+
'''cron save''' all persistent jobs will be stored in VFS/EEPROM.
  
 
=== Mark job for UTC time via ecmd ===
 
=== Mark job for UTC time via ecmd ===
Line 85: Line 85:
 
=== Mark job as anacron job via ecmd ===
 
=== Mark job as anacron job via ecmd ===
  
Dieses Flag bietet eine Art anacron-Funktion. Gedacht ist dies für Jobs, die bestimmte Stati setzen.
+
This flag provides a kind of anacron functionality which is intended for jobs that set specific states.
Ein Beispiel wäre die Zirkulationspumpe einer Heizung. Angenommen die Pumpe soll um 6.00 Uhr
+
Take the circulation pump of a central heating as example. If the pump has to be switched on at
eingesaltet und um 9.00 wieder ausgeschaltet werden, könnte das natürlich auch mit normalen Jobs
+
6.00 and switched off at 9.00 this could be realized by a simple cron job. But if the controller
erledigt werden. Sollte der Controller allerdings um 7.00 neu booten (z.B. wg. Stromausfall) bliebe
+
reboots at 7.00 (as the result of a blackout for instance) the pump will not be switched on till 6.00 of the
Pumpe bis zum nächsten Tag 6.00 ausgeschaltet. Ähnliches gilt für grössere Zeitsprünge durch NTP-Updates.
+
following day. The same counts in case of a time skip by NTP updates.
  
Um das Problem zu lösen, werden alle anacron-Jobs nachgezogen, die innerhalb des übersprungenen Zeitraums
+
To solve this problem all anacron jobs that falls in the skiped time range will be executed (in case of
(also vom 1.1.1970 bis zur aktuellen Zeit im Falle das Boots) hätten ausgeführt werden müssen, wobei jeder
+
boot this means from 1.1.1970 till the current time), each job just one time and in correct order (latest
Job nur einmal ausgeführt wird und auch in der korrekten Reihenfolge (jüngstes Ausführungsdatum zählt).
+
execution time counts). To keep the runtime of the decision loop short, the starting point in the past
Damit die Schleife zum Ermitteln der Jobs nicht unnötig lange dauert, ist der Startzeitpunkt in der
+
is limited to <current time> - CRON_ANACRON_MAXAGE secs. Default is one day (86400 secs).
Vergangenheit auf <Aktuelle Zeit> - CRON_ANACRON_MAXAGE Sekunden beschränkt. Voreingestellt ist hier
 
ein Tag (86400 Sekunden).
 
  
 
'''cron anacron N 1''' mark job N as anacron job
 
'''cron anacron N 1''' mark job N as anacron job
Line 105: Line 103:
  
 
=== Define cronjob in source code: callback function ===
 
=== Define cronjob in source code: callback function ===
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.
+
As you may have noticed this functionality is also be covered by the static cron daemon, wich even consumes
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:
+
less resources. But there are some advantages:
  
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)
+
* No need to add code to a foreign module (clarity of cron_static.c suffers with every additional module)
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.
+
* You can remove the cronjob at runtime
* Du kannst Extradaten an die Callback Funktion übergeben
+
* You can pass extra data to the callback funtion
  
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben
+
The function to be called by the daemon has to have the signature '''void func(char* data)''' and should ''not''
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem
+
be defined in cron/cron.c but in the particular module that uses the cron functionality.
jeweiligen Modul, welche die Cron Funktionalität nutzen will.
 
  
# Binde in dein Modul die Datei 'cron/cron.h' ein.
+
# Include 'cron/cron.h' in your module
# 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.
+
# Call the function '''cron_jobinsert_callback''' from your initialization function to insert cronjobs on startup of ethersex.
# Die Funktionsparameter haben die folgende Semantik:
+
# The semantic of the function parameters is:
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc
+
* Minute, -1 as wildcard, -2 means every 2nd minute, etc.
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc
+
* Hour, -1 as wildcard, -2 means every 2nd hour, etc.
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc
+
* Day, -1 as wildcard, -2 means every 2nd day, etc.
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc
+
* Month, -1 as wildcard, -2 means every 2nd month, 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
+
* Day of week, 1 = Sunday, 2 = Monday, 4 = Tuesday, 8 = Wednesday, 16 = Thursday, 32 = Friday, 64 = Saturday or adding of multiple values
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc
+
* Number of repeats, INFINIT_RUNNING for never ending, 1=once, etc.
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)
+
* Position to add to the cron list (CRON_APPEND = add to end)
* Callback Funktion
+
* Callback function
* Größe von Extradaten
+
* Size of extra data
* Extradaten
+
* Pointer to extra data
  
Beispiel aus der Test Einträge Datei:
+
Example taken from the test entry file:
  void test(void* data) { /* tu was */ }
+
  void test(void* data) { /* do something */ }
 
  // in init
 
  // in init
 
  cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);
 
  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.
+
Extra data is cool stuff. Stella PWM for instance uses it to store the chanel no and the
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben
+
target value. If the cronjob is executed, it's extra data is passed to the callback
und diese stehen direkt zur Verfügung.
+
function and can be processed. Please keep in mind that the pointer to extra data
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,
+
has to be the result of a call to malloc, which allocates the memory on the heap.
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.
+
(Example: '''char* extra = malloc(2);''' for 2 bytes on the heap)
(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.
+
Don't care about freeing the allocated memory. The cron daemon will do this job.
Dies erledigt der Cron daemon bereits.
 
  
 
=== Define cronjob in source code: ecmd command ===
 
=== Define cronjob in source code: ecmd command ===
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch
+
The static cron daemon is limited to use callback functions. With the dynamic cron daemon you
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen
+
are even able to call ecmd commands (set output pins, control Stella PWM, reset ethersex, etc.)
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).
 
  
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:
+
Here an example of a function call to insert such a job:
  
 
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");
 
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");

Latest revision as of 09:18, 8 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.

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 in your browser for instance. 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 all persistent jobs will be stored in VFS/EEPROM.

Mark job for UTC time via ecmd

cron utc N 1 mark job N for UTC time

cron utc N 0 remove UTC flag

cron utc N show current state

Mark job as anacron job via ecmd

This flag provides a kind of anacron functionality which is intended for jobs that set specific states. Take the circulation pump of a central heating as example. If the pump has to be switched on at 6.00 and switched off at 9.00 this could be realized by a simple cron job. But if the controller reboots at 7.00 (as the result of a blackout for instance) the pump will not be switched on till 6.00 of the following day. The same counts in case of a time skip by NTP updates.

To solve this problem all anacron jobs that falls in the skiped time range will be executed (in case of boot this means from 1.1.1970 till the current time), each job just one time and in correct order (latest execution time counts). To keep the runtime of the decision loop short, the starting point in the past is limited to <current time> - CRON_ANACRON_MAXAGE secs. Default is one day (86400 secs).

cron anacron N 1 mark job N as anacron job

cron anacron N 0 remove anacron flag

cron anacron N show current state

Define cronjob in source code: callback function

As you may have noticed this functionality is also be covered by the static cron daemon, wich even consumes less resources. But there are some advantages:

  • No need to add code to a foreign module (clarity of cron_static.c suffers with every additional module)
  • You can remove the cronjob at runtime
  • You can pass extra data to the callback funtion

The function to be called by the daemon has to have the signature void func(char* data) and should not be defined in cron/cron.c but in the particular module that uses the cron functionality.

  1. Include 'cron/cron.h' in your module
  2. Call the function cron_jobinsert_callback from your initialization function to insert cronjobs on startup of ethersex.
  3. The semantic of the function parameters is:
  • Minute, -1 as wildcard, -2 means every 2nd minute, etc.
  • Hour, -1 as wildcard, -2 means every 2nd hour, etc.
  • Day, -1 as wildcard, -2 means every 2nd day, etc.
  • Month, -1 as wildcard, -2 means every 2nd month, etc.
  • Day of week, 1 = Sunday, 2 = Monday, 4 = Tuesday, 8 = Wednesday, 16 = Thursday, 32 = Friday, 64 = Saturday or adding of multiple values
  • Number of repeats, INFINIT_RUNNING for never ending, 1=once, etc.
  • Position to add to the cron list (CRON_APPEND = add to end)
  • Callback function
  • Size of extra data
  • Pointer to extra data

Example taken from the test entry file:

void test(void* data) { /* do something */ }
// in init
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);

Extra data is cool stuff. Stella PWM for instance uses it to store the chanel no and the target value. If the cronjob is executed, it's extra data is passed to the callback function and can be processed. Please keep in mind that the pointer to extra data has to be the result of a call to malloc, which allocates the memory on the heap. (Example: char* extra = malloc(2); for 2 bytes on the heap)

Don't care about freeing the allocated memory. The cron daemon will do this job.

Define cronjob in source code: ecmd command

The static cron daemon is limited to use callback functions. With the dynamic cron daemon you are even able to call ecmd commands (set output pins, control Stella PWM, reset ethersex, etc.)

Here an example of a function call to insert such a job:

cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");