Das Open-Control-Projekt - Die Alternative zur C-Control-I


Das Forum zur C-Control-1
Welche C-Control-Varianten existieren?
Übersicht - Suchen - Neueste 50 Beiträge - Neuer Beitrag - Login - Registrieren
INFO - FAQ - CC2-Forum - CCPro-Forum 

 Einfacher Watchdog fuer C-Control 1/Station Kategorie: C-Control I V1.1 (von Jürgen Christoph - 13.11.2004 23:37)
Hallo

Beim meiner C-Control-Station hatte ich das Problem, dass ich einen
Watchdog brauche, moeglichst ohne Zusatzhardware, also den auf der
CPU. Dazu gibt es auch in der Programmsammlung ein Beispiel, das
darauf beruht, den Timer-Interrupt zur Bedienung des Watchdog her-
anzuziehen. Das wollte ich noch etwas erweitern, weil man damit
nicht erkennen konnte, ob das Basicprogramm ueberhaupt noch korrekt
arbeitet, solange der Timerinterrupt noch arbeitet, wird nie der
Watchdog zuschlagen.

Die Idee ist eine Variable, die von der Anwendung stets rueck-
zusetzen ist, und wenn sie dennoch ueberlaeuft, wird der Timer-
interrupt einen Reset ausloesen.

Das ist sozusagen ein Software-Watchdog ueber den Hardware-Watch-
dog der CPU gesetzt. Damit bekommt nun die C-Control ihren Reset,
wenn sich das Basic-Programm "verlaufen" sollte.

Wer mag kann es gerne mal probieren, anbei die .S19 Datei und die
Assemblerquelle.

Viel Spass damit, J. Christoph


Watchdog.S19:

S1220101200520099B20FDA619B7523FDC9BA6DCB79FA6D8B7A09A81071338100CB61F4C
S12301200B7B0AAB7DB784B61EA9002008ABE8B784B61EA903B783B71EB684B71F3CDCB6E8
S11A0140DCA10A260D3FDCCD0E913CA026043C9F27B34F81A60181B0
S5030003F9

Watchdog.A05:

