[PicForth] Re: multitasker.fs question

David McNab david at rebirthing.co.nz
Mon Dec 6 12:35:02 CET 2004


Alex Holden wrote:
> Yep, it's a pretty annoying limitation of the architecture. And for the 
> same reason the task is always reentered at the start of the toplevel 
> word, not at the word after the yield.

I don't think this is accurate.

Just now, I've completed a module which provides words allowing tasks to 
delay for arbitrary measured amounts of time, independently of other tasks.

To test it, I'm running a program with 3 tasks, each of which looks like:

   task : task0

       ttyl" task0 started"
       begin
           blink0 bit-toggle
           1 clk.wait.secs     \ blink once every second
       again
   ;

the other 2 tasks are exactly the same, except they pass different 
values to clk.wait.secs

Quick glossary of above:
  - ttyl" - prints a string to serial port, followed by crlf
  - clk.wait.secs - a macro containing a loop which waits for 1 second to
    elapse (based on a 24-bit int (refer lib3) incremented by timer1
    interrupt, and which contains a yield)

If each task were being re-entered from the top, I'd be seeing the 
'task0 started' message once a second.

FWICT, the 'yield' word generates code to save the PCLATH:PCL pair 
required to jump to the next instruction, then jumps back to the right 
place in 'multitasker's scheduling loop.

If you're seeing your tasks being re-entered from the top after each 
yield, then there's definitely something wrong with picforth and/or your 
code.

> Yep. I have a task which polls a piece of hardware ten times a second 
> and another which talks to a user via a serial terminal. When the user 
> executes a command which requires the task to accept a string, the task 
> sits around in 'accept' indefinitely and the hardware servicing stops 
> for the duration. Calling yield if key? returns false would be ideal but 
> that won't work so I've decided to simply document the fact that normal 
> operation of the system ceases while user interaction is taking place 
> (it only happens when the system is being configured so it's not really 
> a big deal in this case).

I think something's getting really screwed in your compilation.

With my clocktest prog, I added another task which does just as you 
mention - calls yield if key? returns false:

   task : task3
       begin
           yield
           tty.poll if
               tty.getc 1+ tty.putc
           then
       again
   ;

All works fine - the first three tasks blink the LEDs at chosen rates, 
while this new one receives chars and echoes them back incremented.

>> If this is the case (I expect it would be), then it might be worth a 
>> mention in the doco.
> It is, in the second sentence. "It allows you to relinquish the CPU 
> whenever you want, provided that you are not in the middle of a call 
> (context-switch only occurs during top level calls)."

Right you are, but it's not the best wording. I didn't understand it on 
the first couple of readings.

Maybe could be better expressed as "tasks may execute 'yield' anywhere 
within their top-level word, but not within words called by the 
top-level word", or similar.

-- 
Cheers
David


More information about the PicForth mailing list