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