Go to Triangle Digital Support Home Page TDS2020F TECHNICAL MANUAL
Interrupt multitasking explained
Live website search
Enter key words



Before considering in detail the multitasking scheme which #ROBIN.TDS provides, we first review the method already built into the Forth ROM. It is included here because for many applications it is a better choice, but is easily forgotten. Although it is a different multitasking method there is compatibility with even Pre-emptive Multitasking and both can be used in the same program.

One pass around the loop of a background task is performed at regular intervals with the precise time defined by the user. This scheme is particularly useful when there are a number of events occurring at pre-set intervals. The background task can handle all of them leaving the foreground task free for asynchronous work. For example a set of timers can be decremented each second to emulate those in PLCs (Programmable Logic Controllers), see file #PLC.TDS.

Using Interrupt Multitasking there is only one parameter stack and user-variables, number formatting area and PAD are common to both tasks. However a second return stack is maintained (above the old one) for the background task. It is particularly economical with memory.


A separate high-level Forth task can be assigned to any or all of the four external and 39 internal interrupts. The task-switching scheme shown in INTERRUPTS, page 169, executes immediately an event happens-this is often what is needed in real-time systems. Using the Timer 3 Output Compare Interrupt B we can arrange for a regular interrupt to occur at whatever interval is desired up to a maximum of 53.3ms. Now the background program is running 'all' the time and can be considered to be in an infinite loop, just like the foreground program.

This is achieved with the word LATER , which determines the interval between successive runs of the background task. LATER takes a number n from the stack, which is then added to the Output Compare Register B. After a period of time (n times 0.8138�s) the free running counter Timer 3 will again match the Output Compare Register B and we will get another 'loop' of the background program.

The example is in the file #RING.TDS which you can try and modify:



: RINGER ( - ) \ Background task,

               \  ring bell every second

   COUNTER @ 19 >      \ true every 20 passes through

   IF                  \ counter reached its limit

      7 EMIT           \ ring bell over serial link

      COUNTER OFF      \ restart counter

   THEN 1 COUNTER +!  \ count off this pass

   61440 LATER RETURN; \ each unit is 814ns, 50ms

                       \ total, i.e. 1/20 sec

: RING ( - ) \ Start background task RINGER

   $FFB0 6 ONE  EIS START ;  \ enable the OCI B

                       \  of timer 3

-27 +ORIGIN ASSIGN RINGER \ associate task RINGER

        \ with output compare interrupt B of timer 3


Type SET RING return (or RING return if using RAM) to start the background task ( DIS will stop it). A further example is given in the file #MT.TDS.

In a real program you can use the Output Compare Interrupt B Enable (bit 6 of address $FFB0) to turn the background task on and off.

You can pass data from one task to another by means of variables or arrays provided one task writes and the other reads. You might want to disable the interrupt or set a semaphore while this 'mailbox' is being written if an interrupt half way through the write would result in bad data being read by the other task. See RESOURCE LOCKS, page 201.


Execution of many background programs at defined time intervals can be achieved using the library program #EVERY.TDS. It is an extension to the above scheme. For example run routine AAAA every 100ms, BBBB every second and CCCC each minute. See the file for a working example but this shows how the multiple regular tasks are defined. Any time period up to 1638.2 seconds (27 minutes) can be used.


: INTWORK \ Interrupt. One pass is made every 1/20

          \  second. As many programs as needed can

          \  be added but total execution time (should

          \  all be called) must be less than 50ms

 0.1 EVERY AAAA  \ do AAAA every 0.1 sec

 1.0 EVERY BBBB  \ do BBBB every second

 60.0 EVERY CCCC  \ do CCCC every minute

 50MS RETURN;     \ return to foreground program


Another file, #PLC.TDS, shows EVERY in use emulating 8 separate timers of a Programmable Logic Controller.

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