SYSTEM.C2 V1.4 - Hilfe


Beschreibung

Einfügen als System-Modul

Funktionen:

timer()
settime()
hour()
minute()
second()
gettime()

dcferr()
setdate()
year()
month()
day()
dow()

dst()
setDST()
call()
jump()

hook()
unhook()

setEXICON()
getEXICON()
threadStepReset()
getOSInfo()
getOSVersion()
getOSRelease()


Beschreibung   Nach oben

Das Modul system.c2 ermöglicht Systemzugriffe auf Timer-und Uhrenfunktionen,
Aufrufe für Systemroutinen, Interruptkonfiguration für Systemroutinen und
Abfrage von OS-Informationen.

Einfügen als System-Modul   Nach oben

Die Datei system.c2 in das Verzeichnis .\CControl2\Lib kopieren.


Funktionen:


System-Timer abfragen   Nach oben

    inline function timer() returns long

Diese Funktion gibt den aktuellen Wert des ms-Systemtimers zurück.
Der Wertebereich ist vom Typ Long.

Uhrzeit setzen   Nach oben

    inline function settime(int hour, int minute, int second)

Mit dieser Funktion wird die Uhrzeit der CC2-interne Echtzeituhr gestellt.

hour Stunde (0-23)
minute Minute (0-59)
second Sekunde (0-59)


Uhrzeit abfragen   Nach oben

    inline function hour() returns
    inline function minute() returns
    inline function second() returns
    function gettime(TIME time) returns

Mit diesen Funktionen können die aktuellen Zeitwerte der CC2-Echtzeituhr
gelesen werden. Mit hour(), minute() und second() können jeweils die Einzelwerte
für Stunde, Minute und Sekunde abgefragt werden.
Mit gettime() wird die Uhrzeit als Block ausgelesen und in der Benutzerdefinierten
Variable time vom Typ TIME gespeichert.
Letztere Möglichkeit hat den Vorteil, daß man sich nicht um einen Sekundenwechsel
zwischen den Abfragen sorgen muß.

Der Variabel-Typ system.TIME:
type TIME
{
 int hour;
 int minute; 
 int second;
}

Variabeln vom Typ TIME werden folgendermaßen definiert:
system.TIME Zeit;



Status des DCF77-Syncronisation
  Nach oben

    inline function dcferr() returns int

Das Betriebssystem versucht zu jeder vollen Minute die interne Echtzeituhr auf
den empfangenen DCF77-Datenrahmen zu synchronisieren.
Unter schlechten Empfangsbedingungen kann eine Synchronisation über
einen längeren Zeitraum ausfallen. Die interne Echtzeituhr läuft dann quarzgetaktet weiter.
Bedingt durch Temperatureinflüsse und Toleranzen der elektronischen Bauteile führt das
nach einer längeren Zeit zu einer zunehmenden Zeitabweichung der internen Uhr.
Um im C2-Programm die Aktualität und Genauigkeit der internen Uhr abzuschätzen, kann
über die Funktion dcferr ein Zähler des Betriebssystems abgefragt werden, der die Anzahl
der vergeblichen Synchronisationen wiedergibt.
Das Rücksetzen des Zählers erfolgt mit jeder korrekten Synchronisation.
Ist dann z.B. innerhalb von 30 Minuten keine neue Synchronisation möglich, steht der Zähler auf 30.
Bei dauerhaftem Synchronisationsausfall wird der Zähler auf dem Wert 32767 festgehalten.
Auch beim Reset wird der Zähler mit diesem Wert initialisiert.
Wichtig !
Durch einen Bug im Original OS (Release 20.12.2000) ergibt sich nach dem Programmstart
auch ohne DCF77-Empfang der Wert 0 für dcferr().
Es sollte daher immer OSOPT_V2 bzw. OSOPT V3.0 oder höher benutzt werden.

Datum setzen   Nach oben

    function setdate(int year, int month, int day)

Mit setdate() kann das Datum der CC2-Echtzeituhr gesetzt werden.
Die Daten für DOW (Wochentag) und DST (Sommerzeit-Flag) werden
in der Funktion berechnet und entsprechend gesetzt.

year Jahr, vierstellig !
month Monat (1-12)
day Tag (1-31 bzw. 1-30 bzw. 1-28/29)

 

Datum abfragen   Nach oben

    inline function year() returns int
    inline function month() returns int
    inline function day() returns int
    inline function dow() returns int

Mit diesen Funktionen können die Werte für Jahr, Monat, Tag und Wochentag
abgefragt werden.
year() gibt dabei die Jahreszahl vierstellig, month() den Monat (1-12),
day() den Kalendertag (1-31) und dow() den Wochentag (0-6) zurück.
Beim Wochentag entspricht 0 Sonntag, 1 Montag bis 6 für Samstag.

Sommerzeitflag abfragen   Nach oben

    inline function dst() returns int

