
|
INFO - FAQ - CC2-Forum - CCPro-Forum |
|
Hallo, ich habe eine C-Station 1 die sehr anfällig ist, wenn ich einen Lichtschalter usw. betätige. Es kommt öfters vor das diese sich mitten im ablauf aufhängt bzw. das Programm abstürzt. Meine Frage: Kann ich mit diesen Watchdog bei ausfall des CPU`s einen Reset und anschließend neu starten ? Gruß Arno > 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 |