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 09:57] – [Implementation specific and example] willem | en:pfw:multi_tasker [2025-02-27 21:13] (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 ^ | + | ^ TCB ^ Task1 ^ Task2 ^ Task3 |
- | | **Link** | + | | **Link** |
- | | **Tstate** | + | | **Tstate** |
- | | **Error# | + | | **Error# |
- | | **TRP** | + | | **TRP** |
- | | **TR0** | + | | **TR0** |
- | | **TS0** | + | | **TS0** |
< | < | ||
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 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@ > | 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 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, | ||
+ | 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 - 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, | ||
+ | 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, | ||
+ | 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, > | ||
+ | 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 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 | ||
+ | </ |
en/pfw/multi_tasker.1723881479.txt.gz · Last modified: 2024-08-17 09:57 by willem