Die Funktion dst() gibt den Zustand des Sommerzeitflags (DST) zurück.
Der Wert 0 (False) entspricht der Winterzeit(Normalzeit), der Wert -1 (True) der Sommerzeit.
Das DST-Flag wird entweder durch das Stellen des Systemdatums berechnet und gesetzt,
oder durch den Aufruf der Funktion setDST() gesetzt.

buf[] Byte-Puffer für die zu empfangenen Daten
len Anzahl der zu empfangenen Bytes
timeout Zeit in ms, die auf Daten gewartet werden soll,
bis abgeprochen wird.

 

Sommerzeit-Flag setzen / Sommer-/Winterzeitumstellung   Nach oben

    function setDST() returns int

Mit dieser Funktion kann die CC2-Echtzeituhr automatisch auf Sommerzeit
bzw. Winterzeit gesetzt werden.
Bei jedem Aufruf wird geprüft, ob die Zeit umgestellt werden muß.
Beim Wechsel von Winter- auf Sommerzeit wird die Uhr um eine Stunde vorgestellt,
beim Wechsel von Sommer- auf Winterzeit eine Stunde zurück.
Dies geschieht jeweils am letzten Sonntag im März bzw. Oktober ab 2 bzw. 3 Uhr.
Wird die Funktion nicht am Tag der Zeitumstellung aufgerufen, so muß beachtet
werden, daß eine Umstellung nur zwischen 1Uhr und 22 Uhr erfolgt.
Die Funktion gibt zurück, wie die Uhr verstellt wurde:
 0 - Es gab keine Zeitumstellung
 1 - Die Uhr wurde um eine Stunde vorgestellt (Winter- auf Sommerzeit)
-1 - Die Uhr wurde um eine Stunde zurückgestellt (Sommer- auf Winterzeit)
Bei einer Zeitumstellung durch diese Funktion wird auch das DST-Flag entsprechend gesetzt.

Es empfiehlt sich die Funktion setDST() zyklisch aufzurufen. Hier kann z.B.
ein Thread benutzt werden, der z.B. allgemeine Aufgaben erledigt und daher
ständig läuft.

Wird mit dem PCF8583 Uhrenbaustein und somit mit dem Modul pcf8583.c2(ab V1.51)
gearbeitet, so wird das Aufrufen dieser Funktion von dem Thread pcf8583.sync erledigt,
sofern autosync beim Init des Moduls pcf8583.c2 aktiviert wurde.

Aufruf von Systemroutinen   Nach oben

    inline function call( int segment, int offset )
    inline function jump( int segment, int offset )

Mit diesen Funktionen können Systemroutinen, geschrieben in Assembler oder C,
aufgerufen werden.
Bei call() erfolgt ein Aufruf der Systemroutine mit anschließender Rückkehr
in das C2-Programm.
Bei jump() erfolgt ein Sprung zur Systemroutine. Das C2-Programm und
somit die VM wird verlassen 
Jump wird nur benötigt, wenn man ohne dem Betriebssystem arbeiten will,
aber z.B. Anfangs über ein C2-Programm Initialisierungen vornehmen möchte.

segment Segment-Nr. 0 bis 8
0 = Betriebssystem, interner RAM
1 = frei verwendbar (OSOPT ab V3.0 notwendig)
2 = frei verwendbar (OSOPT ab V3.0 notwendig)
3 = frei verwendbar (einige Module benötigen
      Systemtreiber in diesem Segment)
4,5 = VMC-Programmroutinen
6,7 = Konstantenspeicher
8 = SRAM
offset 0x0000 bis 0xFFFE
Die Adresse müssen geradzahlig sein !

Hinweis für mit call() aufgerufene Systemroutinen:
Der Rechenstack der Assembler- bzw. C-Routine muß durch
zweimaliges Pop zuerst geleert werden, bevor man in das C2-Programm
zurückkehren kann !
Bsp.in ASM:
xy    proc far
      ...
      ;Systemroutine
      ...
      POP R1
      POP R1
      RETS
xy    endp


Benutzerdefinierte Interruptroutinen   Nach oben

    inline function hook(int event, int segment, int offset, int mode)
    inline function unhook(int event)

Mit hook() können Systemroutinen, ausgelöst durch folgende Ereignisse,
aufgerufen werden:

Die Funktion hook “hängt ”eine benutzerdefinierte Interruptroutine in die normale
Interruptbehandlung des Systems ein.Der Parameter event gibt vor,für welche Interrupt-
quelle eine Interruptroutine aktiviert werden soll:
Event  Interruptquelle
EVENT_TIMER (0) 1 ms Timer
EVENT_P1H0 (1) Digitalport P1H.0
EVENT_P1H1 (2) Digitalport P1H.1
EVENT_P1H2 (3) Digitalport P1H.2
EVENT_P1H3 (4) Digitalport P1H.3

