en:pfw:multi_tasker
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| en:pfw:multi_tasker [2024-08-17 10:04] – [The idea] willem | en:pfw:multi_tasker [2025-03-14 13:30] (current) – [Contributions] willem | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ===== Cooperative multitasker ===== | ===== Cooperative multitasker ===== | ||
| - | < | ||
| Line 15: | Line 14: | ||
| * **You determine the task change with** '' | * **You determine the task change with** '' | ||
| * **The basic word set:** '' | * **The basic word set:** '' | ||
| + | |||
| + | {{ : | ||
| 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 ^ Function | ^ TCB ^ Task1 ^ Task2 ^ Task3 ^ Function | ||
| | **Link** | | **Link** | ||
| - | | **Tstate** | + | | **Tstate** |
| - | | **Error# | + | | **Error# |
| | **TRP** | | **TRP** | ||
| | **TR0** | | **TR0** | ||
| 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 a 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 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@ > | swap r@ > | ||
| + | </ | ||
| + | |||
| + | ==== 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 | ||
| </ | </ | ||
| Line 254: | Line 271: | ||
| < | < | ||
| + | **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 ''> | ||
| + | |||
| + | <code forth> | ||
| + | code PAUSE ( -- ) \ 29 machine cycles, is 0.232 microsec. at 125 MHz | ||
| + | { ip sp tos } push, \ 4 - Save tasks Forth environment | ||
| + | sun TP mov, \ 1 - TCB address to SUN | ||
| + | day rp mov, \ 1 - RP to DAY | ||
| + | day sun 0C #) str, \ 2 - DAY TRP ! | ||
| + | begin, >box | ||
| + | begin, | ||
| + | sun sun ) ldr, \ 2 - Fetch next link to SUN | ||
| + | day sun 4 #) ldr, \ 2 - Next TSTATE @ to DAY | ||
| + | day 0 # cmp, \ 1 - | ||
| + | =? no until, | ||
| + | TP sun mov, \ 1 - Next link address = new TCB | ||
| + | day sun 0C #) ldr, \ 2 - TRP @ to DAY | ||
| + | rp day mov, \ 1 - DAY to RP | ||
| + | { ip sp tos } pop, \ 4 - Restore tasks Forth environment | ||
| + | begin, >box | ||
| + | next, \ 6 | ||
| + | end-code | ||
| + | |||
| + | code STOP ( -- ) | ||
| + | tp> , ( Address of main TCB ) | ||
| + | code> | ||
| + | w w ) ldr, \ 2 - main TCB to W | ||
| + | sun TP mov, \ 1 - Task to DAY | ||
| + | sun w cmp, \ 1 - main = task? | ||
| + | box> =? no until, | ||
| + | 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 TRP | ||
| + | box> again, | ||
| + | end-code | ||
| + | |||
| + | code SLEEP ( task -- ) | ||
| + | tp> , ( Address of main TCB ) | ||
| + | code> | ||
| + | w w ) ldr, \ 2 - main TCB to W | ||
| + | tos w cmp, \ 1 - main = task? | ||
| + | =? no if, > | ||
| + | day 0 # movs, \ 1 | ||
| + | ahead, > | ||
| + | end-code | ||
| + | |||
| + | code WAKE ( task -- ) | ||
| + | day 0 # movs, \ 1 - Build true flag | ||
| + | day day mvns, \ 1 | ||
| + | box> then, \ | ||
| + | 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 from stack to IP | ||
| + | day tos 20 #) ldr, \ Read TR0 to DAY | ||
| + | rp day mov, \ Use TR0 as tasks RP | ||
| + | sp tos 24 #) ldr, \ Use TS0 as tasks SP | ||
| + | { ip sp tos hop } push, \ Initialise tasks return stack | ||
| + | day rp mov, \ Copy RP to DAY | ||
| + | day tos 0C #) str, \ Set tasks TRP too | ||
| + | rp moon mov, \ Restore noForth registers | ||
| + | { ip sp } pop, | ||
| + | tos sp )+ ldr, \ Pop stack | ||
| + | next, | ||
| + | end-code | ||
| + | </ | ||
en/pfw/multi_tasker.1723881878.txt.gz · Last modified: 2024-08-17 10:04 by willem