|
||
MULTITASKING SUMMARYDEFINITIONSThis is a list of words defined within the Forth ROM and files #ROBIN.TDS, #TASKS.TDS, #TIMING.TDS & #EVERY.TDS which are available for use in application programs which require multitasking.
FILESThese are the files you might need in using multitasking:
MULTITASKING METHODSThree forms of multitasking are available on TDS2020F embedded computer:
q Interrupt Multitasking where an interrupt swaps the Forth system for a new one at regular intervals. Each time it runs one pass through a high-level Forth word and then returns, so forming a background loop. This is a standard feature of TDS2020F in the Forth ROM. q Co-operative Multitasking is the traditional Forth 'Round Robin' multitasker where one task takes control until the word PAUSE is met which causes a task switch to the next in the ring. This word is already placed in input/output and delay causing routines. q Pre-emptive Multitasking is like Co-operative Multitasking in that it allows I/O and delays to cause a task switch, but no task can hog the processor for more than 10ms (default value). After this time the task is forced to give up control to the next one.
The files #ROBIN.TDS, #TASKS.TDS and associated routines add Co-operative and Pre-emptive multitasking to the one already present in the TDS2020F Forth ROM. These multitaskers are available to subscription customers-see UPDATE SERVICE, page 38. OVERVIEWTDS2020F is a powerful computer spending much of its time dormant in many applications. Make it work harder by doing the job of many dedicated computers. Suppose you are controlling an oven for production line cooking. There is a conveyor belt that carries the product through three zones. They pre-heat, cook then cool the cakes being made. The problem to be considered is PID control (Proportional-Integral-Derivative) of each of the three parts of the oven and the software would be made easier if there were a separate computer for each zone. Otherwise we must work a little on the pre-heat, do part of the cook zone control, then some control of cooling before returning to work on the pre-heat again. Keeping track of software operation in a case like this is difficult. The pre-emptive multitasker shortens development in such a case. We see some applications constructed as a large monolithic program because the author thought multitasking would be hard, but the reverse is true, it saves time and cost. Forget you have only one computer, pretend there are many-three in the case of the cake oven. Now develop the software for each problem independently; expend your efforts on the nuances of the PID control algorithm for each zone. In each case you end up with a single routine (Forth word) in the form of an infinite loop that you would enter at power up if you really did have three computers. Debugging of each can be done independently of the others in the normal way using the interactive Forth facilities, which allow running of a sub-program by just typing its name. The final stage is to combine the individual programs, essentially a mechanical step just following rules. Suppose the three programs are called PREHEAT COOK and COOL . Construct a master program in this way:
: ~PREHEAT FRED ACTIVATE PREHEAT ; : ~COOK HARRY ACTIVATE COOK ; : ~COOL JOE ACTIVATE COOL ; : WORK ( - ) \ Word to be entered at power-up BLUECOLD TASKS \ create set of inactive tasks ~PREHEAT \ start up control of pre-heat oven ~COOK \ start-up control of cooking oven ~COOL \ start-up control of cooler START ; \ maintain interactive Forth on ser. port
Here FRED HARRY JOE are task names and ACTIVATE is in the Forth ROM. Once the program is compiled you interactively type phrase SET WORK to adjust cold start parameters. If using Flash-EEPROM the TDS2020F computer immediately executes WORK and it will also directly enter it at the next power-up. Notice that after three tasks have been given jobs the program executes START , which is the entry point of interactive Forth-itself a never ending loop. By adopting this structure you can monitor the other three tasks while they run. For instance you may construct a small program on the fly to monitor variables as they change in the PREHEAT COOK or COOL programs. That is real debugging! Falling into Forth at the end is not mandatory, but very useful. With this scheme temperature control of each zone of the oven can be done in a way as complex as you want and each will work independently of the other. The important point is that development of the software is easier, more structured and therefore reliable than the alternative method with one large block of code laced with flags remembering current states. Not only this, it costs less to develop and you'll get to market faster. If the different processes interact you need the LOCK and UNLOCK routines provided to manage shared variables and other resources. See RESOURCE LOCKS, page 201. FAST START GUIDE TO PRE-EMPTIVE MULTITASKINGThis multitasking system lets one TDS2020F 'simultaneously' execute many separate programs, each with an infinite loop like BEGIN . AGAIN at its highest level. The tasks can be independent or talk to each other-also any task can start or stop any other. To a large extent the different programs can be debugged individually and this is one of the main advantages of the scheme. These instructions will cover perhaps 80% of all cases. If you need technical detail read the rest, but you might want to stop at the end of this sub-section. SETTING UP NEW TASKSAdd the following near the start of your application program:
INCLUDE #ROBIN.TDS INCLUDE #TASKS.TDS
When the program is compiled using the F8 key it will halt while #ROBIN.TDS and #TASKS.TDS are compiled. Then it will resume and complete as usual. By adding the lines shown tasks FRED HARRY and JOE are available to you. Change the names or the number of tasks by editing #TASKS.TDS. The library routines give the name OPERATOR to the main task and this can be used just like the others. USING MULTIPLE TASKSIn your program use any of the tasks in either of the following ways. The generic description is followed by an example in each case ( 7 EMIT sounds the PC bell):
Generic (loop) : WORK1 <task name> ACTIVATE BEGIN <code done for ever> AGAIN ; Example (loop) : WORK1 \ Ring bell twice per second for ever FRED ACTIVATE BEGIN 7 EMIT 500 MS AGAIN ;
Generic (single pass) : WORK2 <task name> ACTIVATE <code to be done once only> STOP ; Example (single pass) : WORK2 \ Ring bell ten times then stop HARRY ACTIVATE 10 0 DO 7 EMIT 200 MS LOOP STOP ;
Forth words which start other tasks, like WORK1 and WORK2 , are used inside other definitions. The power-up initialisation is a good place to put them and they must be preceded by TASKS (defined in #TASKS.TDS). The main program might now read as follows:
: MAIN TASKS INITIALISE WORK1 WORK2 START ;
Use this as a model for your own program-see ERROR HANDLING, page 144, for its outer shell. Here TASKS sets up the pre-emptive multitasker, INITIALISE is a word you define to clear variables, task locks and set data direction registers. WORK1 and WORK2 are fully debugged programs containing ACTIVATE to give jobs to named tasks and START is the entry point to Forth so that you will have interactive Forth available even in a finished system while the product is working. COMMON RESOURCESA resource is a bit of hardware like an I/O port, a Liquid Crystal Display or memory location. Ideally each resource should be accessed by only one task and the system would behave just as if it were several TDS2020F boards instead of only one, however the interaction of tasks often gives the features required. When more than one task can access a resource you must ensure that it does not create a problem. For instance suppose one task uses a variable to temporarily store information. It writes data to the variable because it will be needed later on. If another task were to use the same variable you might lose the original information. This is why multitasking can be dangerous; the second task might only want the variable occasionally. When testing the program all seems well but later the bug will become apparent-perhaps after the system has been completed and shipped. Try to avoid all multitasking (and interrupts) in safety-critical applications. Make sure that the logic of your design is impeccable, not just that it tests correctly. See RESOURCE LOCKS, page 201, for help in sharing resources. A REAL EXAMPLETo try out the system, compile file #TASKTRY.TDS. Now type SET WORK return (or WORK return if using RAM instead of Flash-EEPROM). The background tasks FRED HARRY and JOE are constructed and then three test words activate and give work to each task. These tasks print to the screen every 2.0, 3.2 and 4.4 seconds. Even so, the foreground task you are using to interactively execute Forth is still active. Show this by slowly typing FRED HALT return and task FRED will not be seen any more. Your input will be broken up by interruptions from the other tasks, but will still work. HARRY HALT and JOE HALT will stop the other two tasks. Use TEST1 , TEST2 , or TEST3 to restart any of the background operations. As compiled, the pre-emptive capability is switched on and you will see that the phrases 'This is task FRED' etc. are occasionally broken up, even though they are produced internally with the word TYPE which only has one PAUSE embedded within it, the only place where a Co-operative Multitasking system will switch tasks. This is because the tasks are being switched pre-emptively. Type UNSLICE and return while the three background tasks are running and you will see that the phrases are no longer broken up because the system has reverted to Co-operative Multitasking. If you are using Flash-EEPROM you can switch off. On power-up there is the usual introductory banner, but the three other tasks are in operation and you will see their output. This is the end of the quick guide-for more technical information that might be needed in some cases read further. |