Go to Triangle Digital Support Home Page TDS2020F TECHNICAL MANUAL
Programming
Error handling
Live website search
Enter key words
 

ERROR HANDLING

RECOMMENDED METHODS

Appropriate handling of run-time errors is especially important in embedded systems. Here are some suggestions presented in a cookbook fashion. For a more detailed explanation see OPERATION OF CATCH AND THROW, page 146.

MESSAGES TO SERIAL PORT 1

Use this recommendation if serial Port 1 is used only during compiling, not by the application. If you structure the end of your program as follows you can .

 

q       escape to Forth by connecting a terminal to serial Port 1 and pressing any key. This allows final debugging and later system maintenance and repair even though the program is by then fixed in PROM.

q       see run-time error messages on a terminal attached to serial Port 1. For example these might include ADDR ERROR if the program mistakenly reads an odd numbered address or FULL STACK if you've accidentally left something on the stack each time round the main loop.

q       have the program restart from the beginning after an error in the hope that this will at least enable partial operation until the fault can be cleared.

: INITIALISE ( - ) \ Set direction of I/O ports,
\ zero all variables, including
\ any multitasker locks.
. initialisations . ;
: TRY ( - ) \ One pass through the main
\ program loop
KEY? IF START THEN
. rest of program . ;
: MAIN ( - ) \ Indefinite application loop
INITIALISE BEGIN TRY AGAIN ;
: WORK ( - ) \ Word executed at power-up
BEGIN ['] MAIN CATCH ERROR AGAIN ;

MESSAGES ELSEWHERE

You can redirect the messages elsewhere by redirecting the EMIT contained within the word ERROR . These are some possibilities that can be substituted for the plain ERROR in the above recommendation-the redirection words shown are in the places indicated:

 

<LCD WIPE ERROR LCD>

See page 101. Send messages to character LCD

<MED G-WIPE ERROR MED>

File #GRAPHIC.TDS. Send messages to graphics LCD

<2 ERROR 2>

File #SERIAL2.TDS. Send messages to serial Port 2

NO MESSAGES

If you want no messages on error just put SP0 @ SP! in place of ERROR in the above example. This will clear the stack and still cause the application to restart.

NO RESTART ON ERROR

In some circumstances it can be dangerous to operate an embedded computer with a run-time fault in the application software. In these cases it may be more prudent to stop operation on error.

To arrange this, eliminate the word WORK above and rename MAIN to WORK . Without the CATCH in your software the system will go to the CATCH inside the Forth loop QUIT , which is always set at power-up, even in a stand-alone system. In other words on a run-time error execution of your program will cease and processing will continue with interactive Forth on serial Port 1.

If you see your prototype halt you can attach a terminal and with interactive Forth discover the source of the bug.

SPECIFIC ACTION ON ERROR

The word ERROR in the above examples displays a message-see ERROR CODES, page 148. However you may want to take some special action after a run-time error. You can change ERROR to anything you want, remembering that the error number is provided on the stack and that you should clear the stack afterwards.

The following substitution for WORK in the above example would just count the number of errors by incrementing the variable ERROR-COUNT :

 

VARIABLE ERROR-COUNT \ Counter of run-time errors

: WORK ( - ) \ Word executed at power-up

ERROR-COUNT OFF \ clear counter

BEGIN ['] MAIN CATCH \ stick here if ok

1 ERROR-COUNT +! \ count error

SP0 @ SP! \ clear stack

AGAIN ;

OPERATION OF CATCH AND THROW

To implement more complex error handling you need to understand the CATCH and THROW mechanism. It is a way of handling exceptions without having to propagate flags up through multiple levels of nesting. It is similar to the 'non-local return' of other languages such as C's setjmp() and longjmp(), or LISP's CATCH and THROW. In ANS Forth THROW is used deep inside the code at a low level as a 'multi-level exit', with CATCH marking the location to which a THROW may return.

CATCH is similar to EXECUTE in that it takes the execution token of a Forth word and performs its action (execution token, or xt, is the new name for a code field address, or cfa, in Forth). The word being executed may have one or more THROWs buried in its sub-structure and will terminate either if it completes in the normal way, or if execution reaches one of the THROWs. In the first case a zero parameter is passed back from the word (on the stack as usual). In the second case the exception number associated with the THROW is given as you suddenly arrive after the CATCH several layers up.

An exception causing such action may be ABORT or ABORT" or an error condition like stack overflow caused by a program bug. On the TDS2020F it can also be a supervisory error generated by the H8/532 microprocessor from execution of an invalid instruction, address alignment or watchdog error, perhaps because an electrical spike has caused the microprocessor to jump out of its program.

By default a THROW will send you back to the CATCH already present within the Forth interactive QUIT loop, which is fine during debugging but often useless in a dedicated target system. You should use your own CATCH to determine operation in the case of exceptions. In the simplest case produce an outer 'error loop' surrounding the indefinite loop in which a dedicated system program should normally stay.

To take the specific example of the recommendation shown at the start of this section, INITIALISE would write to variables and set up hardware like data direction registers. TRY is one pass through the main loop, being defined in terms of simpler primitives to perform the required task. SET WORK is typed interactively after compilation to tell the TDS2020F that WORK is to be executed at power-up.

The execution token of MAIN , obtained by the phrase ['] MAIN , is passed to CATCH whose job is therefore to execute MAIN . This is a never-ending loop where the application should stay if all is well; there is no exit inside MAIN apart from any embedded THROWs.

WORK is the outer indefinite 'error loop' which makes the program restart in case of error. Should a THROW be reached the nesting of words will be abandoned and execution will resume after the word CATCH , leaving the error number on the stack. The word ERROR that then executes is not ANS Forth but is included in the TDS2020F as a default word for error processing. It takes the error number and displays a message describing the fault, also resetting the parameter stack.

For additional principles covering a multitasking system see ERRORS WHEN MULTITASKING, page 199,

PROCESSOR TRAPS

The messages ADDR ERROR, INV INSTN and WATCHDOG indicate that the processor on the TDS2020F lost control via a trap. If this happens the hardware facilities are used to safely re-enter the Forth system. The message indicates what has happened.

Although this is a warm restart there can be no guarantee that the memory data remained intact while the processor was running out of control. However applications can be designed to tolerate most crashes from spikes etc.

Interrupts are disabled after an Address Error trap, but not after the other two. This trap re-enters the code via an NMI that disables interrupts.

The action to be taken on a crash can be altered either as described above or to something you define by changing the action of the appropriate exception interrupt. For more details see:

 

q       INTERRUPT JUMP TABLE, page 170

q       NMI FLOW DIAGRAM, page 165

q       COLD START ROUTINE, page 244

q       ERRORS WHEN MULTITASKING, page 199

 

Here is an example that displays a message instead of the appropriate THROW on a watchdog timeout:

 

CODE RESET-DOG ( - ) \ Housekeeping
B 0 ## DPR LDC, \ ensure DP is page 0
B $FFEC )) R3 MOVI, \ need to clear OVF of TCSR
$FFEC )) $A57F ## MOVIM, \ restart watchdog
END-CODE

 

