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:57] – [Implementation specific and example] 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 232: Line 234:
     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 248: Line 250:
     swap >r  false r@ terr? his !   \ Reset tasks error flag     swap >r  false r@ terr? his !   \ Reset tasks error flag
     swap 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 254: 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.1723881479.txt.gz · Last modified: 2024-08-17 09:57 by willem