1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32 33 34 35
36
37 package ti.sysbios.knl;
38
39 import xdc.rov.ViewInfo;
40
41 import xdc.runtime.Error;
42 import xdc.runtime.Assert;
43 import xdc.runtime.Diags;
44 import xdc.runtime.Log;
45 import xdc.runtime.IHeap;
46
47 import ti.sysbios.knl.Queue;
48
49 /*!
50 * ======== Task ========
51 * Task Manager.
52 *
53 * The Task module makes available a set of functions that manipulate task
54 * objects accessed through pointers of type {@link #Handle}. Tasks represent
55 * independent threads of control that conceptually execute functions in
56 * parallel within a single C program; in reality, concurrency is achieved
57 * by switching the processor from one task to another.
58 *
59 * All tasks executing within a single program share a common set of
60 * global variables, accessed according to the standard rules of scope
61 * defined for C functions.
62 *
63 * Each task is in one of five modes of execution at any point in time:
64 * running, ready, blocked, terminated, or inactive. By design, there is
65 * always one
66 * (and only one) task currently running, even if it is only the idle task
67 * managed internally by Task. The current task can be suspended from
68 * execution by calling certain Task functions, as well as functions
69 * provided by other modules like the Semaphore or Event Modules.
70 * The current task
71 * can also terminate its own execution. In either case, the processor
72 * is switched to the highest priority task that is ready to run.
73 *
74 * You can assign numeric priorities to tasks. Tasks are
75 * readied for execution in strict priority order; tasks of the same
76 * priority are scheduled on a first-come, first-served basis.
77 * The priority of the currently running task is never lower
78 * than the priority of any ready task. Conversely, the running task
79 * is preempted and re-scheduled for execution whenever there exists
80 * some ready task of higher priority.
81 *
82 * @a(Task Stacks)
83 *
84 * When you create a task, it is provided with its own run-time stack,
85 * used for storing local variables as well as for further nesting of
86 * function calls. Each stack must be large enough to handle normal
87 * subroutine calls and one task preemption context.
88 * A task preemption context is the context that gets saved when one task
89 * preempts another as a result of an interrupt thread readying
90 * a higher-priority task.
91 *
92 * See sections 3.5.3 and 7.5 of the BIOS User's Guide for further
93 * discussions regarding task stack sizing.
94 *
95 * Certain system configuration settings will result in
96 * task stacks needing to be large enough to absorb two interrupt
97 * contexts rather than just one.
98 * Setting {@link ti.sysbios.BIOS#logsEnabled BIOS.logsEnabled} to 'true'
99 * or installing any Task hooks will have the side effect of allowing
100 * up to two interrupt contexts to be placed on a task stack. Also
101 * see {@link #minimizeLatency Task.minimizeLatency}.
102 *
103 * @a(Task Deletion)
104 *
105 * Any dynamically created task that is not in the Task_Mode_RUNNING
106 * state (ie not the currently running task) can be deleted using the
107 * {@link #delete} API.
108 *
109 * Task_delete() removes the task from all internal queues and calls
110 * Memory_free() is used to free the task object and its stack.
111 * Memory_free() must acquire a lock to the memory before proceeding.
112 * If another task already holds a lock to the memory, then the thread
113 * performing the delete will be blocked until the memory is unlocked.
114 *
115 * Note:
116 * Task_delete() should be called with extreme care.
117 * As mentioned above, the scope of Task_delete() is limited to
118 * freeing the Task object itself, freeing the task's stack memory
119 * if it was allocated at create time, and removing the task from
120 * any SYS/BIOS-internal state structures.
121 *
122 * SYS/BIOS does not keep track of any resources the task may have
123 * acquired or used during its lifetime.
124 *
125 * It is the application's responsibility to guarantee the integrity
126 * of a task's partnerships prior to deleting that task.
127 *
128 * For example, if a task has obtained exclusive access to a resource,
129 * deleting that task will make the resource forever unavailable.
130 *
131 * Task_delete() sets the referenced task handle to NULL. Any subsequent
132 * call to a Task instance API using that null task handle will behave
133 * unpredictably and will usually result in an application crash.
134 *
135 * Assuming a task completely cleans up after itself prior to calling
136 * Task_exit() (or falling through the the bottom of the task
137 * function), it is then safest to use Task_delete() only when a task
138 * is in the 'Task_Mode_TERMINATED' state.
139 *
140 * Delete hooks:
141 * You can specify application-wide Delete hook functions that
142 * run whenever a task is deleted. See the discussion of Hook Functions
143 * below for details.
144 *
145 * Task_delete() constraints:
146 * @p(blist)
147 * -The task cannot be the currently executing task (Task_self()).
148 * -Task_delete cannot be called from a Swi or Hwi.
149 * -No check is performed to prevent Task_delete from being used on a
150 * statically-created object. If a program attempts to delete a task object
151 * that was created statically, the Memory_free() call will result in an
152 * assertion failure in its corresponding Heap manager, causing the
153 * application to exit.
154 * @p
155 *
156 * @a(Stack Alignment)
157 *
158 * Stack size parameters for both static and dynamic tasks are rounded
159 * up to the nearest integer multiple of a target-specific alignment
160 * requirement.
161 *
162 * In the case of Task's which are created with a user-provided stack,
163 * both the base address and the stackSize are aligned. The base address
164 * is increased to the nearest aligned address. The stack size is decreased
165 * accordingly and then rounded down to the nearest integer multiple of the
166 * target-specific required alignment.
167 *
168 * @p(html)
169 * <a name="hookfunc"></a>
170 * @p
171 *
172 * @a(Hook Functions)
173 *
174 * Sets of hook functions can be specified for the Task module. Each
175 * set can contain these hook functions:
176 * @p(blist)
177 * -Register: A function called before any statically created tasks
178 * are initialized at runtime. The register hook is called at boot time
179 * before main() and before interrupts are enabled.
180 * -Create: A function that is called when a task is created.
181 * This includes tasks that are created statically and those
182 * created dynamically using {@link #create} or {@link #construct}.
183 * For statically created tasks, create hook is called before main()
184 * and before interrupts are enabled. For dynamically created or
185 * constructed tasks, create hook is called in the same context the
186 * task is created or constructed in i.e. if a task is created in
187 * main(), the create hook is called in main context and if the task
188 * is created within another task, it is called in task context. The
189 * create hook is called outside of a Task_disable/enable block and
190 * before the task has been added to the ready list.
191 * -Ready: A function that is called when a task becomes ready to run.
192 * The ready hook is called in the context of the thread unblocking
193 * a task and therefore it can be called in Hwi, Swi or Task context.
194 * If a Swi or Hwi posts a semaphore that unblocks a task, the ready
195 * hook would be called in the Swi or Hwi's context. The ready hook is
196 * called from within a Task_disable/enable block with interrupts enabled.
197 * -Switch: A function that is called just before a task switch
198 * occurs. The 'prev' and 'next' task handles are passed to the switch
199 * hook. 'prev' is set to NULL for the initial task switch that occurs
200 * during SYS/BIOS startup. The switch hook is called from within a
201 * Task_disable/enable block with interrupts enabled, in the
202 * context of the task being switched from (ie: the `prev` task).
203 * -Exit: A function that is called when a task exits using {@link #exit}.
204 * It is called in the exiting task's context. The exit hook is passed
205 * the handle of the exiting task. The exit hook is called outside of a
206 * Task_disable/enable block and before the task has been removed from
207 * the kernel lists.
208 * -Delete: A function that is called when any task is deleted at
209 * run-time with {@link #delete}. The delete hook is called in idle task
210 * context if {@link #deleteTerminatedTasks} is set to true. Otherwise,
211 * it is called in the context of the task that is deleting another task.
212 * The delete hook is called outside of a Task_disable/enable block.
213 * @p
214 * Hook functions can only be configured statically.
215 *
216 * If you define more than one set of hook functions, all the functions
217 * of a particular type will be run when a Task triggers that type of
218 * hook.
219 *
220 * @a(Warning)
221 * Configuring ANY Task hook function will have the side effect of allowing
222 * up to two interrupt contexts beings saved on a task stack. Be careful
223 * to size your task stacks accordingly.
224 *
225 * @p(html)
226 * <B>Register Function</B>
227 * @p
228 *
229 * The Register function is provided to allow a hook set to store its
230 * hookset ID. This id can be passed to {@link #setHookContext} and
231 * {@link #getHookContext} to set or get hookset-specific context. The
232 * Register function must be specified if the hook implementation
233 * needs to use {@link #setHookContext} or {@link #getHookContext}.
234 * The registerFxn hook function is called during system initialization
235 * before interrupts have been enabled.
236 *
237 * @p(code)
238 * Void myRegisterFxn(Int id);
239 * @p
240 *
241 * @p(html)
242 * <B>Create and Delete Functions</B>
243 * @p
244 *
245 * The create and delete functions are called whenever a Task is created
246 * or deleted. They are called with interrupts enabled (unless called
247 * at boot time or from main()).
248 *
249 * @p(code)
250 * Void myCreateFxn(Task_Handle task, Error_Block *eb);
251 * @p
252 *
253 * @p(code)
254 * Void myDeleteFxn(Task_Handle task);
255 * @p
256 *
257 * @p(html)
258 * <B>Switch Function</B>
259 * @p
260 *
261 * If a switch function is specified, it is invoked just before the new task
262 * is switched to. The switch function is called with interrupts enabled.
263 *
264 * This function can be used to save/restore additional task context (for
265 * example, external hardware registers), to check for task stack overflow,
266 * to monitor the time used by each task, etc.
267 *
268 * @p(code)
269 * Void mySwitchFxn(Task_Handle prev, Task_Handle next);
270 * @p
271 *
272 * To properly handle the switch to the first task your switchFxn should
273 * check for "prev == NULL" before using prev:
274 *
275 * @p(code)
276 * Void mySwitchFxn(Task_Handle prev, Task_Handle next)
277 * {
278 * if (prev != NULL) {
279 * ...
280 * }
281 * ...
282 * }
283 * @p
284 *
285 * @p(html)
286 * <B>Ready Function</B>
287 * @p
288 *
289 * If a ready function is specified, it is invoked whenever a task is made
290 * ready to run. The ready function is called with interrupts enabled
291 * (unless called at boot time or from main()).
292 *
293 * @p(code)
294 * Void myReadyFxn(Task_Handle task);
295 * @p
296 *
297 * @p(html)
298 * <B>Exit Function</B>
299 * @p
300 *
301 * If an exit function is specified, it is invoked when a task exits (via
302 * call to Task_exit() or when a task returns from its' main function).
303 * The Exit Function is called with interrupts enabled.
304 *
305 * @p(code)
306 * Void myExitFxn(Task_Handle task);
307 * @p
308 *
309 * @p(html)
310 * <h3> Calling Context </h3>
311 * <table border="1" cellpadding="3">
312 * <colgroup span="1"></colgroup> <colgroup span="5" align="center">
313 * </colgroup>
314 *
315 * <tr><th> Function </th><th> Hwi </th><th> Swi </th>
316 * <th> Task </th><th> Main </th><th> Startup </th></tr>
317 * <!-- -->
318 * <tr><td> {@link #create} </td><td> N </td><td> N </td>
319 * <td> Y </td><td> Y </td><td> N </td></tr>
320 * <tr><td> {@link #disable} </td><td> Y </td><td> Y </td>
321 * <td> Y </td><td> Y </td><td> N </td></tr>
322 * <tr><td> {@link #exit} </td><td> N </td><td> N </td>
323 * <td> Y </td><td> N </td><td> N </td></tr>
324 * <tr><td> {@link #getIdleTask} </td><td> Y </td><td> Y </td>
325 * <td> Y </td><td> Y </td><td> N </td></tr>
326 * <tr><td> {@link #Params_init} </td><td> Y </td><td> Y </td>
327 * <td> Y </td><td> Y </td><td> Y </td></tr>
328 * <tr><td> {@link #restore} </td><td> Y </td><td> Y </td>
329 * <td> Y </td><td> Y </td><td> N </td></tr>
330 * <tr><td> {@link #self} </td><td> Y </td><td> Y </td>
331 * <td> Y </td><td> Y </td><td> N </td></tr>
332 * <tr><td> {@link #sleep} </td><td> N </td><td> N </td>
333 * <td> Y </td><td> N </td><td> N </td></tr>
334 * <tr><td> {@link #yield} </td><td> Y </td><td> Y </td>
335 * <td> Y </td><td> N </td><td> N </td></tr>
336 * <tr><td> {@link #construct} </td><td> N </td><td> N </td>
337 * <td> Y </td><td> Y </td><td> N </td></tr>
338 * <tr><td> {@link #delete} </td><td> N </td><td> N </td>
339 * <td> Y </td><td> Y </td><td> N </td></tr>
340 * <tr><td> {@link #destruct} </td><td> N </td><td> N </td>
341 * <td> Y </td><td> Y </td><td> N </td></tr>
342 * <tr><td> {@link #getEnv} </td><td> Y </td><td> Y </td>
343 * <td> Y </td><td> Y </td><td> N </td></tr>
344 * <tr><td> {@link #getHookContext} </td><td> Y </td><td> Y </td>
345 * <td> Y </td><td> Y </td><td> N </td></tr>
346 * <tr><td> {@link #getMode} </td><td> Y </td><td> Y </td>
347 * <td> Y </td><td> Y </td><td> N </td></tr>
348 * <tr><td> {@link #getPri} </td><td> Y </td><td> Y </td>
349 * <td> Y </td><td> Y </td><td> N </td></tr>
350 * <tr><td> {@link #getFunc} </td><td> Y </td><td> Y </td>
351 * <td> Y </td><td> Y </td><td> N </td></tr>
352 * <tr><td> {@link #setEnv} </td><td> Y </td><td> Y </td>
353 * <td> Y </td><td> Y </td><td> N </td></tr>
354 * <tr><td> {@link #setHookContext} </td><td> Y </td><td> Y </td>
355 * <td> Y </td><td> Y </td><td> N </td></tr>
356 * <tr><td> {@link #setPri} </td><td> Y </td><td> Y </td>
357 * <td> Y </td><td> N </td><td> N </td></tr>
358 * <tr><td> {@link #stat} </td><td> Y </td><td> Y </td>
359 * <td> Y </td><td> Y </td><td> N </td></tr>
360 * <tr><td colspan="6"> Definitions: <br />
361 * <ul>
362 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
363 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
364 * <li> <b>Task</b>: API is callable from a Task thread. </li>
365 * <li> <b>Main</b>: API is callable during any of these phases: </li>
366 * <ul>
367 * <li> In your module startup after this module is started
368 * (e.g. Task_Module_startupDone() returns TRUE). </li>
369 * <li> During xdc.runtime.Startup.lastFxns. </li>
370 * <li> During main().</li>
371 * <li> During BIOS.startupFxns.</li>
372 * </ul>
373 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
374 * <ul>
375 * <li> During xdc.runtime.Startup.firstFxns.</li>
376 * <li> In your module startup before this module is started
377 * (e.g. Task_Module_startupDone() returns FALSE).</li>
378 * </ul>
379 * </ul>
380 * </td></tr>
381 *
382 * </table>
383 * @p
384 */
385
386 @DirectCall
387 @ModuleStartup
388 @InstanceInitStatic
389 @InstanceFinalize
390 @InstanceInitError
391 @Template ("./Task.xdt") 392
393
394 module Task
395 {
396
397
398
399
400
401 /*! Task function type definition. */
402 typedef Void (*FuncPtr)(UArg, UArg);
403
404 /*! "All Task Blocked" function type definition. */
405 typedef Void (*AllBlockedFuncPtr)(Void);
406
407 /*! Check value computation function type definition. */
408 typedef UInt32 (*ModStateCheckValueFuncPtr)(Task.Module_State *);
409
410 /*! Data Integrity Check function type definition */
411 typedef Int (*ModStateCheckFuncPtr)(Task.Module_State *, UInt32);
412
413 /*! Check value computation function type definition. */
414 typedef UInt32 (*ObjectCheckValueFuncPtr)(Task.Handle);
415
416 /*! Task object data integrity check function type definition */
417 typedef Int (*ObjectCheckFuncPtr)(Task.Handle, UInt32);
418
419 /*!
420 * Task execution modes.
421 *
422 * These enumerations are the range of modes or states that
423 * a task can be in. A task's current mode can be gotten using
424 * {@link #stat}.
425 */
426 enum Mode {
427 Mode_RUNNING, /*! Task is currently executing. */
428 Mode_READY, /*! Task is scheduled for execution. */
429 Mode_BLOCKED, /*! Task is suspended from execution. */
430 Mode_TERMINATED, /*! Task is terminated from execution. */
431 Mode_INACTIVE /*! Task is on inactive task list */
432 };
433
434 /*!
435 * Task Status Buffer.
436 *
437 * Passed to and filled in by {@link #stat};
438 */
439 struct Stat {
440 Int priority; /*! Task priority. */
441 Ptr stack; /*! Task stack. */
442 SizeT stackSize; /*! Task stack size. */
443 IHeap.Handle stackHeap; /*! Heap used to alloc stack. */
444 Ptr env; /*! Global environment struct. */
445 Mode mode; /*! Task's current mode. */
446 Ptr sp; /*! Task's current stack pointer. */
447 SizeT used; /*! max # of words used on stack. */
448 };
449
450 /*!
451 * Task hook set type definition.
452 *
453 * Sets of hook functions can be specified for the Task module.
454 * See {@link #hookfunc Hook Functions} for details.
455 */
456 struct HookSet {
457 Void (*registerFxn)(Int);
458 Void (*createFxn)(Handle, Error.Block *);
459 Void (*readyFxn)(Handle);
460 Void (*switchFxn)(Handle, Handle);
461 Void (*exitFxn)(Handle);
462 Void (*deleteFxn)(Handle);
463 };
464
465 /*! "Don't care" task affinity */
466 const UInt AFFINITY_NONE = ~(0);
467
468 /*! @_nodoc */
469 metaonly struct BasicView {
470 String label;
471 Int priority;
472 String mode;
473 String fxn[];
474 UArg arg0;
475 UArg arg1;
476 SizeT stackSize;
477 Ptr stackBase;
478 String curCoreId;
479 String affinity;
480 }
481
482 /*! @_nodoc */
483 metaonly struct DetailedView {
484 String label;
485 Int priority;
486 String mode;
487 String fxn[];
488 UArg arg0;
489 UArg arg1;
490 String stackPeak;
491 SizeT stackSize;
492 Ptr stackBase;
493 String curCoreId;
494 String affinity;
495 String blockedOn;
496 }
497
498 /*! @_nodoc */
499 metaonly struct ModuleView {
500 String schedulerState;
501 String readyQMask[];
502 Bool workPending;
503 UInt numVitalTasks;
504 Ptr currentTask[];
505 String hwiStackPeak;
506 SizeT hwiStackSize;
507 Ptr hwiStackBase;
508 }
509
510 /*! @_nodoc (not used by view) */
511 metaonly struct CallStackView {
512 Int depth;
513 String decode;
514 }
515
516 /*! @_nodoc */
517 metaonly struct ReadyQView {
518 Ptr task;
519 Ptr next;
520 Ptr prev;
521 Ptr readyQ;
522 String label;
523 Int priority;
524 String mode;
525 String fxn[];
526 String curCoreId;
527 String affinity;
528 }
529
530 /*! @_nodoc */
531 @Facet
532 metaonly config ViewInfo.Instance rovViewInfo =
533 ViewInfo.create({
534 viewMap: [
535 ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic', structName: 'BasicView'}],
536 ['Detailed', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitDetailed', structName: 'DetailedView'}],
537 ['CallStacks', {type: ViewInfo.TREE, viewInitFxn: 'viewInitCallStack', structName: 'CallStackView'}],
538 ['ReadyQs', {type: ViewInfo.TREE_TABLE, viewInitFxn: 'viewInitReadyQs', structName: 'ReadyQView'}],
539 ['Module', {type: ViewInfo.MODULE, viewInitFxn: 'viewInitModule', structName: 'ModuleView'}],
540 ]
541 });
542
543
544
545
546
547 /*! Logged on every task switch */
548 config Log.Event LM_switch = {
549 mask: Diags.USER1 | Diags.USER2,
550 msg: "LM_switch: oldtsk: 0x%x, oldfunc: 0x%x, newtsk: 0x%x, newfunc: 0x%x"
551 };
552
553 /*! Logged on calls to Task_sleep */
554 config Log.Event LM_sleep = {
555 mask: Diags.USER1 | Diags.USER2,
556 msg: "LM_sleep: tsk: 0x%x, func: 0x%x, timeout: %d"
557 };
558
559 /*! Logged when a task is made ready to run (ie Semaphore_post()) */
560 config Log.Event LD_ready = {
561 mask: Diags.USER2,
562 msg: "LD_ready: tsk: 0x%x, func: 0x%x, pri: %d"
563 };
564
565 /*! Logged when a task is blocked (ie Semaphore_pend()) */
566 config Log.Event LD_block = {
567 mask: Diags.USER2,
568 msg: "LD_block: tsk: 0x%x, func: 0x%x"
569 };
570
571 /*! Logged on calls to Task_yield */
572 config Log.Event LM_yield = {
573 mask: Diags.USER1 | Diags.USER2,
574 msg: "LM_yield: tsk: 0x%x, func: 0x%x, currThread: %d"
575 };
576
577 /*! Logged on calls to Task_setPri */
578 config Log.Event LM_setPri = {
579 mask: Diags.USER1 | Diags.USER2,
580 msg: "LM_setPri: tsk: 0x%x, func: 0x%x, oldPri: %d, newPri %d"
581 };
582
583 /*!
584 * Logged when Task functions fall thru the bottom
585 * or when Task_exit() is explicitly called.
586 */
587 config Log.Event LD_exit = {
588 mask: Diags.USER2,
589 msg: "LD_exit: tsk: 0x%x, func: 0x%x"
590 };
591
592 /*! Logged on calls to Task_setAffinity */
593 config Log.Event LM_setAffinity = {
594 mask: Diags.USER1 | Diags.USER2,
595 msg: "LM_setAffinity: tsk: 0x%x, func: 0x%x, oldCore: %d, oldAffinity %d, newAffinity %d"
596 };
597
598 /*! Logged on every task schedule entry */
599 config Log.Event LM_schedule = {
600 mask: Diags.USER3,
601 msg: "LD_schedule: coreId: %d, workFlag: %d, curSetLocal: %d, curSetX: %d, curMaskLocal: %d"
602 };
603
604 /*! Logged when no scheduling work was found */
605 config Log.Event LM_noWork = {
606 mask: Diags.USER3,
607 msg: "LD_noWork: coreId: %d, curSetLocal: %d, curSetX: %d, curMaskLocal: %d"
608 };
609
610
611
612 /*!
613 * Error raised when a stack overflow (or corruption) is detected.
614 *
615 * This error is raised by kernel's stack checking function. This
616 * function checks the stacks before every task switch to make sure
617 * that reserved word at top of stack has not been modified.
618 *
619 * The stack checking logic is enabled by the {@link #initStackFlag} and
620 * {@link #checkStackFlag} configuration parameters. If both of these
621 * flags are set to true, the kernel will validate the stacks.
622 */
623 config Error.Id E_stackOverflow = {
624 msg: "E_stackOverflow: Task 0x%x stack overflow."
625 };
626
627 /*!
628 * Error raised when a task's stack pointer (SP) does not point
629 * somewhere within the task's stack.
630 *
631 * This error is raised by kernel's stack checking function. This
632 * function checks the SPs before every task switch to make sure
633 * they point within the task's stack.
634 *
635 * The stack checking logic is enabled by the {@link #initStackFlag} and
636 * {@link #checkStackFlag} configuration parameters. If both of these
637 * flags are set to true, the kernel will validate the stack pointers.
638 */
639 config Error.Id E_spOutOfBounds = {
640 msg: "E_spOutOfBounds: Task 0x%x stack error, SP = 0x%x."
641 };
642
643 config Error.Id E_deleteNotAllowed = {
644 msg: "E_deleteNotAllowed: Task 0x%x."
645 };
646
647 /*!
648 * Error raised when the check value of the Task module state does not
649 * match the stored check value (computed during startup). This indicates
650 * that the Task module state was corrupted.
651 */
652 config Error.Id E_moduleStateCheckFailed = {
653 msg: "E_moduleStateCheckFailed: Task module state data integrity check failed."
654 };
655
656 /*!
657 * Error raised when the check value of the Task object does not match
658 * the stored check value (computed during startup). This indicates
659 * that the Task object was corrupted.
660 */
661 config Error.Id E_objectCheckFailed = {
662 msg: "E_objectCheckFailed: Task 0x%x object data integrity check failed."
663 };
664
665
666
667 /*! Asserted in Task_create and Task_delete */
668 config Assert.Id A_badThreadType = {
669 msg: "A_badThreadType: Cannot create/delete a task from Hwi or Swi thread."
670 };
671
672 /*! Asserted in Task_delete */
673 config Assert.Id A_badTaskState = {
674 msg: "A_badTaskState: Can't delete a task in RUNNING state."
675 };
676
677 /*! Asserted in Task_delete */
678 config Assert.Id A_noPendElem = {
679 msg: "A_noPendElem: Not enough info to delete BLOCKED task."
680 };
681
682 /*! Asserted in Task_create */
683 config Assert.Id A_taskDisabled = {
684 msg: "A_taskDisabled: Cannot create a task when tasking is disabled."
685 };
686
687 /*! Asserted in Task_create */
688 config Assert.Id A_badPriority = {
689 msg: "A_badPriority: An invalid task priority was used."
690 };
691
692 /*! Asserted in Task_sleep */
693 config Assert.Id A_badTimeout = {
694 msg: "A_badTimeout: Can't sleep FOREVER."
695 };
696
697 /*! Asserted in Task_setAffinity */
698 config Assert.Id A_badAffinity = {
699 msg: "A_badAffinity: Invalid affinity."
700 };
701
702 /*! Asserted in Task_sleep */
703 config Assert.Id A_sleepTaskDisabled = {
704 msg: "A_sleepTaskDisabled: Cannot call Task_sleep() while the Task scheduler is disabled."
705 };
706
707 /*! Asserted in Task_getIdleTaskHandle */
708 config Assert.Id A_invalidCoreId = {
709 msg: "A_invalidCoreId: Cannot pass a non-zero CoreId in a non-SMP application."
710 };
711
712 /*!
713 * Number of Task priorities supported. Default is 16.
714 *
715 * The maximum number of priorities supported is
716 * target specific and depends on the number of
717 * bits in a UInt data type. For 6x and ARM devices
718 * the maximum number of priorities is therefore 32.
719 * For 28x, 55x, and MSP430 devices, the maximum number of
720 * priorities is 16.
721 */
722 config UInt numPriorities = 16;
723
724 /*!
725 * Default stack size (in MAUs) used for all tasks.
726 *
727 * Default is obtained from the family-specific TaskSupport module
728 * (e.g. {@link ti.sysbios.family.arm.m3.TaskSupport},
729 * {@link ti.sysbios.family.c62.TaskSupport}).
730 */
731 config SizeT defaultStackSize;
732
733 /*!
734 * Default memory section used for all statically created task stacks.
735 *
736 * The default stack section name is target/device specific.
737 * For C6x targets it is ".far:taskStackSection".
738 * For C28x targets it is ".taskStackSection".
739 * For GNU targets it is ".bss".
740 * For all other targets it is ".bss:taskStackSection".
741 *
742 * By default, all statically created task stacks are grouped together
743 * into the defaultStackSection and placed where ever
744 * the target specific defaultStackSection base section name
745 * (ie .bss, .far, .ebss) is placed.
746 *
747 * To place all task stacks into a different memory segment,
748 * add the following to your config script:
749 *
750 * @p(code)
751 * Program.sectMap[Task.defaultStackSection] = new Program.SectionSpec();
752 * Program.sectMap[Task.defaultStackSection].loadSegment =
753 * "yourMemorySegment";
754 * @p
755 *
756 * To group all task stacks into a different section AND place that
757 * section into a specific memory segment, add the following to your
758 * config script:
759 *
760 * @p(code)
761 * Task.defaultStackSection = ".yourSectionName";
762 * Program.sectMap[Task.defaultStackSection] = new Program.SectionSpec();
763 * Program.sectMap[Task.defaultStackSection].loadSegment =
764 * "yourMemorySegment";
765 * @p
766 *
767 * Where "yourSectionName" can be just about anything, and
768 * "yourMemorySegment"
769 * must be a memory segment defined for your board.
770 */
771 metaonly config String defaultStackSection;
772
773 /*!
774 * Default Mem heap used for all dynamically created task stacks.
775 *
776 * Default is null.
777 */
778 config IHeap.Handle defaultStackHeap;
779
780 /*!
781 * Default core affinity for newly created tasks.
782 *
783 * Default is Task_AFFINITY_NONE, meaning don't care.
784 */
785 metaonly config UInt defaultAffinity = AFFINITY_NONE;
786
787 /*!
788 * Create a task (of priority 0) to run the Idle functions in.
789 *
790 * When set to true, a task is created that continuously calls the
791 * {@link Idle#run Idle_run()} function, which, in turn calls each of
792 * the configured Idle functions.
793 *
794 * When set to false, no Idle Task is created and it is up to the
795 * user to call the Idle_run() function if the configured Idle
796 * functions need to be run. Or, by adding the following lines to
797 * the config script, the Idle functions will run whenever all
798 * tasks are blocked ({@link #allBlockedFunc Task.allBlockedFunc}):
799 *
800 * @p(code)
801 * Task.enableIdleTask = false;
802 * Task.allBlockedFunc = Idle.run;
803 * @p
804 *
805 * Default is true.
806 *
807 * @see #idleTaskStackSize
808 * @see #idleTaskStackSection
809 * @see #idleTaskVitalTaskFlag
810 * @see #allBlockedFunc
811 */
812 metaonly config Bool enableIdleTask = true;
813
814 /*!
815 * Reduce interrupt latency by enabling interrupts
816 * within the Task scheduler.
817 *
818 * By default, interrupts are disabled within certain critical
819 * sections of the task scheduler when switching to a different
820 * task thread. This default behavior guarantees that a task stack
821 * will only ever absorb ONE ISR context. Nested interrupts all run
822 * on the shared Hwi stack.
823 *
824 * While most users find this behavior desirable, the resulting
825 * impact on interrupt latency is too great for certain applications.
826 *
827 * By setting this parameter to 'true', the worst case interrupt latency
828 * imposed by the kernel will be reduced but will result in task stacks
829 * needing to be sized to accommodate one additional interrupt context.
830 *
831 * See sections 3.5.3 and 7.5 of the BIOS User's Guide for further
832 * discussions regarding task stack sizing.
833 *
834 * Also see {@link ti.sysbios.BIOS#logsEnabled BIOS.logsEnabled}
835 * and the discussion on Task hooks.
836 */
837 metaonly config Bool minimizeLatency = false;
838
839 /*!
840 * Idle task stack size in MAUs.
841 *
842 * Default is inherited from module config defaultStackSize.
843 */
844 metaonly config SizeT idleTaskStackSize;
845
846 /*!
847 * Idle task stack section
848 *
849 * Default is inherited from module config defaultStackSection;
850 */
851 metaonly config String idleTaskStackSection;
852
853 /*!
854 * Idle task's vitalTaskFlag.
855 * (see {@link #vitalTaskFlag}).
856 *
857 * Default is true.
858 */
859 metaonly config Bool idleTaskVitalTaskFlag = true;
860
861 /*!
862 * Function to call while all tasks are blocked.
863 *
864 * This function will be called repeatedly while no tasks are
865 * ready to run.
866 *
867 * Ordinarily (in applications that have tasks ready to run at startup),
868 * the function will run in the context of the last task to block.
869 *
870 * In an application where there are no tasks ready to run
871 * when BIOS_start() is called, the allBlockedFunc function is
872 * called within the BIOS_start() thread which runs on the system/ISR
873 * stack.
874 *
875 * By default, allBlockedFunc is initialized to point to an internal
876 * function that simply returns.
877 *
878 * By adding the following lines to the config script, the Idle
879 * functions will run whenever all tasks are blocked:
880 *
881 * @p(code)
882 * Task.enableIdleTask = false;
883 * Task.allBlockedFunc = Idle.run;
884 * @p
885 *
886 * @see #enableIdleTask
887 *
888 * @a(constraints)
889 * The configured allBlockedFunc is designed to be called repeatedly.
890 * It must return in order for the task scheduler to check if all
891 * tasks are STILL blocked and if not, run the highest priority task
892 * currently ready to run.
893 *
894 * The configured allBlockedFunc function is called with interrupts
895 * disabled. If your function must run with interrupts enabled,
896 * surround the body of your code with Hwi_enable()/Hwi_restore()
897 * function calls per the following example:
898 *
899 * @p(code)
900 * Void yourFunc() {
901 * UInt hwiKey;
902 *
903 * hwiKey = Hwi_enable();
904 *
905 * ... // your code here
906 *
907 * Hwi_restore(hwiKey);
908 * }
909 * @p
910 */
911 config AllBlockedFuncPtr allBlockedFunc = null;
912
913 /*!
914 * Initialize stack with known value for stack checking at runtime
915 * (see {@link #checkStackFlag}).
916 * If this flag is set to false, while the
917 * {@link ti.sysbios.hal.Hwi#checkStackFlag} is set to true, only the
918 * first byte of the stack is initialized.
919 *
920 * This is also useful for inspection of stack in debugger or core
921 * dump utilities.
922 * Default is true.
923 */
924 config Bool initStackFlag = true;
925
926 /*!
927 * Check 'from' and 'to' task stacks before task context switch.
928 *
929 * The check consists of testing the top of stack value against
930 * its initial value (see {@link #initStackFlag}). If it is no
931 * longer at this value, the assumption is that the task has
932 * overrun its stack. If the test fails, then the
933 * {@link #E_stackOverflow} error is raised.
934 *
935 * Default is true.
936 *
937 * To enable or disable full stack checking, you should set both this
938 * flag and the {@link ti.sysbios.hal.Hwi#checkStackFlag}.
939 *
940 * @a(Note)
941 * Enabling stack checking will add some interrupt latency because the
942 * checks are made within the Task scheduler while interrupts are
943 * disabled.
944 */
945 config Bool checkStackFlag = true;
946
947 /*!
948 * Automatically delete terminated tasks.
949 *
950 * If this feature is enabled, an Idle function is installed that
951 * deletes dynamically created Tasks that have terminated either
952 * by falling through their task function or by explicitly calling
953 * Task_exit().
954 *
955 * A list of terminated Tasks that were created dynmically is
956 * maintained internally. Each invocation of the installed Idle function
957 * deletes the first Task on this list. This one-at-a-time process
958 * continues until the list is empty.
959 *
960 * @a(Note)
961 * This feature is disabled by default.
962 *
963 * @a(WARNING)
964 * When this feature is enabled, an error will be raised if the user's
965 * application attempts to delete a terminated task. If a terminated task
966 * has already been automatically deleted and THEN the user's application
967 * attempts to delete it (ie: using a stale Task handle), the results are
968 * undefined and probably catastrophic!
969 *
970 */
971 config Bool deleteTerminatedTasks = false;
972
973 /*!
974 * Const array that holds the HookSet objects.
975 *
976 * See {@link #hookfunc Hook Functions} for details about HookSets.
977 */
978 config HookSet hooks[length] = [];
979
980 /*!
981 * ======== moduleStateCheckFxn ========
982 * Function called to perform module state data integrity check
983 *
984 * If {@link #moduleStateCheckFlag} is set to true, SYS/BIOS kernel
985 * will call this function each time Task_disable() function is called.
986 * SYS/BIOS provides a default implementation of this function that
987 * computes the check value for the static module state fields and
988 * compares the resulting check value against the stored value. In
989 * addition, the check function validates some of the pointers used
990 * by the Task scheduler. The application can install its own
991 * implementation of the module state check function.
992 *
993 * Here's an example module state check function:
994 *
995 * *.cfg
996 * @p(code)
997 * var Task = xdc.useModule('ti.sysbios.knl.Task');
998 *
999 * // Enable Task module state data integrity check
1000 * Task.moduleStateCheckFlag = true;
1001 *
1002 * // Install custom module state check function
1003 * Task.moduleStateCheckFxn = "&myCheckFunc";
1004 * @p
1005 *
1006 * *.c
1007 * @p(code)
1008 * #define ti_sysbios_knl_Task__internalaccess
1009 * #include <ti/sysbios/knl/Task.h>
1010 *
1011 * Int myCheckFunc(Task_Module_State *moduleState, UInt32 checkValue)
1012 * {
1013 * UInt32 newCheckValue;
1014 *
1015 * newCheckValue = Task_moduleStateCheckValueFxn(moduleState);
1016 * if (newCheckValue != checkValue) {
1017 * // Return '-1' to indicate data corruption. SYS/BIOS kernel
1018 * // will raise an error.
1019 * return (-1);
1020 * }
1021 *
1022 * return (0);
1023 * }
1024 * @p
1025 */
1026 config ModStateCheckFuncPtr moduleStateCheckFxn = Task.moduleStateCheck;
1027
1028 /*!
1029 * ======== moduleStateCheckValueFxn ========
1030 * Function called to compute module state check value
1031 *
1032 * If {@link #moduleStateCheckFlag} is set to true, SYS/BIOS kernel
1033 * will call this function during startup to compute the Task module
1034 * state's check value.
1035 *
1036 * SYS/BIOS provides a default implementation of this function that
1037 * computes a 32-bit checksum for the static module state fields (i.e.
1038 * module state fields that do not change during the lifetime of the
1039 * application). The application can install its own implementation
1040 * of this function.
1041 *
1042 * Here's an example module state check value computation function:
1043 *
1044 * *.cfg
1045 * @p(code)
1046 * var Task = xdc.useModule('ti.sysbios.knl.Task');
1047 *
1048 * // Enable Task module state data integrity check
1049 * Task.moduleStateCheckFlag = true;
1050 *
1051 * // Install custom module state check value function
1052 * Task.moduleStateCheckValueFxn = "&myCheckValueFunc";
1053 * @p
1054 *
1055 * *.c
1056 * @p(code)
1057 * #define ti_sysbios_knl_Task__internalaccess
1058 * #include <ti/sysbios/knl/Task.h>
1059 *
1060 * UInt32 myCheckValueFunc(Task_Module_State *moduleState)
1061 * {
1062 * UInt64 checksum;
1063 *
1064 * checksum = (uintptr_t)moduleState->readyQ +
1065 * (uintptr_t)moduleState->smpCurSet +
1066 * (uintptr_t)moduleState->smpCurMask +
1067 * (uintptr_t)moduleState->smpCurTask +
1068 * (uintptr_t)moduleState->smpReadyQ +
1069 * (uintptr_t)moduleState->idleTask +
1070 * (uintptr_t)moduleState->constructedTasks;
1071 * checksum = (checksum >> 32) + (checksum & 0xFFFFFFFF);
1072 * checksum = checksum + (checksum >> 32);
1073 *
1074 * return ((UInt32)(~checksum));
1075 * }
1076 * @p
1077 */
1078 config ModStateCheckValueFuncPtr moduleStateCheckValueFxn =
1079 Task.getModuleStateCheckValue;
1080
1081 /*!
1082 * ======== moduleStateCheckFlag ========
1083 * Perform a runtime data integrity check on the Task module state
1084 *
1085 * This configuration parameter determines whether a data integrity
1086 * check is performed on the Task module state in order to detect
1087 * data corruption.
1088 *
1089 * If this field is set to true, a check value of the static fields in
1090 * the Task module state (i.e. fields that do not change during the
1091 * lifetime of the application) is computed during startup. The
1092 * computed check value is stored for use by the Task module state check
1093 * function. The application can implement its own check value
1094 * computation function (see {@link #moduleStateCheckValueFxn}).
1095 * By default, SYS/BIOS installs a check value computation function that
1096 * computes a 32-bit checksum of the static fields in the Task module
1097 * state.
1098 *
1099 * The module state check function (see {@link #moduleStateCheckFxn})
1100 * is called from within the Task_disable() function. The application
1101 * can provide its own implementation of this function. By default,
1102 * SYS/BIOS installs a check function that computes the check value
1103 * for select module state fields and compares the resulting check
1104 * value against the stored value.
1105 *
1106 * If the module state check function returns a '-1' (i.e. check failed),
1107 * then the SYS/BIOS kernel will raise an error.
1108 */
1109 config Bool moduleStateCheckFlag = false;
1110
1111 /*!
1112 * ======== objectCheckFxn ========
1113 * Function called to perform Task object data integrity check
1114 *
1115 * If {@link #objectCheckFlag} is set to true, SYS/BIOS kernel
1116 * will call this function from within a Task switch hook and
1117 * each time a Task blocks or unblocks. SYS/BIOS provides a default
1118 * implementation of this function that computes the check value
1119 * for the static Task object fields and compares the resulting
1120 * check value against the stored value. The application can install
1121 * its own implementation of the object check function.
1122 *
1123 * Here's an example Task object check function:
1124 *
1125 * *.cfg
1126 * @p(code)
1127 * var Task = xdc.useModule('ti.sysbios.knl.Task');
1128 *
1129 * // Enable Task object data integrity check
1130 * Task.objectCheckFlag = true;
1131 *
1132 * // Install custom Task object check function
1133 * Task.objectCheckFxn = "&myCheckFunc";
1134 * @p
1135 *
1136 * *.c
1137 * @p(code)
1138 * #define ti_sysbios_knl_Task__internalaccess
1139 * #include <ti/sysbios/knl/Task.h>
1140 *
1141 * Int myCheckFunc(Task_Handle handle, UInt32 checkValue)
1142 * {
1143 * UInt32 newCheckValue;
1144 *
1145 * newCheckValue = Task_objectCheckValueFxn(handle);
1146 * if (newCheckValue != checkValue) {
1147 * // Return '-1' to indicate data corruption. SYS/BIOS kernel
1148 * // will raise an error.
1149 * return (-1);
1150 * }
1151 *
1152 * return (0);
1153 * }
1154 * @p
1155 */
1156 config ObjectCheckFuncPtr objectCheckFxn = Task.objectCheck;
1157
1158 /*!
1159 * ======== objectCheckValueFxn ========
1160 * Function called to compute Task object check value
1161 *
1162 * If {@link #objectCheckFlag} is set to true, SYS/BIOS kernel
1163 * will call this function to compute the Task object's check value
1164 * each time a Task is created.
1165 *
1166 * SYS/BIOS provides a default implementation of this function that
1167 * computes a 32-bit checksum for the static Task object fields (i.e.
1168 * Task object fields that do not change during the lifetime of the
1169 * Task). The application can install its own implementation of this
1170 * function.
1171 *
1172 * Here's an example Task object check value computation function:
1173 *
1174 * *.cfg
1175 * @p(code)
1176 * var Task = xdc.useModule('ti.sysbios.knl.Task');
1177 *
1178 * // Enable Task object data integrity check
1179 * Task.objectCheckFlag = true;
1180 *
1181 * // Install custom Task object check value function
1182 * Task.objectCheckValueFxn = "&myCheckValueFunc";
1183 * @p
1184 *
1185 * *.c
1186 * @p(code)
1187 * #define ti_sysbios_knl_Task__internalaccess
1188 * #include <ti/sysbios/knl/Task.h>
1189 *
1190 * UInt32 myCheckValueFunc(Task_Handle taskHandle)
1191 * {
1192 * UInt64 checksum;
1193 *
1194 * checksum = taskHandle->stackSize +
1195 * (uintptr_t)taskHandle->stack +
1196 * (uintptr_t)taskHandle->stackHeap +
1197 * #if defined(__IAR_SYSTEMS_ICC__)
1198 * (UInt64)taskHandle->fxn +
1199 * #else
1200 * (uintptr_t)taskHandle->fxn +
1201 * #endif
1202 * taskHandle->arg0 +
1203 * taskHandle->arg1 +
1204 * (uintptr_t)taskHandle->hookEnv +
1205 * taskHandle->vitalTaskFlag;
1206 * checksum = (checksum >> 32) + (checksum & 0xFFFFFFFF);
1207 * checksum = checksum + (checksum >> 32);
1208 *
1209 * return ((UInt32)(~checksum));
1210 * }
1211 * @p
1212 */
1213 config ObjectCheckValueFuncPtr objectCheckValueFxn =
1214 Task.getObjectCheckValue;
1215
1216 /*!
1217 * ======== objectCheckFlag ========
1218 * Perform a runtime data integrity check on each Task object
1219 *
1220 * This configuration parameter determines whether a data integrity
1221 * check is performed on each Task object in the system in order to detect
1222 * data corruption.
1223 *
1224 * If this field is set to true, a check value of the static fields in
1225 * the Task object (i.e. fields that do not change during the lifetime
1226 * of the Task) is computed when the Task is created. The computed check
1227 * value is stored for use by the Task object check function. The
1228 * application can implement its own check value computation function
1229 * (see {@link #objectCheckValueFxn}). By default, SYS/BIOS installs a
1230 * check value computation function that computes a 32-bit checksum of
1231 * the static fields in the Task object.
1232 *
1233 * The Task object check function (see {@link #objectCheckFxn})
1234 * is called from within a Task switch hook if stack checking
1235 * (see {@link #checkStackFlag}) is enabled. It is also called when
1236 * a task blocks or unblocks. The application can provide its own
1237 * implementation of this function. By default, SYS/BIOS installs a
1238 * check function that computes the check value for select Task
1239 * object fields and compares the resulting check value against the
1240 * stored value.
1241 *
1242 * If the Task object check function returns a '-1' (i.e. check failed),
1243 * then the SYS/BIOS kernel will raise an error.
1244 */
1245 config Bool objectCheckFlag = false;
1246
1247
1248
1249 /*!
1250 * ======== addHookSet ========
1251 * addHookSet is used in a config file to add a hook set.
1252 *
1253 * Configures a set of hook functions for the
1254 * Task module. Each set contains these hook functions:
1255 *
1256 * @p(blist)
1257 * -Register: A function called before any statically created tasks
1258 * are initialized at runtime. The register hook is called at boot time
1259 * before main() and before interrupts are enabled.
1260 * -Create: A function that is called when a task is created.
1261 * This includes tasks that are created statically and those
1262 * created dynamically using {@link #create} or {@link #construct}.
1263 * The create hook is called outside of a Task_disable/enable block and
1264 * before the task has been added to the ready list.
1265 * -Ready: A function that is called when a task becomes ready to run.
1266 * The ready hook is called from within a Task_disable/enable block with
1267 * interrupts enabled.
1268 * -Switch: A function that is called just before a task switch
1269 * occurs. The 'prev' and 'next' task handles are passed to the Switch
1270 * hook. 'prev' is set to NULL for the initial task switch that occurs
1271 * during SYS/BIOS startup. The Switch hook is called from within a
1272 * Task_disable/enable block with interrupts enabled.
1273 * -Exit: A function that is called when a task exits using
1274 * {@link #exit}. The exit hook is passed the handle of the exiting
1275 * task. The exit hook is called outside of a Task_disable/enable block
1276 * and before the task has been removed from the kernel lists.
1277 * -Delete: A function that is called when any task is deleted at
1278 * run-time with {@link #delete}. The delete hook is called outside
1279 * of a Task_disable/enable block.
1280 * @p
1281 * Hook functions can only be configured statically.
1282 *
1283 * See {@link #hookfunc Hook Functions} for more details.
1284 *
1285 * HookSet structure elements may be omitted, in which case those
1286 * elements will not exist.
1287 *
1288 * For example, the following configuration code defines a HookSet:
1289 *
1290 * @p(code)
1291 * // Hook Set 1
1292 * Task.addHookSet({
1293 * registerFxn: '&myRegister1',
1294 * createFxn: '&myCreate1',
1295 * readyFxn: '&myReady1',
1296 * switchFxn: '&mySwitch1',
1297 * exitFxn: '&myExit1',
1298 * deleteFxn: '&myDelete1'
1299 * });
1300 * @p
1301 *
1302 * @param(hook) structure of type HookSet
1303 */
1304 metaonly Void addHookSet(HookSet hook);
1305
1306 /*!
1307 * @_nodoc
1308 * ======== Task_startup ========
1309 * Start the task scheduler.
1310 *
1311 * Task_startup signals the end of boot operations, enables
1312 * the Task scheduler and schedules the highest priority ready
1313 * task for execution.
1314 *
1315 * Task_startup is called by BIOS_start() after Hwi_enable()
1316 * and Swi_enable(). There is no return from this function as the
1317 * execution thread is handed to the highest priority ready task.
1318 */
1319 Void startup();
1320
1321 /*!
1322 * ======== Task_enabled ========
1323 * Returns TRUE if the Task scheduler is enabled
1324 *
1325 * @_nodoc
1326 */
1327 Bool enabled();
1328
1329 /*!
1330 * @_nodoc
1331 * ======== unlockSched ========
1332 * Force a Task scheduler unlock. Used by Core_atExit() & Core_hwiFunc()
1333 * to unlock Task scheduler before exiting.
1334 *
1335 * This function should only be called after a Hwi_disable() has entered
1336 * the Inter-core gate and disabled interrupts locally.
1337 */
1338 Void unlockSched();
1339
1340 /*!
1341 * ======== Task_disable ========
1342 * Disable the task scheduler.
1343 *
1344 * {@link #disable} and {@link #restore} control Task scheduling.
1345 * {@link #disable} disables all other Tasks from running until
1346 * {@link #restore} is called. Hardware and Software interrupts
1347 * can still run.
1348 *
1349 * {@link #disable} and {@link #restore} allow you to ensure that
1350 * statements
1351 * that must be performed together during critical processing are not
1352 * preempted by other Tasks.
1353 *
1354 * The value of the key returned is opaque to applications and is meant
1355 * to be passed to Task_restore().
1356 *
1357 * In the following example, the critical section is
1358 * not preempted by any Tasks.
1359 *
1360 * @p(code)
1361 * key = Task_disable();
1362 * `critical section`
1363 * Task_restore(key);
1364 * @p
1365 *
1366 * You can also use {@link #disable} and {@link #restore} to
1367 * create several Tasks and allow them to be invoked in
1368 * priority order.
1369 *
1370 * {@link #disable} calls can be nested.
1371 *
1372 * @b(returns) key for use with {@link #restore}
1373 *
1374 * @a(constraints)
1375 * Do not call any function that can cause the current task to block
1376 * within a {@link #disable}/{@link #restore} block. For example,
1377 * {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend}
1378 * (if timeout is non-zero),
1379 * {@link #sleep}, {@link #yield}, and Memory_alloc can all
1380 * cause blocking.
1381 */
1382 UInt disable();
1383
1384 /*!
1385 * @_nodoc
1386 * ======== enable ========
1387 * Enable the task scheduler.
1388 *
1389 * {@link #enable} unconditionally enables the Task scheduler and
1390 * schedules the highest priority ready task for execution.
1391 *
1392 * This function is called by {@link #startup} (which is called by
1393 * {@link ti.sysbios.BIOS#start BIOS_start}) to begin multi-tasking
1394 * operations.
1395 */
1396 Void enable();
1397
1398 /*!
1399 * ======== restore ========
1400 * Restore Task scheduling state.
1401 *
1402 * {@link #disable} and {@link #restore} control Task scheduling
1403 * {@link #disable} disables all other Tasks from running until
1404 * {@link #restore} is called. Hardware and Software interrupts
1405 * can still run.
1406 *
1407 * {@link #disable} and {@link #restore} allow you to ensure that
1408 * statements
1409 * that must be performed together during critical processing are not
1410 * preempted.
1411
1412 * In the following example, the critical section is not preempted
1413 * by any Tasks.
1414 *
1415 * @p(code)
1416 * key = Task_disable();
1417 * `critical section`
1418 * Task_restore(key);
1419 * @p
1420 *
1421 * You can also use {@link #disable} and {@link #restore} to create
1422 * several Tasks and allow them to be performed in priority order.
1423 *
1424 * {@link #disable} calls can be nested.
1425 *
1426 * {@link #restore} returns with interrupts enabled if the key unlocks
1427 * the scheduler
1428 *
1429 * @param(key) key to restore previous Task scheduler state
1430 *
1431 * @a(constraints)
1432 * Do not call any function that can cause the current task to block
1433 * within a {@link #disable}/{@link #restore} block. For example,
1434 * {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()}
1435 * (if timeout is non-zero),
1436 * {@link #sleep}, {@link #yield}, and Memory_alloc can all
1437 * cause blocking.
1438 *
1439 * {@link #restore} internally calls Hwi_enable() if the key passed
1440 * to it results in the unlocking of the Task scheduler (ie if this
1441 * is root Task_disable/Task_restore pair).
1442 */
1443 Void restore(UInt key);
1444
1445 /*!
1446 * @_nodoc
1447 * ======== restoreHwi ========
1448 * Restore Task scheduling state.
1449 * Used by dispatcher. Does not re-enable Ints.
1450 */
1451 Void restoreHwi(UInt key);
1452
1453 /*!
1454 * ======== self ========
1455 * Returns a handle to the currently executing Task object.
1456 *
1457 * Task_self returns the object handle for the currently executing task.
1458 * This function is useful when inspecting the object or when the current
1459 * task changes its own priority through {@link #setPri}.
1460 *
1461 * No task switch occurs when calling Task_self.
1462 *
1463 * Task_self will return NULL until Tasking is initiated at the end of
1464 * BIOS_start().
1465 *
1466 * @b(returns) address of currently executing task object
1467 */
1468 Handle self();
1469
1470 /*!
1471 * ======== selfMacro ========
1472 * Returns a handle to the currently executing Task object.
1473 *
1474 * Task_selfMacro is identical to {@link #self} but is implemented as
1475 * and inline macro.
1476 *
1477 * @b(returns) address of currently executing task object
1478 */
1479 @Macro
1480 Handle selfMacro();
1481
1482 /*!
1483 * @_nodoc
1484 * ======== checkStacks ========
1485 * Check for stack overflow.
1486 *
1487 * This function is usually called by the {@link #HookSet} switchFxn to
1488 * make sure task stacks are valid before performing the context
1489 * switch.
1490 *
1491 * If a stack overflow is detected on either the oldTask or the
1492 * newTask, a {@link #E_stackOverflow} Error is raised and the system
1493 * exited.
1494 *
1495 * In order to work properly, {@link #checkStacks} requires that the
1496 * {@link #initStackFlag} set to true, which it is by default.
1497 *
1498 * You can call {@link #checkStacks} directly from your application.
1499 * For example, you can check the current task's stack integrity
1500 * at any time with a call like the following:
1501 *
1502 * @p(code)
1503 * Task_checkStacks(Task_self(), Task_self());
1504 * @p
1505 *
1506 * @param(oldTask) leaving Task Object Ptr
1507 * @param(newTask) entering Task Object Ptr
1508 */
1509 Void checkStacks(Handle oldTask, Handle newTask);
1510
1511 /*!
1512 * ======== exit ========
1513 * Terminate execution of the current task.
1514 *
1515 * Task_exit terminates execution of the current task, changing its mode
1516 * from {@link #Mode_RUNNING} to {@link #Mode_TERMINATED}. If all tasks
1517 * have been terminated, or if all remaining tasks have their
1518 * vitalTaskFlag attribute set to FALSE, then SYS/BIOS terminates the
1519 * program as a whole by calling the function System_exit with a status
1520 * code of 0.
1521 *
1522 * Task_exit is automatically called whenever a task returns from its
1523 * top-level function.
1524 *
1525 * Exit Hooks (see exitFxn in {@link #HookSet}) can be used to provide
1526 * functions that run whenever a task is terminated. The exitFxn Hooks
1527 * are called before the task has been blocked and marked
1528 * {@link #Mode_TERMINATED}.
1529 * See {@link #hookfunc Hook Functions} for more information.
1530 *
1531 * Any SYS/BIOS function can be called from an Exit Hook function.
1532 *
1533 * Calling {@link #self} within an Exit function returns the task
1534 * being exited. Your Exit function declaration should be similar to
1535 * the following:
1536 * @p(code)
1537 * Void myExitFxn(Void);
1538 * @p
1539 *
1540 * A task switch occurs when calling Task_exit unless the program as a
1541 * whole is terminated
1542 *
1543 * @a(constraints)
1544 * Task_exit cannot be called from a Swi or Hwi.
1545 *
1546 * Task_exit cannot be called from the program's main() function.
1547 */
1548 Void exit();
1549
1550 /*!
1551 * ======== sleep ========
1552 * Delay execution of the current task.
1553 *
1554 * Task_sleep changes the current task's mode from {@link #Mode_RUNNING}
1555 * to {@link #Mode_BLOCKED}, and delays its execution for nticks
1556 * increments of the {@link Clock system clock}. The actual time
1557 * delayed can be up to 1 system clock tick less than nticks due to
1558 * granularity in system timekeeping and the time elapsed per
1559 * tick is determined by {@link Clock#tickPeriod Clock_tickPeriod}.
1560 *
1561 * After the specified period of time has elapsed, the task reverts to
1562 * the {@link #Mode_READY} mode and is scheduled for execution.
1563 *
1564 * A task switch always occurs when calling Task_sleep if nticks > 0.
1565 *
1566 * @param(nticks) number of system clock ticks to sleep
1567 *
1568 * @a(constraints)
1569 * Task_sleep cannot be called from a Swi or Hwi, or within a
1570 * {@link #disable} / {@link #restore} block.
1571 *
1572 * Task_sleep cannot be called from the program's main() function.
1573 *
1574 * Task_sleep should not be called from within an Idle function. Doing
1575 * so prevents analysis tools from gathering run-time information.
1576 *
1577 * nticks cannot be {@link ti.sysbios.BIOS#WAIT_FOREVER BIOS_WAIT_FOREVER}.
1578 */
1579 Void sleep(UInt32 nticks);
1580
1581 /*!
1582 * ======== yield ========
1583 * Yield processor to equal priority task.
1584 *
1585 * Task_yield yields the processor to another task of equal priority.
1586 *
1587 * A task switch occurs when you call Task_yield if there is an equal
1588 * priority task ready to run.
1589 *
1590 * Tasks of higher priority preempt the currently running task without
1591 * the need for a call to Task_yield. If only lower-priority tasks are
1592 * ready to run when you call Task_yield, the current task continues to
1593 * run. Control does not pass to a lower-priority task.
1594 *
1595 * @a(constraints)
1596 * When called within an Hwi, the code sequence calling Task_yield
1597 * must be invoked by the Hwi dispatcher.
1598 *
1599 * Task_yield cannot be called from the program's main() function.
1600 */
1601 Void yield();
1602
1603 /*!
1604 * ======== getIdleTask ========
1605 * returns a handle to the idle task object (for core 0)
1606 */
1607 Handle getIdleTask();
1608
1609 /*!
1610 * ======== getIdleTaskHandle ========
1611 * returns a handle to the idle task object for the specified coreId
1612 * (should be used only in applications built with
1613 * {@link ti.sysbios.BIOS#smpEnabled} set to true)
1614 *
1615 * @a(Note)
1616 * If this function is called in a non-SMP application, coreId should
1617 * always be 0.
1618 */
1619 Handle getIdleTaskHandle(UInt coreId);
1620
1621 /*!
1622 * @_nodoc
1623 * ======== startCore ========
1624 * begin tasking on a core
1625 */
1626 Void startCore(UInt coreId);
1627
1628 /*!
1629 * ======== getNickName ========
1630 *
1631 */
1632 metaonly String getNickName(Any tskView);
1633
1634 instance:
1635
1636 /*!
1637 * ======== create ========
1638 * Create a Task.
1639 *
1640 * Task_create creates a new task object. If successful, Task_create
1641 * returns the handle of the new task object. If unsuccessful,
1642 * Task_create returns NULL unless it aborts.
1643 *
1644 * The fxn parameter uses the {@link #FuncPtr} type to pass a pointer to
1645 * the function the Task object should run. For example, if myFxn is a
1646 * function in your program, your C code can create a Task object
1647 * to call that
1648 * function as follows:
1649 *
1650 * @p(code)
1651 * Task_Params taskParams;
1652 *
1653 * // Create task with priority 15
1654 * Task_Params_init(&taskParams);
1655 * taskParams.stackSize = 512;
1656 * taskParams.priority = 15;
1657 * Task_create((Task_FuncPtr)myFxn, &taskParams, &eb);
1658 * @p
1659 *
1660 * The following statements statically create a task in the
1661 * configuration file:
1662 *
1663 * @p(code)
1664 * var params = new Task.Params;
1665 * params.instance.name = "tsk0";
1666 * params.arg0 = 1;
1667 * params.arg1 = 2;
1668 * params.priority = 1;
1669 * Task.create('&tsk0_func', params);
1670 * @p
1671 *
1672 * If NULL is passed instead of a pointer to an actual Task_Params
1673 * struct, a
1674 * default set of parameters is used. The "eb" is an error block that
1675 * you can use
1676 * to handle errors that may occur during Task object creation.
1677 *
1678 * The newly created task is placed in {@link #Mode_READY} mode, and is
1679 * scheduled to begin concurrent execution of the following function
1680 * call:
1681 *
1682 * @p(code)
1683 * (*fxn)(arg1, arg2);
1684 * @p
1685 *
1686 * As a result of being made ready to run, the task runs any
1687 * application-wide Ready functions that have been specified.
1688 *
1689 * Task_exit is automatically called if and when the task returns
1690 * from fxn.
1691 *
1692 * @p(html)
1693 * <B>Create Hook Functions</B>
1694 * @p
1695 *
1696 * You can specify application-wide Create hook functions in your config
1697 * file that run whenever a task is created. This includes tasks that
1698 * are created statically and those created dynamically using
1699 * Task_create.
1700 *
1701 * For Task objects created statically, Create functions are called
1702 * during the Task module initialization phase of the program startup
1703 * process prior to main().
1704 *
1705 * For Task objects created dynamically, Create functions
1706 * are called after the task handle has been initialized but before the
1707 * task has been placed on its ready queue.
1708 *
1709 * Any SYS/BIOS function can be called from Create functions.
1710 * SYS/BIOS passes the task handle of the task being created to each of
1711 * the Create functions.
1712 *
1713 * All Create function declarations should be similar to this:
1714 * @p(code)
1715 * Void myCreateFxn(Task_Handle task);
1716 * @p
1717 *
1718 * @param(fxn) Task Function
1719 *
1720 * @a(constraints)
1721 * @p(blist)
1722 * - The fxn parameter and the name attribute cannot be NULL.
1723 * - The priority attribute must be less than or equal to
1724 * ({@link #numPriorities} - 1) and greater than or equal to one (1)
1725 * (priority 0 is owned by the Idle task).
1726 * - The priority can be set to -1 for tasks that will not execute
1727 * until another task changes the priority to a positive value.
1728 * - The stackHeap attribute must identify a valid memory Heap.
1729 * @p
1730 */
1731 create(FuncPtr fxn);
1732
1733
1734
1735 /*! Task function argument. Default is 0 */
1736 config UArg arg0 = 0;
1737
1738 /*! Task function argument. Default is 0 */
1739 config UArg arg1 = 0;
1740
1741 /*!
1742 * Task priority (0 to Task.numPriorities-1, or -1).
1743 * Default is 1.
1744 */
1745 config Int priority = 1;
1746
1747 /*!
1748 * Task stack pointer. Default = null.
1749 *
1750 * Null indicates that the stack is to be allocated by create().
1751 *
1752 * @a(Static Configuration Usage Warning)
1753 * This parameter can only be assigned a non-null value
1754 * during runtime Task creates or constructs.
1755 *
1756 * Static configuration of the 'stack' parameter is not supported.
1757 *
1758 * Note that if {@link ti.sysbios.BIOS#runtimeCreatesEnabled
1759 * BIOS.runtimeCreatesEnabled} is set to false, then the user is required
1760 * to provide the stack buffer when constructing the Task object.
1761 * If 'stack' is not provided, then Task_construct() will fail.
1762 */
1763 config Ptr stack = null;
1764
1765 /*!
1766 * Task stack size in MAUs.
1767 *
1768 * The default value of 0 means that the module config
1769 * {@link #defaultStackSize} is used.
1770 */
1771 config SizeT stackSize = 0;
1772
1773 /*!
1774 * Mem section used for statically created task stacks.
1775 *
1776 * Default is inherited from module config defaultStackSection.
1777 */
1778 metaonly config String stackSection;
1779
1780 /*!
1781 * Mem heap used for dynamically created task stack.
1782 *
1783 * The default value of NULL means that the module config
1784 * {@link #defaultStackHeap} is used.
1785 */
1786 config IHeap.Handle stackHeap = null;
1787
1788 /*! Environment data struct. */
1789 config Ptr env = null;
1790
1791 /*!
1792 * Exit system immediately when the last task with this
1793 * flag set to TRUE has terminated.
1794 *
1795 * Default is true.
1796 */
1797 config Bool vitalTaskFlag = true;
1798
1799 /*!
1800 * The core which this task is to run on. Default is Task_AFFINITY_NONE
1801 *
1802 * If there is a compelling reason for a task to be pinned to a
1803 * particular core, then setting 'affinity' to the corresponding core
1804 * id will force the task to only be run on that core.
1805 *
1806 * The default affinity is inherited from {@link #defaultAffinity
1807 * Task.defaultAffinity}
1808 * which in turn defaults to {@link #AFFINITY_NONE Task_AFFINITY_NONE},
1809 * which means the task can be run on either core.
1810 *
1811 * Furthermore, Task_AFFINITY_NONE implies that the task can be moved
1812 * from core to core as deemed necessary by the Task scheduler in order
1813 * to keep the two highest priority ready tasks running simultaneously.
1814 */
1815 config UInt affinity;
1816
1817
1818
1819 /*!
1820 * @_nodoc
1821 * ======== getArg0 ========
1822 * Returns arg0 passed via params to create.
1823 *
1824 * @b(returns) task's arg0
1825 */
1826 UArg getArg0();
1827
1828 /*!
1829 * @_nodoc
1830 * ======== getArg1 ========
1831 * Returns arg1 passed via params to create.
1832 *
1833 * @b(returns) task's arg1
1834 */
1835 UArg getArg1();
1836
1837 /*!
1838 * ======== getEnv ========
1839 * Get task environment pointer.
1840 *
1841 * Task_getEnv returns the environment pointer of the specified task. The
1842 * environment pointer references an arbitrary application-defined data
1843 * structure.
1844 *
1845 * If your program uses multiple hook sets, {@link #getHookContext}
1846 * allows you to get environment pointers you have set for a particular
1847 * hook set and Task object combination.
1848 *
1849 * @b(returns) task environment pointer
1850 */
1851 Ptr getEnv();
1852
1853 /*!
1854 * ======== getFunc ========
1855 * Get Task function and arguments
1856 *
1857 * If either arg0 or arg1 is NULL, then the corresponding argument is not
1858 * returned.
1859 *
1860 * @param(arg0) pointer for returning Task's first function argument
1861 * @param(arg1) pointer for returning Task's second function argument
1862 *
1863 * @b(returns) Task function
1864 */
1865 FuncPtr getFunc(UArg *arg0, UArg *arg1);
1866
1867 /*!
1868 * ======== getHookContext ========
1869 * Get hook set's context for a task.
1870 *
1871 * For example, this C code gets the HookContext, prints it,
1872 * and sets a new value for the HookContext.
1873 *
1874 * @p(code)
1875 * Ptr pEnv;
1876 * Task_Handle myTask;
1877 * Int myHookSetId1;
1878 *
1879 * pEnv = Task_getHookContext(task, myHookSetId1);
1880 *
1881 * System_printf("myEnd1: pEnv = 0x%lx, time = %ld\n",
1882 * (ULong)pEnv, (ULong)Timestamp_get32());
1883 *
1884 * Task_setHookContext(task, myHookSetId1, (Ptr)0xc0de1);
1885 * @p
1886 *
1887 * See {@link #hookfunc Hook Functions} for more details.
1888 *
1889 * @param(id) hook set ID
1890 * @b(returns) hook set context for task
1891 */
1892 Ptr getHookContext(Int id);
1893
1894 /*!
1895 * ======== getPri ========
1896 * Get task priority.
1897 *
1898 * Task_getPri returns the priority of the referenced task.
1899 *
1900 * @b(returns) task priority
1901 */
1902 Int getPri();
1903
1904 /*!
1905 * @_nodoc
1906 * ======== setArg0 ========
1907 * Set arg0 (used primarily for legacy support)
1908 */
1909 Void setArg0(UArg arg);
1910
1911 /*!
1912 * @_nodoc
1913 * ======== setArg1 ========
1914 * Set arg1 (used primarily for legacy support)
1915 */
1916 Void setArg1(UArg arg);
1917
1918 /*!
1919 * ======== setEnv ========
1920 * Set task environment.
1921 *
1922 * Task_setEnv sets the task environment pointer to env. The
1923 * environment pointer references an arbitrary application-defined
1924 * data structure.
1925 *
1926 * If your program uses multiple hook sets, {@link #setHookContext}
1927 * allows you to set environment pointers for any
1928 * hook set and Task object combination.
1929 *
1930 * @param(env) task environment pointer
1931 */
1932 Void setEnv(Ptr env);
1933
1934 /*!
1935 * ======== setHookContext ========
1936 * Set hook instance's context for a task.
1937 *
1938 * For example, this C code gets the HookContext, prints it,
1939 * and sets a new value for the HookContext.
1940 *
1941 * @p(code)
1942 * Ptr pEnv;
1943 * Task_Handle myTask;
1944 * Int myHookSetId1;
1945 *
1946 * pEnv = Task_getHookContext(task, myHookSetId1);
1947 *
1948 * System_printf("myEnd1: pEnv = 0x%lx, time = %ld\n",
1949 * (ULong)pEnv, (ULong)Timestamp_get32());
1950 *
1951 * Task_setHookContext(task, myHookSetId1, (Ptr)0xc0de1);
1952 * @p
1953 *
1954 * See {@link #hookfunc Hook Functions} for more details.
1955 *
1956 * @param(id) hook set ID
1957 * @param(hookContext) value to write to context
1958 */
1959 Void setHookContext(Int id, Ptr hookContext);
1960
1961 /*!
1962 * ======== setPri ========
1963 * Set a task's priority
1964 *
1965 * Task_setpri sets the execution priority of task to newpri, and returns
1966 * that task's old priority value. Raising or lowering a task's priority
1967 * does not necessarily force preemption and re-scheduling of the caller:
1968 * tasks in the {@link #Mode_BLOCKED} mode remain suspended despite a
1969 * change in priority; and tasks in the {@link #Mode_READY} mode gain
1970 * control only if their new priority is greater than that of the
1971 * currently executing task.
1972 *
1973 * newpri should be set to a value greater than or equal to 1 and
1974 * less than or equal to ({@link #numPriorities} - 1). newpri can also
1975 * be set to -1 which puts the the task into the INACTIVE state and the
1976 * task will not run until its priority is raised at a later time by
1977 * another task. Priority 0 is reserved for the idle task.
1978 * If newpri equals ({@link #numPriorities} - 1), execution of the task
1979 * effectively locks out all other program activity, except for the
1980 * handling of interrupts.
1981 *
1982 * The current task can change its own priority (and possibly preempt its
1983 * execution) by passing the output of {@link #self} as the value of the
1984 * task parameter.
1985 *
1986 * A context switch occurs when calling Task_setpri if a currently
1987 * running task priority is set lower than the priority of another
1988 * currently ready task, or if another ready task is made to have a
1989 * higher priority than the currently running task.
1990 *
1991 * Task_setpri can be used for mutual exclusion.
1992 *
1993 * If a task's new priority is different than its previous priority,
1994 * then its relative placement in its new ready task priority
1995 * queue can be different than the one it was removed from. This can
1996 * effect the relative order in which it becomes the running task.
1997 *
1998 * The effected task is placed at the head of its new priority queue
1999 * if it is the currently running task. Otherwise it is placed at
2000 * at the end of its new task priority queue.
2001 *
2002 * @param(newpri) task's new priority
2003 * @b(returns) task's old priority
2004 *
2005 * @a(constraints)
2006 * newpri must be a value between 1 and ({@link #numPriorities} - 1) or -1.
2007 *
2008 * The task cannot be in the {@link #Mode_TERMINATED} mode.
2009 *
2010 * The new priority should not be zero (0). This priority level is
2011 * reserved for the Idle task.
2012 */
2013 UInt setPri(Int newpri);
2014
2015 /*!
2016 * ======== stat ========
2017 * Retrieve the status of a task.
2018 *
2019 * Task_stat retrieves attribute values and status information about a
2020 * task.
2021 *
2022 * Status information is returned through statbuf, which references a
2023 * structure of type {@link #Stat}.
2024 *
2025 * When a task is preempted by a software or hardware interrupt, the task
2026 * execution mode returned for that task by Task_stat is still
2027 * {@link #Mode_RUNNING} because the task runs when the preemption ends.
2028 *
2029 * The current task can inquire about itself by passing the output of
2030 * {@link #self} as the first argument to Task_stat. However, the task
2031 * stack pointer (sp) in the {@link #Stat} structure is the value from
2032 * the previous context switch.
2033 *
2034 * Task_stat has a non-deterministic execution time. As such, it is not
2035 * recommended to call this API from Swis or Hwis.
2036 *
2037 * @param(statbuf) pointer to task status structure
2038 *
2039 * @a(constraints)
2040 * statbuf cannot be NULL;
2041 */
2042 Void stat(Stat *statbuf);
2043
2044 /*!
2045 * ======== getMode ========
2046 * Retrieve the {@link #Mode} of a task.
2047 */
2048 Mode getMode();
2049
2050 /*!
2051 * ======== setAffinity ========
2052 * Set task's core affinity (should be used only in applications built
2053 * with {@link ti.sysbios.BIOS#smpEnabled BIOS.smpEnabled} set to true)
2054 *
2055 * If the new core ID is different than the current core affinity
2056 * a reschedule will be performed immediately.
2057 *
2058 * @a(constraints)
2059 * Must NOT be called with interrupts disabled
2060 * (ie within a Hwi_disable()/Hwi_restore() block).
2061 *
2062 * Must NOT be called with tasking disabled
2063 * (ie within a Task_disable()/Task_restore() block).
2064 *
2065 * @b(returns) task's previous core affinity
2066 */
2067 UInt setAffinity(UInt coreId);
2068
2069 /*!
2070 * ======== getAffinity ========
2071 * Return task's core affinity (should be used only in applications built
2072 * with {@link ti.sysbios.BIOS#smpEnabled} set to true)
2073 *
2074 * @b(returns) task's current core affinity
2075 */
2076 UInt getAffinity();
2077
2078 /*!
2079 * @_nodoc
2080 * ======== block ========
2081 * Block a task.
2082 *
2083 * Remove a task from its ready list.
2084 * The effect of this API is manifest the next time the internal
2085 * Task scheduler is invoked.
2086 * This can be done directly by embedding the call within a
2087 * {@link #disable}/{@link #restore} block.
2088 * Otherwise, the effect will be manifest as a result of processing
2089 * the next dispatched interrupt, or by posting a Swi, or by falling
2090 * through the task function.
2091 *
2092 * @a(constraints)
2093 * If called from within a Hwi or a Swi, or main(), there is no need
2094 * to embed the call within a {@link #disable}/{@link #restore} block.
2095 */
2096 Void block();
2097
2098 /*!
2099 * @_nodoc
2100 * ======== unblock ========
2101 * Unblock a task.
2102 *
2103 * Place task in its ready list.
2104 * The effect of this API is manifest the next time the internal
2105 * Task scheduler is invoked.
2106 * This can be done directly by embedding the call within a
2107 * {@link #disable}/{@link #restore} block.
2108 * Otherwise, the effect will be manifest as a result of processing
2109 * the next dispatched interrupt, or by posting a Swi, or by falling
2110 * through the task function.
2111 *
2112 * @a(constraints)
2113 * If called from within a Hwi or a Swi, or main(), there is no need
2114 * to embed the call within a {@link #disable}/{@link #restore} block.
2115 */
2116 Void unblock();
2117
2118 /*!
2119 * @_nodoc
2120 * ======== blockI ========
2121 * Block a task.
2122 *
2123 * Remove a task from its ready list.
2124 * Must be called within Task_disable/Task_restore block
2125 * with interrupts disabled.
2126 * This API is meant to be used internally.
2127 */
2128 Void blockI();
2129
2130 /*!
2131 * @_nodoc
2132 * ======== unblockI ========
2133 * Unblock a task.
2134 *
2135 * Place task in its ready list.
2136 * Must be called within Task_disable/Task_restore block
2137 * with interrupts disabled.
2138 * This API is meant to be used internally.
2139 *
2140 * @param(hwiKey) key returned from Hwi_disable()
2141 */
2142 Void unblockI(UInt hwiKey);
2143
2144 internal:
2145
2146 /*! Target-specific support functions. */
2147 proxy SupportProxy inherits ti.sysbios.interfaces.ITaskSupport;
2148
2149 2150 2151 2152 2153 2154
2155 Void schedule();
2156
2157 2158 2159 2160
2161 Void enter();
2162
2163 2164 2165 2166
2167 Void sleepTimeout(UArg arg);
2168
2169 2170 2171 2172
2173 Int postInit(Object *task, Error.Block *eb);
2174
2175 2176 2177 2178 2179
2180 config UInt numConstructedTasks = 0;
2181
2182 2183 2184 2185
2186 Void allBlockedFunction();
2187
2188 2189 2190 2191 2192
2193 Void deleteTerminatedTasksFunc();
2194
2195 2196 2197 2198 2199
2200 Void processVitalTaskFlag(Object *task);
2201
2202 2203 2204
2205 Int moduleStateCheck(Task.Module_State *moduleState, UInt32 checkValue);
2206
2207 2208 2209
2210 UInt32 getModuleStateCheckValue(Task.Module_State *moduleState);
2211
2212 2213 2214
2215 Int objectCheck(Task.Handle handle, UInt32 checkValue);
2216
2217 2218 2219
2220 UInt32 getObjectCheckValue(Task.Handle handle);
2221
2222 2223 2224 2225
2226 config Void (*startupHookFunc)(Void) = null;
2227
2228 2229 2230 2231
2232 struct PendElem {
2233 Queue.Elem qElem;
2234 Task.Handle task;
2235 Clock.Handle clock;
2236 };
2237
2238 struct Instance_State {
2239 Queue.Elem qElem;
2240 volatile Int priority;
2241 UInt mask;
2242 Ptr context;
2243
2244 Mode mode;
2245 PendElem *pendElem;
2246
2247 SizeT stackSize;
2248 Char stack[];
2249 IHeap.Handle stackHeap;
2250 FuncPtr fxn;
2251 UArg arg0;
2252 UArg arg1;
2253 Ptr env;
2254 Ptr hookEnv[];
2255 Bool vitalTaskFlag;
2256
2257 Queue.Handle readyQ;
2258 UInt curCoreId;
2259 UInt affinity;
2260
2261 };
2262
2263 struct Module_State {
2264 volatile Bool locked;
2265 volatile UInt curSet;
2266 Bool workFlag;
2267
2268
2269 UInt vitalTasks;
2270
2271 Handle curTask;
2272 Queue.Handle curQ;
2273 Queue.Object readyQ[];
2274
2275 volatile UInt smpCurSet[];
2276
2277
2278 volatile UInt smpCurMask[];
2279 Handle smpCurTask[];
2280 Queue.Handle smpReadyQ[];
2281
2282
2283
2284 Queue.Object inactiveQ;
2285 Queue.Object terminatedQ;
2286
2287 Handle idleTask[];
2288 Handle constructedTasks[];
2289
2290 };
2291
2292 struct RunQEntry {
2293 Queue.Elem elem;
2294 UInt coreId;
2295 Int priority;
2296 };
2297
2298 struct Module_StateSmp {
2299 Queue.Object *sortedRunQ;
2300
2301 volatile RunQEntry smpRunQ[];
2302
2303 };
2304 }