; *************************************************************** ; * 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