;********************************************************************
;* Assembler:   AS05.EXE
;* Dateiname:   WatchDog.a05
;* Ausgabe:     WatchDog.s19
;* System:      C-Control Station I
;* Autor:       J. Christoph
;* Datum:       2004-11-12
;*
;* Abgeleitet von WDOG der "DEMO ZUM WATCHDOG", CONRAD ELECRONIC 7.01
;*
;* Funktionsweise WDOG:
;*  Der Watchdog des hc05 Prozessors laeuft in maximal 3 Millisekunden
;*  ab und ist direkt aus dem BASIC Programm nicht schnell genug bedienbar.
;*  Der Timer-Interrupt kommt alle 20 Millisekunden und reicht dazu auch
;*  nicht aus; kann aber dazu gebracht werden. Folgender Trick wird angewandt:
;*  Der Timer-Interrupt wird zehnmal schneller erzeugt, kommt also
;*  alle 2 Millisekunden, das reicht um darin den Watchdog zu bedienen.
;*  Damit die Uhrzeit korrekt bleibt, ruft der Timerinterrupt nur jedes
;*  zehnte Mal dann noch die eigentliche Funktion des Betriebssystem auf.
;*
;* Unklar in der Quelle WDOG war mir:
;*  Normalerweise wird Output compare register 2 mit den Werten
;*  10000 und 625(SLOWMODE, ein sechzehntel) aufgezogen, bei WDOG
;*   1000 und 125(SLOWMODE, ein achtel). Das mit der 125 habe ich
;*  uebernommen, aber nicht so richtig verstanden. Vielleicht ist
;*  tatsaechlich statt der 125 eine 62,5 gemeint. Egal, SLOWMODE
;*  benutzt eh kaum einer, ist die C-Control doch schon langsam
;*  genug.
;*
;* Die Neuerungen:
;*  Einen Watchdog in einer Interrupt-Funktion zu bedienen, ist nicht
;*  optimal, und in sonstigen Embedded-Anwendung meist unzulaessig.
;*  Warum? Das BASIC Programm kann sich laengst verlaufen haben und
;*  arbeitet nicht mehr, da laeuft der Timer-Interrupt immer noch.
;*  Abhilfe: Es wird zusaetzlich vom Timerinterrupt eine 16 Bit Variable
;*  benutzt, die zum Reset fuehrt, wenn das BASIC-Hauptprogramm diese
;*  nicht mehr regelmaessig bedient.
;*  Den Timeout kann man grosszuegig bemessen, maximal sind
;*  65536 * 20ms -> 21,8 Minuten moeglich.
;*  Es haengt von der jeweiligen C-Control Anwendung ab, was da fuer
;*  sinnvoll erachtet wird; und kann in der Source Watchdog.a05 an-
;*  gepasst werden.
;*
;*  Diese 16 Bit Variable muss nun im BASIC Programm in seiner
;*  Hauptschleife, also da wo es immer vorbeikommen sollte, wenn es
;*  noch lebt, immer wieder rueckgesetzt werden. Und zwar mit einem
;*  Aufruf SYS &H103, siehe hier im Code bei "Serve".
;*  Ich entschied mich fuer ca. 3 Minuten, siehe Konstante 9000,
;*  damit ich genug Zeit habe, per Fernwartung ein neues Programm zu
;*  laden und selbsttaetig neu zu starten, und das alles waehrend der
;*  Watchdog aktiv bleibt.
;*
;* Variablen Speicherbedarf.
;*  Um nicht Speicher aus den spaerlichen 24 Byte des Anwenders zu
;*  belegen, benutzt das Programm hier folgende 3 Bytes:
;*
;*  $dc: Vorteiler durch 10, siehe auch WDOG, das dort $a1 benutzte,
;*       also die user byte variable [1]. Speicherstelle $dc wird
;*       in der C-Control offenbar nirgends benutzt.
;*  $9f: Zufallszahlengenerator (high byte) von RANDOMIZE
;*  $a0: Zufallszahlengenerator (low byte)  von RANDOMIZE
;*       Damit ist die BASIC Funktion RANDOMIZE nicht mehr verwendbar,
;*       die ich aber noch niemals gebraucht habe, da die C-Control in
;*       meinen Anwendungen nie Zufaelliges tun soll; und wenn, tut's
;*       dann der aktuelle Inhalt von TIMER. Wer auf RANDOMIZE
;*       nicht verzichten mag, nehme zwei andere freie Bytes.
;*
;* Wichtige Hinweise:
;*  1. END
;*  Die BASIC Anweisung END kann nicht mehr benutzt werden, da sonst
;*  der Watchdog zuschlagen wird. Schliesslich weiss das Programm hier
;*  nicht, ob das BASIC Programm sich in eine Endlosschleife begab
;*  oder END benutzte. Bei der Anwendung eines Watchdogs ist aller-
;*  dings nicht zu erwarten, dass jemand ein END braucht, da das
;*  Programm schliesslich nicht anhalten soll. Sollte jemand auf
;*  END nicht verzichten koennen, Abhilfe ist einfach:
;*  Anstelle von END benutze man dann (Endlos Watchdog fuettern):
;*  #EndLoop
;*   SYS &H103
;*   GOTO #EndLoop
;*
;*  2. RANDOMIZE
;*  Die BASIC Anweisung RANDOMIZE kann nicht mehr benutzt werden,
;*  siehe oben bei Variable $9f/$a0.
;*
;*  3. SYSCODE
;*  Es reicht, den Syscode nur einmal in die C-Control zu laden und
;*  dann die Anweisung SYSCODE aus dem BASIC Programm auszu-
;*  kommentieren, zu Schonung des bei SYSCODE in der C-Control
;*  benutzen Eeproms.
;*
;* Hardware Voraussetzungen:
;*  Die Starttaste der C-Control muss permanent aktiv sein, nur dann
;*  kann das System nach dem Watchdog-Reset selbsttaetig neu starten.
;*
;********************************************************************

