User Tools

Site Tools


en:pfw:multi_tasker

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
en:pfw:multi_tasker [2024-08-17 09:53] – [Generic Forth code] willemen:pfw:multi_tasker [2025-02-27 21:13] (current) – [Contributions] willem
Line 1: Line 1:
 ===== Cooperative multitasker ===== ===== Cooperative multitasker =====
-<html><h2 style="background-color:yellow">Under construction</h2></html> 
  
  
Line 15: Line 14:
   * **You determine the task change with** ''%%PAUSE%%''   * **You determine the task change with** ''%%PAUSE%%''
   * **The basic word set:** ''%%TASK%%'' ''%%TASK:%%'' ''%%START-TASK%%'' ''%%WAKE%%'' ''%%SLEEP%%'' ''%%STOP%%'' ''%%PAUSE%%''   * **The basic word set:** ''%%TASK%%'' ''%%TASK:%%'' ''%%START-TASK%%'' ''%%WAKE%%'' ''%%SLEEP%%'' ''%%STOP%%'' ''%%PAUSE%%''
 +
 +{{ :pfw:multitasker_memory_use.gif?direct&400 |}}
  
 A picture of three installed tasks, task3 is asleep.\\ A picture of three installed tasks, task3 is asleep.\\
 +All the tasks link to each other so they form a circular list.\\
 Note that the number of task variables may vary for an other implementation.\\ Note that the number of task variables may vary for an other implementation.\\
 The clue is to find out what's the most efficient method is for a given CPU & Forth implementation.\\ The clue is to find out what's the most efficient method is for a given CPU & Forth implementation.\\
-^  TCB  ^  Task1  ^  Task2  ^  Task3  ^ +^  TCB  ^  Task1  ^  Task2  ^  Task3   Function  ^ 
-|  **Link**  |  task2  |  task3  |  task1  | +|  **Link**  |  task2  |  task3  |  task1  | Tasks link chain 
-|  **Tstate**  |  true  |  true  |  false  | +|  **Tstate**  |  true  |  true  |  false  | Active flag, true = active 
-|  **Error#**  |  0  |  0  |  0  | +|  **Error#**  |  0  |  0  |  0  | Error number, 0 = no error 
-|  **TRP**  |  ptr1  |  ptr2  |  ptr3  | +|  **TRP**  |  ptr1  |  ptr2  |  ptr3  | Return stack pointer 
-|  **TR0**  |  ptr1  |  ptr2  |  ptr3  | +|  **TR0**  |  adr1  |  adr2  |  adr3  | Return stack bottom 
-|  **TS0**  |  ptr1  |  ptr2  |  ptr3  |+|  **TS0**  |  adr1  |  adr2  |  adr3  | Data stack bottom |
  
 <html> <html>
Line 194: Line 196:
 ==== Implementation specific and example ==== ==== Implementation specific and example ====
  
-This part is system specific (noForth t) and it's just an sample implementation:\\+This part is system specific (noForth t) and it's just sample implementation:\\
 <code forth> <code forth>
 \ Redefine teminal I/O and MS to include multitasker \ Redefine teminal I/O and MS to include multitasker
Line 217: Line 219:
 Now a simple example, a counter as background task:\\ Now a simple example, a counter as background task:\\
 <code forth> <code forth>
-Uses: INCR ( 1 +to ) 
- 
 task: one task: one
 0 value CNT  decimal 0 value CNT  decimal
-: COUNTER  1 2 3  begin  incr cnt  50 ms  again ;+: COUNTER  1 2 3  begin  1 +to cnt  50 ms  again ;
 ' counter  one start-task   ' counter  one start-task  
 multi multi
Line 230: Line 230:
 <code forth> <code forth>
 Uses: @+ Uses: @+
 +
 : .WORD     ( u -- ) \ Type the word 'u' with 8-digits : .WORD     ( u -- ) \ Type the word 'u' with 8-digits
     0 <# # # # # # # # # #> type space ;     0 <# # # # # # # # # #> type space ;
  
-: TASKS     ( -- )  \ Show all data from the TCB+: TASKS     ( -- )  \ Show all eight data cells from the TCB
     main     main
     begin     begin
