From 2f83a0bea9da444e3d70569eba3d6847ca02be03 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Fri, 21 Sep 2018 21:59:17 +0200 Subject: ... --- forth/forth/avr/task.fs | 160 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 forth/forth/avr/task.fs (limited to 'forth/forth/avr/task.fs') diff --git a/forth/forth/avr/task.fs b/forth/forth/avr/task.fs new file mode 100644 index 0000000..1a96928 --- /dev/null +++ b/forth/forth/avr/task.fs @@ -0,0 +1,160 @@ +\ ******************************************************************* +\ * +\ Filename: task.txt * +\ Date: 07.06.2015 * +\ FF Version: 5.0 * +\ MCU: Atmega * +\ Copyright: Mikael Nordman * +\ Author: Mikael Nordman * +\ ******************************************************************* +\ FlashForth is licensed according to the GNU General Public License* +\ ******************************************************************* +\ TASK leaves the userarea address on the stack. +\ The basic size of a task is decimal 32 bytes. +\ The return stack, the parameter stack and the tib buffer areas +\ are in addition to that. +\ These are allocated at the end (high address) of the user area. +\ Own user varibles can be allocated from offset 2 upwards, +\ below the return stack. Addsize must reflect any additonal +\ user variables that are used. +\ uareasize = 32 + rsize + tibsize + ssize + addsize +\ +\ The operator task is predefined. +\ flash decimal 72 72 72 0 task: operator +\ +\ A background task with a 12 cell return stack and a +\ 12 cell parameter stack and no tib. +\ flash decimal 0 24 24 0 task: bg1 +\ +\ A background task with also one extra user variable. +\ flash decimal 0 24 24 2 task: bg2 +\ ram decimal 2 user bg2_cnt + +\ Do not use user variables as task specific variables +\ User variables are needed by _words_common_to_several_tasks_ +\ which need some task specific data storage. + +-task +marker -task +hex ram + +\ Near definition saves memory ! +: up! up ! ; +: up@ up @ ; +: op@ operator @ ; +: ul@ ulink @ ; +: ul! ulink ! ; +: op! op@ up! ; +\ access user variables of other task +: his ( task-addr var-addr -- addr ) + up@ - swap @ + +; + +\ Define a new task +\ A new task must be defined in the flash memory space +: task: ( tibsize stacksize rsize addsize -- ) + flash create + up@ s0 - dup \ Basic size ts ss rs as bs bs + ram here + flash , \ User pointer ts ss rs as bs + 4 for + over , + + next + cell+ \ Task size + ram allot +; + +\ Initialise a user area and link it to the task loop +\ May only be executed from the operator task +: tinit ( taskloop-addr task-addr -- ) + \ use task user area + @+ up! \ a addsize-addr + ul@ if \ ? Already running + 2drop + else + \ Pointer to task area + dup 2- task ! + \ r0 = uarea+addsize+rsize + @+ swap @+ rot + up@ + \ a ssize-addr r0 + \ Save r0 + r0 ! \ a ssize-addr + \ s0 = r0 + ssize + @ r0 @ + s0 ! \ a + \ Store task-loop address to the return stack + r0 @ x>r \ rsp + \ Store SP to return stack + 1- dup s0 @ swap ! \ rsp + \ Store current rsp and space for saving TOS and P PAUSE + 5 - rsave ! \ + \ tiu = s0 + 2 + s0 @ 2+ tiu ! + 0 ul! + 0 task 2+ ! \ clear status and cr flag + decimal \ Set the base to decimal + then + op! \ run the operator task again +; + +\ Insert a new task after operator in the linked list. +\ May only be executed from the operator task +: run ( task-addr -- ) + @ up! ul@ 0= if \ ? Already running + up@ \ task-uarea + op! ul@ \ task-uarea operator-ulink + over ul! + swap up! ul! + then + op! \ run operator task +; + +\ End a task by linking it out from the linked list +\ May only be executed from the operator task +: end ( task-addr -- ) + @ up! ul@ if + up@ + op! + begin \ find the uarea in the linked list + dup ul@ <> \ uarea flag + while + ul@ up! \ uarea + repeat + up@ \ uarea prev-uarea + swap up! \ prev-uarea + ul@ \ prev-uarea next-uarea + 0 ul! \ ulink of a ended task is zero + swap up! \ next-uarea + ul! \ + then + op! +; + +\ End all tasks except the operator task +\ May only be executed from the operator task +: single ( -- ) + ul@ op@ <> if \ Are there any running tasks + ul@ op@ ul! \ link operator to himself + up! \ move to next user area + begin + ul@ op@ <> \ is this the last linked user area + while + ul@ 0 ul! \ write zero to ulink + up! \ and move to next user area + repeat + 0 ul! + op! + then +; + +\ List all running tasks +: tasks ( -- ) + up@ op! + begin + up@ + task @ 6 - op! c>n .id space + up! + ul@ op@ - + while + ul@ up! + repeat + up! +; + -- cgit v1.2.3