Vorteiler    equ $dc        ; Benutzt als Teiler durch 10
ZaehlerHigh  equ $9f        ; High byte Watchdog Zaehler (z.B RANDOMIZE High)
ZaehlerLow   equ $a0        ; Low byte Watchdog Zaehler  (z.B.RANDOMIZE Low)

;********************************************************************
        ORG     $0101       ; Beginn des Programms
;********************************************************************

Start
;********************************************************************
                            ; ALLE Einsprunge durch BASIC liegen am
                            ; Anfang, aendern also ihren SYS-Einsprung
                            ; nicht, sollte der Code dahinter modifiziert
                            ; werden.
Init    BRA     FuncInit    ; Diese Interrupt Routine aktivieren SYS &H101
Serve   BRA     FuncServe   ; Software Watchdog bedienen         SYS &H103
Force ;;BRA     FuncForce   ; Watchdog zwangsweise ausloesen     SYS &H105
;********************************************************************

FuncForce                   ; Force the Watchdog to reset system
        SEI
        BRA FuncForce

FuncInit
        LDA #(Irq-Start+1)  ; Vector auf die neue Funktion "Irq" setzen.
        STA $52
        CLR Vorteiler
      ;;BRA FuncServe       ; Und auch den Software 16Bit Zaehler setzen.
       
FuncServe                   ; Ruecksetzen der 16 Bit Variable, das Minus wird
        SEI                 ; gebraucht weil der Zaehler hoch-, nicht runtergezaehlt
        LDA #hi(-9000)    
        STA ZaehlerHigh
        LDA #lo(-9000)     ; 9000 bedeuten 3 Minuten * 60 Sekunden * 50Hz(20millisec)
        STA ZaehlerLow
        CLI
        RTS
       
Irq
        BRCLR 3,$13, ExitA1 ; Branch if (Timer status register).3 not set
        BSET  0,$0C         ; Aktiviere / Bediene Watchdog

        LDA $1F             ; (OCR2LOW (Output compare register 2, low byte))
        BRCLR 5,$7B, Fast   ; Abfrage SLOWMODE
Slow
        ADD #lo(125)        ; Wieso 125 ist mir unklar, uebernommen vom Conrad Beispiel
        STA $84             ; (Buffer zum Berechnen von OCR1 & OCR2 (low byte))
        LDA $1E             ; (OCR2HIGH (Output compare register 2, high byte))
        ADC #hi(125)
        BRA Common
Fast
        ADD #lo(1000)
        STA $84             ;
        LDA $1E             ;
        ADC #hi(1000)
Common
        STA $83             ; (Buffer zum Berechnen von OCR1 & OCR2 (high byte))
        STA $1E             ;
        LDA $84             ;
        STA $1F             ;

        INC Vorteiler
        LDA Vorteiler
        CMP #10
        BNE ExitA0
Milli20
        CLR Vorteiler
        JSR $0E91           ; ($6e:$6d = $6e:$6d + #20, Zeitzaehler)
       
        INC ZaehlerLow      ; 16 Bit Zaehler Low Byte erhoehen
        BNE ExitA0          ; Low byte nicht 0? Dann auch Zaehler insgesamt nicht 0
        INC ZaehlerHigh     ; 16 Bit Zaehler High Byte erhoehen
        BEQ FuncForce       ; Wenn 0, dann Zaehler von FFFF nach 0000 gelaufen, Reset erzwingen
ExitA0
        CLRA                ; Fertig
        RTS
ExitA1
        LDA #01             ; Nun noch Original-Interrupt bedienen
        RTS
       



 Antwort schreiben

Bisherige Antworten:

Re: Einfacher Watchdog fuer C-Control 1/Station (von Arno Civelek - 25.02.2005 23:58)