
|
INFO - FAQ - CC2-Forum - CCPro-Forum |
|
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 |