: MY-DOG ( - ) \ User version of watchdog trap
RESET-DOG ." WATCHDOG FOUND" CR \ user action
SP0 @ SP! ; \ ensure empty stack
1 +ORIGIN ASSIGN MY-DOG \ Associate user word with trap

COLD RESTARTS

The default action on a processor trap is a warm restart via the CATCH and THROW mechanism. For the coldest possible restart install the utility #DOGCOLD.TDS as part of your application, or use this file as an example of how to trap to your own Forth code. However when using multitasking, do not use #DOGCOLD.TDS, but see ERRORS WHEN MULTITASKING, page 199.

COMPILATION ERRORS

Most error messages are for the system's use at compile-time. If the message is followed by the usual 'ok', for instance NOT UNIQUE, it is a warning only. In the absence of 'ok' this was a true error and should be corrected before compilation is attempted again.

If there is a syntax error, compilation stops. The position at which the problem was identified is shown, although the actual error may be a few lines earlier.

ERROR CODES

In this section is a table of error numbers used as parameters of THROW that are allocated on TDS2020F. For instance:

 

HEX -000D THROW

 

will produce the error message UNDEFINED if the previously executed CATCH is followed by the word ERROR provided in the Forth ROM.

The floating point errors are only seen when using the optional software TDS-FLOAT-ANS. All error codes are given here in hex:

 

All positive numbers

 

Free for use by application programmers

0

 

A no-operation in ANS Forth

-0001

 

Used by ABORT

-0002

 

Used by ABORT"

-0003

FULL STACK

The stack is close to overflowing. Check whether an unwanted parameter is being left on the stack each loop.

-0004

EMPTY STK

Empty Stack. Too many items have been pulled off the data stack.

-0008

DICT FULL

Dictionary Full. There is not enough room left for the proposed operation. The value contained in the address returned by $0A +ORIGIN may be too low. See MEMORY MAPS, page 53 for dictionary spaces.

-000D

UNDEFINED

The word specified is not in the dictionary. If WORDS shows it there, the word was never properly defined. E.g. the compiler found a syntax error while trying to compile the word.

-000E

COMP ONLY

Compiling only. Referenced word was found during execution. It should only be used when compiling. Perhaps a colon is missing?

-0010

NO NAME

CREATE (or colon etc.) without a name

-0016

NOT PAIRED

The word shown has no pair. E.g. a LOOP without a DO will give this error.

-0017

ADDR ERROR

Address error, 16-bit access to an odd address. Crashed machine.

-0042

FP DIV 0

Floating point divide by 0

-0043

FP RANGE

Floating point result out of range

-0046

FP INV ARG

Floating point invalid argument

-0100

LEAVE ERR

Word LEAVE used wrongly, perhaps outside a DO LOOP structure.

-0101

NOT UNIQUE

Word is already present, warning only. The new word will supersede the old.

-0102

INCOMPLETE

Stack level changed at compile-time, an IF without a THEN or something similar.

-0103

NOT SET

Word defined with DEFER which has not been given an action with IS .

-0104

NO DEFER

Attempted to use IS with a word not created by DEFER .

-0105

UNRESTORED

Unable to restore input source after EVALUATE .

-0106

INV INSTN

An invalid instruction has been executed. Crashed machine.

-0108

WATCHDOG

The internal watchdog has fired after being ignored for 106ms. Crashed machine.

-0109

LONG SCB

Assembler error; the branch requested of an SCB/xx, instruction is more than 127 bytes.

-010A

OPERANDS

Assembler error; the operands are inappropriate for the op-code used.

-010C

BYTE/WORD

Assembler error; with this instruction you cannot have the byte or word mode requested.

-010D

BIT NUMBER

Assembler error; the bit number requested is not possible with this instruction.

-010E

RAM FULL

End of space for variables. By including the file #EXTVAR.TDS you can place variables in a RAM in the 32-pin socket, giving almost unlimited space.

Others

ERROR xxx

Where xxx is the error number reported.

Go to Triangle Digital Support Home Page Go to top   Next page