; ***************************************************************
; * Copyright (C) 2010, Embed Inc (http://www.embedinc.com) *
; * *
; * Permission to copy this file is granted as long as this *
; * copyright notice is included in its entirety at the *
; * beginning of the file, whether the file is copied in whole *
; * or in part and regardless of whether other information is *
; * added to the copy. *
; * *
; * The contents of this file may be used in any way, *
; * commercial or otherwise. This file is provided "as is", *
; * and Embed Inc makes no claims of suitability for a *
; * particular purpose nor assumes any liability resulting from *
; * its use. *
; ***************************************************************
;
; Cooperative task manager. The exported subroutines are:
;
; TASK_INIT
;
; Initializes the state. Must be first call into this module.
;
; TASK_NEW
;
; Create a new task. Call parameters:
;
; W13 - Size of the new task stack in bytes, must be even.
;
; W14 - Start address of the stack for the new task, must be even.
;
; The new task starts immediately after the CALL TASK_NEW instruction. It
; is intended that a GOTO be put there. The call returns 2 instruction
; words after the call, skipping over the GOTO intended to be immediately
; after the call.
;
; Example call:
;
; mov #<stack size>, w13
; mov #<stack>, w14
; call task_new
; goto <new task start point>
; ... ;existing task continues here
;
; The original task continues running until TASK_YIELD is called.
;
; TASK_YIELD
;
; Gives all other tasks a chance to run. Registers listed in TSKSAVE are
; preserved.
;
; On a 33EP series dsPIC, the delay from the TASK_YIELD call in one task
; to the first instruction in the next task is 25 cycles, plus two cycles
; for every register saved. When all register (W0-W14) are saved, a task
; swap takes 55 cycles. That is 786 ns at 70 MHz instruction rate.
;
; TASK_YIELD_SAVE
;
; Like TASK_YIELD, except that all registers are preserved.
;
; TASK_TIME_DONE
;
; Set Z if the current time slice has elapses, and clears Z otherwise.
;
; This routine only exists when an external task yield time mechanism has
; been implemented. See the description of this mechanism in
; QQQ_TASK.INS.DSPIC.
;
; TASK_YIELD_IFTIME
;
; Like TASK_YIELD except that the yield is only performed when there is an
; external indication that it is time for the current task to yield.
;
; This routine only exists when an external task yield time mechanism has
; been implemented. See the description of this mechanism in
; QQQ_TASK.INS.DSPIC.
;
; TASK_EXIT
;
; Entry point to end the current task. The task state slot becomes
; unused, and may be re-used by a future call to TASK_NEW. This entry
; point can be CALLed, but will not return. The stack state is
; irrelevant on entry to TASK_EXIT. The processor is reset on attempt
; to exit the only task.
;
; TASK_KILL
;
; Kill the task with the ID in W0. Nothing is done if the ID matches no
; task. If the current task is killed, this routine will not return. The
; processor is reset on attempt to kill the only task.
;
; TASK_PRUNE
;
; Delete all but the first W0 tasks in the list. The processor is reset
; on attempt to delete all tasks (W0 = 0). If the task calling this
; routine is not one of the first W0 tasks in the list, then not all
; intended tasks may be deleted.
;
; The purpose of this routine is to restore to a set of "base" tasks, with
; all "new" tasks stopped. To use this feature:
;
; 1 - Create all the base tasks, and no others.
;
; 2 - Call TASK_N_CURR to get the number of base tasks.
;
; 3 - Create and possibly stop any number of new tasks. However, the
; original base tasks must not be stopped.
;
; 4 - Call TASK_PRUNE with the number of tasks found in step 2.
;
; TASK_N_MAX
;
; Returns the maximum possible number of tasks in W0.
;
; TASK_N_CURR
;
; Returns the total number of current tasks in W0.
;
; TASK_NID
;
; Returns the task ID for the 0-N task slot identified in W0, where N is
; the value returned by TASK_N_CURR minus 1. The task ID is returned in
; W0.
;
; For valid task slot numbers, the Z flag is cleared. For out of range
; task slot numbers, the Z flag is set and the W0 value is undefined.
;
; TASK_EXIST
;
; Determine whether the task with ID in W0 exists. Z is cleared if the
; task exists and set otherwise.
;
; Global state:
;
; CURRTASK
;
; Global 16 bit unsigned integer variable containing the ID of the
; currently-running task. This variable must be considered read-only by
; application code.
;
; This module is configured by the following preprocessor symbols and files:
;
; MAXTASKS, integer
;
; The maximum number of task that can simultaneously run. Configuring for
; more tasks takes more static storage. Default = 4.
;
; ENDLIM, integer
;
; Minimum number of bytes available to a stack before the stack error trap
; is taken. A stack error trap is taken when a push leaves this many or
; fewer bytes available to the stack.
;
; QQQ_TASK.INS.DSPIC, include file
;
; This include file sets configuration state that needs to be globally
; known, and creates preprocessor routines that may be used outside the
; TASK module. See the header comments in this file for what options are
; available and how they are customized.
;
; The tasks are:
;
; 0 - Original task. This runs the main event loop after initialization.
;
; 1 - *** fill in here ***
;
/include "qq2.ins.dspic"
;*******************************************************************************
;
; Configuration constants.
;
/const maxtasks integer = 4 ;maximum number of concurrent tasks supported
/const endlim integer = 6 ;stack err trap when push with this many bytes left on stack
/include "(cog)src/dspic/task.ins.dspic"
.end