Line 246: Line 247:
 create START-TASK   ( xt task -- )  \ Install & start 'task' with 'xt' create START-TASK   ( xt task -- )  \ Install & start 'task' with 'xt'
     ]  begin  r@ catch terr? !  stop  again  [     ]  begin  r@ catch terr? !  stop  again  [
-DOES>      ( ip xt task -- ) +DOES>      ( xt task ip -- ) 
-    >r  false r@ terr? his !   \ Reset tasks error flag +    swap >r  false r@ terr? his !   \ Reset tasks error flag 
-    r@ >task  r> wake ;        \ Set task ready and start it+    swap r@ >task  r> wake ;        \ Set task ready and start it 
 +</code> 
 + 
 +==== Semaphores ==== 
 + 
 +Semaphores are a way to make part of the processor (temporary) your own. 
 +When several tasks need the same device it is not very handy that they 
 +access this device at about the same time. That's where semaphores can be used. 
 + 
 +<code forth> 
 +: LOCK      ( sema -- ) 
 +    dup @ TP = IF  drop exit  THEN  \ Do nothing when i own it 
 +    BEGIN  dup @ WHILE pause REPEAT \ Semaphore not mine, to next task 
 +    TP swap ! ;                     \ Semaphore free, grab it! 
 + 
 +: UNLOCK    ( sema -- )     dup lock  false swap ! ; \ Free semaphore
 </code> </code>
  
Line 255: Line 271:
 <html><h2 style="background-color:yellow">Implementations</h2></html> <html><h2 style="background-color:yellow">Implementations</h2></html>
  
 +**Primitives for noForth t on the RP2040**
 +
 +Note that this is code directly from the noForth t metacompiler listing.\\
 +So take there there are some meta specific words in it like ''>box'', ''box>'' & ''tp>''.\\
 +
 +<code forth>
 +code PAUSE      ( -- ) \ 29 machine cycles, is 0.232 microsec. at 125 MHz
 +    { ip sp tos } push,     \ 4 - Save Forth environment
 +    sun TP mov,             \ 1 - TCB address to SUN
 +    day rp mov,             \ 1 - RP to DAY
 +    day  sun 0C #) str,     \ 2 - DAY to RP
 +    begin, >box
 +    begin,                  \ An inactive task takes 7 cycles extra = 0.056 µs
 +        sun  sun ) ldr,     \ 2 - Fetch next link to SUN
 +        day  sun 4 #) ldr,  \ 2 - Next TSTATE @ to DAY
 +        day 0 # cmp,        \ 1 -
 +    =? no until,            \ 2 - Not zero?
 +    TP sun mov,             \ 1 - Next link address = new TCB
 +    day  sun 0C #) ldr,     \ 2 - RP @ to DAY
 +    rp day mov,             \ 1 - DAY to RP
 +    { ip sp tos } pop,      \ 4 - Restore Forth environment
 +    begin, >box
 +    next,                   \ 6
 +end-code
 +
 +code STOP   ( -- )
 +    tp> ,  ( Address of main TCB )
 +code>
 +    w  w ) ldr,             \ 2 - main to W
 +    sun TP mov,             \ 1 - Task to DAY
 +    sun w cmp,              \ 1 - main = task?
 +    box> =? no until,       \ 2 - No = continue, yes = ready
 +    day 0 # movs,           \ 1 - False flag
 +    day  sun 4 #) str,      \ 2 - Store in TSTATE of myself
 +    { ip sp tos } push,     \ 4 - Save this tasks Forth environment
 +    w rp mov,               \ 1 - RP to W
 +    w  sun 0C #) str,       \ 2 - W to RP
 +  box> again,               \ 2 - Switch to next task
 +end-code
 +
 +code SLEEP  ( task -- )
 +    tp> ,  ( Address of main TCB )
 +code>
 +    w  w ) ldr,             \ 2 - main to W
 +    tos w cmp,              \ 1 - main = task?
 +    =? no if, >box          \ 2 - No = continue, yes = ready
 +    day 0 # movs,           \ 1
 +  ahead, >box               \ 10 + 2
 +end-code
 +
 +code WAKE   ( task -- )
 +    day 0 # movs,           \ 1 - Build true flag
 +    day day mvns,           \ 1
 +    box> then,              \     Resolve jump
 +    day  tos 4 #) str,      \ 2 - Store in TSTATE of task
 +    box> then,
 +    tos sp )+ ldr,          \ 2 - Drop task
 +    next,                   \ 6
 +end-code
 +
 +code >TASK ( ip xt task -- )
 +    sp  { hop sun } ldm,    \ XT to HOP, IP to SUN
 +    { ip sp } push,         \ Save noForth registers
 +    moon rp mov,            \ Save RP
 +    ip sun mov,             \ Ip to IP
 +    day tos 20 #) ldr,      \ Read R0 to DAY
 +    rp day mov,             \ Use R0 as tasks RP
 +    sp tos 24 #) ldr,       \ Set SP to S0
 +    { ip sp tos hop } push, \ Initialise tasks return stack
 +    day rp mov,             \ Copy RP to DAY
 +    day  tos 0C #) str,     \ Set tasks RP too
 +    rp moon mov,            \ Restore noForth registers
 +    { ip sp } pop,
 +    tos  sp )+ ldr,         \ Pop stack
 +    next,
 +end-code
 +</code>
en/pfw/multi_tasker.1723881188.txt.gz · Last modified: 2024-08-17 09:53 by willem