Die Parameter segment und offset geben die Speicheradresse der Interruptroutine im
Gesamtadreßraum des Mikrocontrollers an.
Wenn eine C-Funktion als Interruptroutine geschreiben werden soll, muß diese im Stil
void fx ( void )
definiert sein, also ohne Parameter und Rückgabewert.
Wird eine Interruptroutine in die normale Interruptbehandlung des Systems eingehängt,
gibt es für die Abarbeitung bei Auftreten des Interrupts drei Möglichkeiten.
Die gewünschte Variante wird durch den Parameter mode bestimmt

Mode  Ausführung
HOOK_REPLACE (0) an Stelle der normalen Interruptbehandlung des Systems
HOOK_BEFORE (1) vor der normalen Interruptbehandlung des Systems
HOOK_AFTER (2) nach der normalen Interruptbehandlung des Systems

Das Aktivieren eigener Interruptroutinen stellt einen erheblichen Eingriff in das
Gesamtsystem dar und hat entscheidenden Einfluß auf dessen Zeitverhalten!
Interruptroutinen müssen so kurz wie möglich gehalten werden.

Eine Interruptroutine für ein Ereignis kann durch Aufruf der Funktion unhook()
deaktiviert werden.

 

EXICON-Register Fast-Interrupts P1H.0-.3   Nach oben

    function setEXICON(int event)
    function getEXICON() returns int

Mit diesen Funktionen kann die Bedingung für ein Interruptereignis für
die Ports P1H.0 bis .3 festgelegt bzw. abgefragt werden.
Es kann dabei bestimmt werden, ob Interrupts bei fallender Flanke (Standard),
bei steigender oder bei allen Flanken ausgelöst werden. zudem können die Interrupts
für einzelne Ports deaktiviert werden, um ein unnötiges Auslösen beim Betrieb dieser
Ports als reine I/Os zu verhindern.
Die Einstellung hat ebenso auf die Counter-Funktion Auswirkungen.
Jeweils zwei Bit im Bitmuster bestimmen das Verhalten des jeweiligen Ports.

event EXICON-Register
0b33221100  (00=P1H.0, 11=P1H.1 usw.)
0b00=kein Interrupt
0b01=fallende Flanke
0b10=steigende Flanke
0b11=beide Flanken

Beispiel: Interrupts an P1H.0 unterbinden und P1H.1 bei beiden Flanken auslösen:
function InterruptChange()
{
 system.setEXICON((system.getEXICON() and 0b00) or 0b1100);
}


Threadwechsel unrerbinden
   Nach oben

    function threadStepReset()

Mit diesen Funktionen der Step-Counter des aktuellen Threads zurückgesetzt werden,
um einen Thread-Wechsel gezielt zu unterbinden.
Die Funktion benötigt mit Aufruf selbst vier Instruktionen.
In Verbindung mit einem "run 255" können so eine bestimmte Anzahl an Instruktionen
unterbrechungsfrei ausgeführt werden.
Diese Funktion ersetzt das bisher übliche Konstrukt mit einem yield. (yield; run255; ... resume;)
Jedoch erfolgt hier nicht, wei bei yield ein sofortiger Threadwechsel, so daß diese
Funktion prinzipiell genau das Gegenteil von yield darstellt.

Beispiel:
function xy()
{
 run 255;
 system.threadStepReset();
 //...
 // max. 254 ununterbrochene VM-Instruktionen
 // bei erneuten Aufruf nach spätestens 251 Instruktionen
 // weitere 254 ununterbroche Instruktionen
 resume;
}

 

Betriebssystem-Informationen abfragen   Nach oben

    function getOSInfo(byte s[])
    function getOSVer(byte s[])
    function getOSRelease(byte s[])

Mit diesen Funktionen kann man die Versions-Infos des geladenen
Betriebssystems(OS) auslesen. Die Info wird in dem übergebenen String
gespeichert.
Mit getOSInfo() erhält man einen String mit 20 Zeichen, bestehend aus
Versions-Nr. und Release-Datum. z.B: "CC2 V3.0  2004/01/03"
Mit getOSVer() erhält man nur die OS-Version als String
mit 8 Zeichen. z.B: "CC2 V3.0"
Mit getOSRelease() erhält man nur das Releasedatum als String
mit 10 Zeichen. z.B: "2004/01/03"

s String-Variable

Wichtig!
Bis OSOPT_V2 wird bei der OS-Version "CC2  V.1" zurückgegeben !
Erst ab OSOPT V3.0 erhält man die tatsächliche Versionsnummer.
Daher sollte man im Zweifelsfall immer nach dem Releasedatum gehen.

Beispiel:
thread main
{string s;
 lcdext.init();
 system.getOSInfo(s);
 lcdext.print(s);
 system.getOSRelease(s);
 lcdext.line(2);
 lcdext.print(s);
 system.getOSVersion(s);
 lcdext.line(3);
 lcdext.print(s);
 quit 1;
}



Autor: André Helbig    www.CC2Net.de     Erstellt: 13.04.2008