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
668 /*! Asserted in Task_create and Task_delete */
669 config Assert.Id A_badThreadType = {
670 msg: "A_badThreadType: Cannot create/delete a task from Hwi or Swi thread."
671 };
672
673 /*! Asserted in Task_delete */
674 config Assert.Id A_badTaskState = {
675 msg: "A_badTaskState: Can't delete a task in RUNNING state."
676 };
677
678 /*! Asserted in Task_delete */
679 config Assert.Id A_noPendElem = {
680 msg: "A_noPendElem: Not enough info to delete BLOCKED task."
681 };
682
683 /*! Asserted in Task_create */
684 config Assert.Id A_taskDisabled = {
685 msg: "A_taskDisabled: Cannot create a task when tasking is disabled."
686 };
687
688 /*! Asserted in Task_create */
689 config Assert.Id A_badPriority = {
690 msg: "A_badPriority: An invalid task priority was used."
691 };
692
693 /*! Asserted in Task_sleep */
694 config Assert.Id A_badTimeout = {
695 msg: "A_badTimeout: Can't sleep FOREVER."
696 };
697
698 /*! Asserted in Task_setAffinity */
699 config Assert.Id A_badAffinity = {
700 msg: "A_badAffinity: Invalid affinity."
701 };
702
703 /*! Asserted in Task_sleep */
704 config Assert.Id A_sleepTaskDisabled = {
705 msg: "A_sleepTaskDisabled: Cannot call Task_sleep() while the Task scheduler is disabled."
706 };
707
708 /*! Asserted in Task_getIdleTaskHandle */
709 config Assert.Id A_invalidCoreId = {
710 msg: "A_invalidCoreId: Cannot pass a non-zero CoreId in a non-SMP application."
711 };
712
713 /*!
714 * Number of Task priorities supported. Default is 16.
715 *
716 * The maximum number of priorities supported is
717 * target specific and depends on the number of
718 * bits in a UInt data type. For 6x and ARM devices
719 * the maximum number of priorities is therefore 32.
720 * For C28x devices, the maximum number of
721 * priorities is 16.
722 */
723 config UInt numPriorities = 16;
724
725 /*!
726 * Default stack size (in MAUs) used for all tasks.
727 *
728 * Default is obtained from the family-specific TaskSupport module
729 * (e.g. {@link ti.sysbios.family.arm.m3.TaskSupport},
730 * {@link ti.sysbios.family.c62.TaskSupport}).
731 */
732 config SizeT defaultStackSize;
733
734 /*!
735 * Default memory section used for all statically created task stacks.
736 *
737 * The default stack section name is target/device specific.
738 * For C6x targets it is ".far:taskStackSection".
739 * For C28x targets it is ".taskStackSection".
740 * For GNU targets it is ".bss".
741 * For all other targets it is ".bss:taskStackSection".
742 *
743 * By default, all statically created task stacks are grouped together
744 * into the defaultStackSection and placed where ever
745 * the target specific defaultStackSection base section name
746 * (ie .bss, .far, .ebss) is placed.
747 *
748 * To place all task stacks into a different memory segment,
749 * add the following to your config script:
750 *
751 * @p(code)
752 * Program.sectMap[Task.defaultStackSection] = new Program.SectionSpec();
753 * Program.sectMap[Task.defaultStackSection].loadSegment =
754 * "yourMemorySegment";
755 * @p
756 *
757 * To group all task stacks into a different section AND place that
758 * section into a specific memory segment, add the following to your
759 * config script:
760 *
761 * @p(code)
762 * Task.defaultStackSection = ".yourSectionName";
763 * Program.sectMap[Task.defaultStackSection] = new Program.SectionSpec();
764 * Program.sectMap[Task.defaultStackSection].loadSegment =
765 * "yourMemorySegment";
766 * @p
767 *
768 * Where "yourSectionName" can be just about anything, and
769 * "yourMemorySegment"
770 * must be a memory segment defined for your board.
771 */
772 metaonly config String defaultStackSection;
773
774 /*!
775 * Default Mem heap used for all dynamically created task stacks.
776 *
777 * Default is null.
778 */
779 config IHeap.Handle defaultStackHeap;
780
781 /*!
782 * Default core affinity for newly created tasks.
783 *
784 * Default is Task_AFFINITY_NONE, meaning don't care.
785 */
786 metaonly config UInt defaultAffinity = AFFINITY_NONE;
787
788 /*!
789 * Create a task (of priority 0) to run the Idle functions in.
790 *
791 * When set to true, a task is created that continuously calls the
792 * {@link Idle#run Idle_run()} function, which, in turn calls each of
793 * the configured Idle functions.
794 *
795 * When set to false, no Idle Task is created and it is up to the
796 * user to call the Idle_run() function if the configured Idle
797 * functions need to be run. Or, by adding the following lines to
798 * the config script, the Idle functions will run whenever all
799 * tasks are blocked ({@link #allBlockedFunc Task.allBlockedFunc}):
800 *
801 * @p(code)
802 * Task.enableIdleTask = false;
803 * Task.allBlockedFunc = Idle.run;
804 * @p
805 *
806 * Default is true.
807 *
808 * @see #idleTaskStackSize
809 * @see #idleTaskStackSection
810 * @see #idleTaskVitalTaskFlag
811 * @see #allBlockedFunc
812 */
813 metaonly config Bool enableIdleTask = true;
814
815 /*!
816 * Reduce interrupt latency by enabling interrupts
817 * within the Task scheduler.
818 *
819 * By default, interrupts are disabled within certain critical
820 * sections of the task scheduler when switching to a different
821 * task thread. This default behavior guarantees that a task stack
822 * will only ever absorb ONE ISR context. Nested interrupts all run
823 * on the shared Hwi stack.
824 *
825 * While most users find this behavior desirable, the resulting
826 * impact on interrupt latency is too great for certain applications.
827 *
828 * By setting this parameter to 'true', the worst case interrupt latency
829 * imposed by the kernel will be reduced but will result in task stacks
830 * needing to be sized to accommodate one additional interrupt context.
831 *
832 * See sections 3.5.3 and 7.5 of the BIOS User's Guide for further
833 * discussions regarding task stack sizing.
834 *
835 * Also see {@link ti.sysbios.BIOS#logsEnabled BIOS.logsEnabled}
836 * and the discussion on Task hooks.
837 */
838 metaonly config Bool minimizeLatency = false;
839
840 /*!
841 * Idle task stack size in MAUs.
842 *
843 * Default is inherited from module config defaultStackSize.
844 */
845 metaonly config SizeT idleTaskStackSize;
846
847 /*!
848 * Idle task stack section
849 *
850 * Default is inherited from module config defaultStackSection;
851 */
852 metaonly config String idleTaskStackSection;
853
854 /*!
855 * Idle task's vitalTaskFlag.
856 * (see {@link #vitalTaskFlag}).
857 *
858 * Default is true.
859 */
860 metaonly config Bool idleTaskVitalTaskFlag = true;
861
862 /*!
863 * Function to call while all tasks are blocked.
864 *
865 * This function will be called repeatedly while no tasks are
866 * ready to run.
867 *
868 * Ordinarily (in applications that have tasks ready to run at startup),
869 * the function will run in the context of the last task to block.
870 *
871 * In an application where there are no tasks ready to run
872 * when BIOS_start() is called, the allBlockedFunc function is
873 * called within the BIOS_start() thread which runs on the system/ISR
874 * stack.
875 *
876 * By default, allBlockedFunc is initialized to point to an internal
877 * function that simply returns.
878 *
879 * By adding the following lines to the config script, the Idle
880 * functions will run whenever all tasks are blocked:
881 *
882 * @p(code)
883 * Task.enableIdleTask = false;
884 * Task.allBlockedFunc = Idle.run;
885 * @p
886 *
887 * @see #enableIdleTask
888 *
889 * @a(constraints)
890 * The configured allBlockedFunc is designed to be called repeatedly.
891 * It must return in order for the task scheduler to check if all
892 * tasks are STILL blocked and if not, run the highest priority task
893 * currently ready to run.
894 *
895 * The configured allBlockedFunc function is called with interrupts
896 * disabled. If your function must run with interrupts enabled,
897 * surround the body of your code with Hwi_enable()/Hwi_restore()
898 * function calls per the following example:
899 *
900 * @p(code)
901 * Void yourFunc() {
902 * UInt hwiKey;
903 *
904 * hwiKey = Hwi_enable();
905 *
906 * ... // your code here
907 *
908 * Hwi_restore(hwiKey);
909 * }
910 * @p
911 */
912 config AllBlockedFuncPtr allBlockedFunc = null;
913
914 /*!
915 * Initialize stack with known value for stack checking at runtime
916 * (see {@link #checkStackFlag}).
917 * If this flag is set to false, while the
918 * {@link ti.sysbios.hal.Hwi#checkStackFlag} is set to true, only the
919 * first byte of the stack is initialized.
920 *
921 * This is also useful for inspection of stack in debugger or core
922 * dump utilities.
923 * Default is true.
924 */
925 config Bool initStackFlag = true;
926
927 /*!
928 * Check 'from' and 'to' task stacks before task context switch.
929 *
930 * The check consists of testing the top of stack value against
931 * its initial value (see {@link #initStackFlag}). If it is no
932 * longer at this value, the assumption is that the task has
933 * overrun its stack. If the test fails, then the
934 * {@link #E_stackOverflow} error is raised.
935 *
936 * Default is true.
937 *
938 * To enable or disable full stack checking, you should set both this
939 * flag and the {@link ti.sysbios.hal.Hwi#checkStackFlag}.
940 *
941 * @a(Note)
942 * Enabling stack checking will add some interrupt latency because the
943 * checks are made within the Task scheduler while interrupts are
944 * disabled.
945 */
946 config Bool checkStackFlag = true;
947
948 /*!
949 * Automatically delete terminated tasks.
950 *
951 * If this feature is enabled, an Idle function is installed that
952 * deletes dynamically created Tasks that have terminated either
953 * by falling through their task function or by explicitly calling
954 * Task_exit().
955 *
956 * A list of terminated Tasks that were created dynmically is
957 * maintained internally. Each invocation of the installed Idle function
958 * deletes the first Task on this list. This one-at-a-time process
959 * continues until the list is empty.
960 *
961 * @a(Note)
962 * This feature is disabled by default.
963 *
964 * @a(WARNING)
965 * When this feature is enabled, an error will be raised if the user's
966 * application attempts to delete a terminated task. If a terminated task
967 * has already been automatically deleted and THEN the user's application
968 * attempts to delete it (ie: using a stale Task handle), the results are
969 * undefined and probably catastrophic!
970 *
971 */
972 config Bool deleteTerminatedTasks = false;
973
974 /*!
975 * Const array that holds the HookSet objects.
976 *
977 * See {@link #hookfunc Hook Functions} for details about HookSets.
978 */
979 config HookSet hooks[length] = [];
980
981 /*!
982 * ======== moduleStateCheckFxn ========
983 * Function called to perform module state data integrity check
984 *
985 * If {@link #moduleStateCheckFlag} is set to true, SYS/BIOS kernel
986 * will call this function each time Task_disable() function is called.
987 * SYS/BIOS provides a default implementation of this function that
988 * computes the check value for the static module state fields and
989 * compares the resulting check value against the stored value. In
990 * addition, the check function validates some of the pointers used
991 * by the Task scheduler. The application can install its own
992 * implementation of the module state check function.
993 *
994 * Here's an example module state check function:
995 *
996 * *.cfg
997 * @p(code)
998 * var Task = xdc.useModule('ti.sysbios.knl.Task');
999 *
1000 * // Enable Task module state data integrity check
1001 * Task.moduleStateCheckFlag = true;
1002 *
1003 * // Install custom module state check function
1004 * Task.moduleStateCheckFxn = "&myCheckFunc";
1005 * @p
1006 *
1007 * *.c
1008 * @p(code)
1009 * #define ti_sysbios_knl_Task__internalaccess
1010 * #include <ti/sysbios/knl/Task.h>
1011 *
1012 * Int myCheckFunc(Task_Module_State *moduleState, UInt32 checkValue)
1013 * {
1014 * UInt32 newCheckValue;
1015 *
1016 * newCheckValue = Task_moduleStateCheckValueFxn(moduleState);
1017 * if (newCheckValue != checkValue) {
1018 * // Return '-1' to indicate data corruption. SYS/BIOS kernel
1019 * // will raise an error.
1020 * return (-1);
1021 * }
1022 *
1023 * return (0);
1024 * }
1025 * @p
1026 */
1027 config ModStateCheckFuncPtr moduleStateCheckFxn = Task.moduleStateCheck;
1028
1029 /*!
1030 * ======== moduleStateCheckValueFxn ========
1031 * Function called to compute module state check value
1032 *
1033 * If {@link #moduleStateCheckFlag} is set to true, SYS/BIOS kernel
1034 * will call this function during startup to compute the Task module
1035 * state's check value.
1036 *
1037 * SYS/BIOS provides a default implementation of this function that
1038 * computes a 32-bit checksum for the static module state fields (i.e.
1039 * module state fields that do not change during the lifetime of the
1040 * application). The application can install its own implementation
1041 * of this function.
1042 *
1043 * Here's an example module state check value computation function:
1044 *
1045 * *.cfg
1046 * @p(code)
1047 * var Task = xdc.useModule('ti.sysbios.knl.Task');
1048 *
1049 * // Enable Task module state data integrity check
1050 * Task.moduleStateCheckFlag = true;
1051 *
1052 * // Install custom module state check value function
1053 * Task.moduleStateCheckValueFxn = "&myCheckValueFunc";
1054 * @p
1055 *
1056 * *.c
1057 * @p(code)
1058 * #define ti_sysbios_knl_Task__internalaccess
1059 * #include <ti/sysbios/knl/Task.h>
1060 *
1061 * UInt32 myCheckValueFunc(Task_Module_State *moduleState)
1062 * {
1063 * UInt64 checksum;
1064 *
1065 * checksum = (uintptr_t)moduleState->readyQ +
1066 * (uintptr_t)moduleState->smpCurSet +
1067 * (uintptr_t)moduleState->smpCurMask +
1068 * (uintptr_t)moduleState->smpCurTask +
1069 * (uintptr_t)moduleState->smpReadyQ +
1070 * (uintptr_t)moduleState->idleTask +
1071 * (uintptr_t)moduleState->constructedTasks;
1072 * checksum = (checksum >> 32) + (checksum & 0xFFFFFFFF);
1073 * checksum = checksum + (checksum >> 32);
1074 *
1075 * return ((UInt32)(~checksum));
1076 * }
1077 * @p
1078 */
1079 config ModStateCheckValueFuncPtr moduleStateCheckValueFxn =
1080 Task.getModuleStateCheckValue;
1081
1082 /*!
1083 * ======== moduleStateCheckFlag ========
1084 * Perform a runtime data integrity check on the Task module state
1085 *
1086 * This configuration parameter determines whether a data integrity
1087 * check is performed on the Task module state in order to detect
1088 * data corruption.
1089 *
1090 * If this field is set to true, a check value of the static fields in
1091 * the Task module state (i.e. fields that do not change during the
1092 * lifetime of the application) is computed during startup. The
1093 * computed check value is stored for use by the Task module state check
1094 * function. The application can implement its own check value
1095 * computation function (see {@link #moduleStateCheckValueFxn}).
1096 * By default, SYS/BIOS installs a check value computation function that
1097 * computes a 32-bit checksum of the static fields in the Task module
1098 * state.
1099 *
1100 * The module state check function (see {@link #moduleStateCheckFxn})
1101 * is called from within the Task_disable() function. The application
1102 * can provide its own implementation of this function. By default,
1103 * SYS/BIOS installs a check function that computes the check value
1104 * for select module state fields and compares the resulting check
1105 * value against the stored value.
1106 *
1107 * If the module state check function returns a '-1' (i.e. check failed),
1108 * then the SYS/BIOS kernel will raise an error.
1109 */
1110 config Bool moduleStateCheckFlag = false;
1111
1112 /*!
1113 * ======== objectCheckFxn ========
1114 * Function called to perform Task object data integrity check
1115 *
1116 * If {@link #objectCheckFlag} is set to true, SYS/BIOS kernel
1117 * will call this function from within a Task switch hook and
1118 * each time a Task blocks or unblocks. SYS/BIOS provides a default
1119 * implementation of this function that computes the check value
1120 * for the static Task object fields and compares the resulting
1121 * check value against the stored value. The application can install
1122 * its own implementation of the object check function.
1123 *
1124 * Here's an example Task object check function:
1125 *
1126 * *.cfg
1127 * @p(code)
1128 * var Task = xdc.useModule('ti.sysbios.knl.Task');
1129 *
1130 * // Enable Task object data integrity check
1131 * Task.objectCheckFlag = true;
1132 *
1133 * // Install custom Task object check function
1134 * Task.objectCheckFxn = "&myCheckFunc";
1135 * @p
1136 *
1137 * *.c
1138 * @p(code)
1139 * #define ti_sysbios_knl_Task__internalaccess
1140 * #include <ti/sysbios/knl/Task.h>
1141 *
1142 * Int myCheckFunc(Task_Handle handle, UInt32 checkValue)
1143 * {
1144 * UInt32 newCheckValue;
1145 *
1146 * newCheckValue = Task_objectCheckValueFxn(handle);
1147 * if (newCheckValue != checkValue) {
1148 * // Return '-1' to indicate data corruption. SYS/BIOS kernel
1149 * // will raise an error.
1150 * return (-1);
1151 * }
1152 *
1153 * return (0);
1154 * }
1155 * @p
1156 */
1157 config ObjectCheckFuncPtr objectCheckFxn = Task.objectCheck;
1158
1159 /*!
1160 * ======== objectCheckValueFxn ========
1161 * Function called to compute Task object check value
1162 *
1163 * If {@link #objectCheckFlag} is set to true, SYS/BIOS kernel
1164 * will call this function to compute the Task object's check value
1165 * each time a Task is created.
1166 *
1167 * SYS/BIOS provides a default implementation of this function that
1168 * computes a 32-bit checksum for the static Task object fields (i.e.
1169 * Task object fields that do not change during the lifetime of the
1170 * Task). The application can install its own implementation of this
1171 * function.
1172 *
1173 * Here's an example Task object check value computation function:
1174 *
1175 * *.cfg
1176 * @p(code)
1177 * var Task = xdc.useModule('ti.sysbios.knl.Task');
1178 *
1179 * // Enable Task object data integrity check
1180 * Task.objectCheckFlag = true;
1181 *
1182 * // Install custom Task object check value function
1183 * Task.objectCheckValueFxn = "&myCheckValueFunc";
1184 * @p
1185 *
1186 * *.c
1187 * @p(code)
1188 * #define ti_sysbios_knl_Task__internalaccess
1189 * #include <ti/sysbios/knl/Task.h>
1190 *
1191 * UInt32 myCheckValueFunc(Task_Handle taskHandle)
1192 * {
1193 * UInt64 checksum;
1194 *
1195 * checksum = taskHandle->stackSize +
1196 * (uintptr_t)taskHandle->stack +
1197 * (uintptr_t)taskHandle->stackHeap +
1198 * #if defined(__IAR_SYSTEMS_ICC__)
1199 * (UInt64)taskHandle->fxn +
1200 * #else
1201 * (uintptr_t)taskHandle->fxn +
1202 * #endif
1203 * taskHandle->arg0 +
1204 * taskHandle->arg1 +
1205 * (uintptr_t)taskHandle->hookEnv +
1206 * taskHandle->vitalTaskFlag;
1207 * checksum = (checksum >> 32) + (checksum & 0xFFFFFFFF);
1208 * checksum = checksum + (checksum >> 32);
1209 *
1210 * return ((UInt32)(~checksum));
1211 * }
1212 * @p
1213 */
1214 config ObjectCheckValueFuncPtr objectCheckValueFxn =
1215 Task.getObjectCheckValue;
1216
1217 /*!
1218 * ======== objectCheckFlag ========
1219 * Perform a runtime data integrity check on each Task object
1220 *
1221 * This configuration parameter determines whether a data integrity
1222 * check is performed on each Task object in the system in order to detect
1223 * data corruption.
1224 *
1225 * If this field is set to true, a check value of the static fields in
1226 * the Task object (i.e. fields that do not change during the lifetime
1227 * of the Task) is computed when the Task is created. The computed check
1228 * value is stored for use by the Task object check function. The
1229 * application can implement its own check value computation function
1230 * (see {@link #objectCheckValueFxn}). By default, SYS/BIOS installs a
1231 * check value computation function that computes a 32-bit checksum of
1232 * the static fields in the Task object.
1233 *
1234 * The Task object check function (see {@link #objectCheckFxn})
1235 * is called from within a Task switch hook if stack checking
1236 * (see {@link #checkStackFlag}) is enabled. It is also called when
1237 * a task blocks or unblocks. The application can provide its own
1238 * implementation of this function. By default, SYS/BIOS installs a
1239 * check function that computes the check value for select Task
1240 * object fields and compares the resulting check value against the
1241 * stored value.
1242 *
1243 * If the Task object check function returns a '-1' (i.e. check failed),
1244 * then the SYS/BIOS kernel will raise an error.
1245 */
1246 config Bool objectCheckFlag = false;
1247
1248
1249
1250 /*!
1251 * ======== addHookSet ========
1252 * addHookSet is used in a config file to add a hook set.
1253 *
1254 * Configures a set of hook functions for the
1255 * Task module. Each set contains these hook functions:
1256 *
1257 * @p(blist)
1258 * -Register: A function called before any statically created tasks
1259 * are initialized at runtime. The register hook is called at boot time
1260 * before main() and before interrupts are enabled.
1261 * -Create: A function that is called when a task is created.
1262 * This includes tasks that are created statically and those
1263 * created dynamically using {@link #create} or {@link #construct}.
1264 * The create hook is called outside of a Task_disable/enable block and
1265 * before the task has been added to the ready list.
1266 * -Ready: A function that is called when a task becomes ready to run.
1267 * The ready hook is called from within a Task_disable/enable block with
1268 * interrupts enabled.
1269 * -Switch: A function that is called just before a task switch
1270 * occurs. The 'prev' and 'next' task handles are passed to the Switch
1271 * hook. 'prev' is set to NULL for the initial task switch that occurs
1272 * during SYS/BIOS startup. The Switch hook is called from within a
1273 * Task_disable/enable block with interrupts enabled.
1274 * -Exit: A function that is called when a task exits using
1275 * {@link #exit}. The exit hook is passed the handle of the exiting
1276 * task. The exit hook is called outside of a Task_disable/enable block
1277 * and before the task has been removed from the kernel lists.
1278 * -Delete: A function that is called when any task is deleted at
1279 * run-time with {@link #delete}. The delete hook is called outside
1280 * of a Task_disable/enable block.
1281 * @p
1282 * Hook functions can only be configured statically.
1283 *
1284 * See {@link #hookfunc Hook Functions} for more details.
1285 *
1286 * HookSet structure elements may be omitted, in which case those
1287 * elements will not exist.
1288 *
1289 * For example, the following configuration code defines a HookSet:
1290 *
1291 * @p(code)
1292 * // Hook Set 1
1293 * Task.addHookSet({
1294 * registerFxn: '&myRegister1',
1295 * createFxn: '&myCreate1',
1296 * readyFxn: '&myReady1',
1297 * switchFxn: '&mySwitch1',
1298 * exitFxn: '&myExit1',
1299 * deleteFxn: '&myDelete1'
1300 * });
1301 * @p
1302 *
1303 * @param(hook) structure of type HookSet
1304 */
1305 metaonly Void addHookSet(HookSet hook);
1306
1307 /*!
1308 * @_nodoc
1309 * ======== Task_startup ========
1310 * Start the task scheduler.
1311 *
1312 * Task_startup signals the end of boot operations, enables
1313 * the Task scheduler and schedules the highest priority ready
1314 * task for execution.
1315 *
1316 * Task_startup is called by BIOS_start() after Hwi_enable()
1317 * and Swi_enable(). There is no return from this function as the
1318 * execution thread is handed to the highest priority ready task.
1319 */
1320 Void startup();
1321
1322 /*!
1323 * ======== Task_enabled ========
1324 * Returns TRUE if the Task scheduler is enabled
1325 *
1326 * @_nodoc
1327 */
1328 Bool enabled();
1329
1330 /*!
1331 * @_nodoc
1332 * ======== unlockSched ========
1333 * Force a Task scheduler unlock. Used by Core_atExit() & Core_hwiFunc()
1334 * to unlock Task scheduler before exiting.
1335 *
1336 * This function should only be called after a Hwi_disable() has entered
1337 * the Inter-core gate and disabled interrupts locally.
1338 */
1339 Void unlockSched();
1340
1341 /*!
1342 * ======== Task_disable ========
1343 * Disable the task scheduler.
1344 *
1345 * {@link #disable} and {@link #restore} control Task scheduling.
1346 * {@link #disable} disables all other Tasks from running until
1347 * {@link #restore} is called. Hardware and Software interrupts
1348 * can still run.
1349 *
1350 * {@link #disable} and {@link #restore} allow you to ensure that
1351 * statements
1352 * that must be performed together during critical processing are not
1353 * preempted by other Tasks.
1354 *
1355 * The value of the key returned is opaque to applications and is meant
1356 * to be passed to Task_restore().
1357 *
1358 * In the following example, the critical section is
1359 * not preempted by any Tasks.
1360 *
1361 * @p(code)
1362 * key = Task_disable();
1363 * `critical section`
1364 * Task_restore(key);
1365 * @p
1366 *
1367 * You can also use {@link #disable} and {@link #restore} to
1368 * create several Tasks and allow them to be invoked in
1369 * priority order.
1370 *
1371 * {@link #disable} calls can be nested.
1372 *
1373 * @b(returns) key for use with {@link #restore}
1374 *
1375 * @a(constraints)
1376 * Do not call any function that can cause the current task to block
1377 * within a {@link #disable}/{@link #restore} block. For example,
1378 * {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend}
1379 * (if timeout is non-zero),
1380 * {@link #sleep}, {@link #yield}, and Memory_alloc can all
1381 * cause blocking.
1382 */
1383 UInt disable();
1384
1385 /*!
1386 * @_nodoc
1387 * ======== enable ========
1388 * Enable the task scheduler.
1389 *
1390 * {@link #enable} unconditionally enables the Task scheduler and
1391 * schedules the highest priority ready task for execution.
1392 *
1393 * This function is called by {@link #startup} (which is called by
1394 * {@link ti.sysbios.BIOS#start BIOS_start}) to begin multi-tasking
1395 * operations.
1396 */
1397 Void enable();
1398
1399 /*!
1400 * ======== restore ========
1401 * Restore Task scheduling state.
1402 *
1403 * {@link #disable} and {@link #restore} control Task scheduling
1404 * {@link #disable} disables all other Tasks from running until
1405 * {@link #restore} is called. Hardware and Software interrupts
1406 * can still run.
1407 *
1408 * {@link #disable} and {@link #restore} allow you to ensure that
1409 * statements
1410 * that must be performed together during critical processing are not
1411 * preempted.
1412
1413 * In the following example, the critical section is not preempted
1414 * by any Tasks.
1415 *
1416 * @p(code)
1417 * key = Task_disable();
1418 * `critical section`
1419 * Task_restore(key);
1420 * @p
1421 *
1422 * You can also use {@link #disable} and {@link #restore} to create
1423 * several Tasks and allow them to be performed in priority order.
1424 *
1425 * {@link #disable} calls can be nested.
1426 *
1427 * {@link #restore} returns with interrupts enabled if the key unlocks
1428 * the scheduler
1429 *
1430 * @param(key) key to restore previous Task scheduler state
1431 *
1432 * @a(constraints)
1433 * Do not call any function that can cause the current task to block
1434 * within a {@link #disable}/{@link #restore} block. For example,
1435 * {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()}
1436 * (if timeout is non-zero),
1437 * {@link #sleep}, {@link #yield}, and Memory_alloc can all
1438 * cause blocking.
1439 *
1440 * {@link #restore} internally calls Hwi_enable() if the key passed
1441 * to it results in the unlocking of the Task scheduler (ie if this
1442 * is root Task_disable/Task_restore pair).
1443 */
1444 Void restore(UInt key);
1445
1446 /*!
1447 * @_nodoc
1448 * ======== restoreHwi ========
1449 * Restore Task scheduling state.
1450 * Used by dispatcher. Does not re-enable Ints.
1451 */
1452 Void restoreHwi(UInt key);
1453
1454 /*!
1455 * ======== self ========
1456 * Returns a handle to the currently executing Task object.
1457 *
1458 * Task_self returns the object handle for the currently executing task.
1459 * This function is useful when inspecting the object or when the current
1460 * task changes its own priority through {@link #setPri}.
1461 *
1462 * No task switch occurs when calling Task_self.
1463 *
1464 * Task_self will return NULL until Tasking is initiated at the end of
1465 * BIOS_start().
1466 *
1467 * @b(returns) address of currently executing task object
1468 */
1469
1470 Handle self();
1471
1472 /*!
1473 * ======== selfMacro ========
1474 * Returns a handle to the currently executing Task object.
1475 *
1476 * Task_selfMacro is identical to {@link #self} but is implemented as
1477 * and inline macro.
1478 *
1479 * @b(returns) address of currently executing task object
1480 */
1481 @Macro
1482 Handle selfMacro();
1483
1484 /*!
1485 * @_nodoc
1486 * ======== checkStacks ========
1487 * Check for stack overflow.
1488 *
1489 * This function is usually called by the {@link #HookSet} switchFxn to
1490 * make sure task stacks are valid before performing the context
1491 * switch.
1492 *
1493 * If a stack overflow is detected on either the oldTask or the
1494 * newTask, a {@link #E_stackOverflow} Error is raised and the system
1495 * exited.
1496 *
1497 * In order to work properly, {@link #checkStacks} requires that the
1498 * {@link #initStackFlag} set to true, which it is by default.
1499 *
1500 * You can call {@link #checkStacks} directly from your application.
1501 * For example, you can check the current task's stack integrity
1502 * at any time with a call like the following:
1503 *
1504 * @p(code)
1505 * Task_checkStacks(Task_self(), Task_self());
1506 * @p
1507 *
1508 * @param(oldTask) leaving Task Object Ptr
1509 * @param(newTask) entering Task Object Ptr
1510 */
1511 Void checkStacks(Handle oldTask, Handle newTask);
1512
1513 /*!
1514 * ======== exit ========
1515 * Terminate execution of the current task.
1516 *
1517 * Task_exit terminates execution of the current task, changing its mode
1518 * from {@link #Mode_RUNNING} to {@link #Mode_TERMINATED}. If all tasks
1519 * have been terminated, or if all remaining tasks have their
1520 * vitalTaskFlag attribute set to FALSE, then SYS/BIOS terminates the
1521 * program as a whole by calling the function System_exit with a status
1522 * code of 0.
1523 *
1524 * Task_exit is automatically called whenever a task returns from its
1525 * top-level function.
1526 *
1527 * Exit Hooks (see exitFxn in {@link #HookSet}) can be used to provide
1528 * functions that run whenever a task is terminated. The exitFxn Hooks
1529 * are called before the task has been blocked and marked
1530 * {@link #Mode_TERMINATED}.
1531 * See {@link #hookfunc Hook Functions} for more information.
1532 *
1533 * Any SYS/BIOS function can be called from an Exit Hook function.
1534 *
1535 * Calling {@link #self} within an Exit function returns the task
1536 * being exited. Your Exit function declaration should be similar to
1537 * the following:
1538 * @p(code)
1539 * Void myExitFxn(Void);
1540 * @p
1541 *
1542 * A task switch occurs when calling Task_exit unless the program as a
1543 * whole is terminated
1544 *
1545 * @a(constraints)
1546 * Task_exit cannot be called from a Swi or Hwi.
1547 *
1548 * Task_exit cannot be called from the program's main() function.
1549 */
1550 Void exit();
1551
1552 /*!
1553 * ======== sleep ========
1554 * Delay execution of the current task.
1555 *
1556 * Task_sleep changes the current task's mode from {@link #Mode_RUNNING}
1557 * to {@link #Mode_BLOCKED}, and delays its execution for nticks
1558 * increments of the {@link Clock system clock}. The actual time
1559 * delayed can be up to 1 system clock tick less than nticks due to
1560 * granularity in system timekeeping and the time elapsed per
1561 * tick is determined by {@link Clock#tickPeriod Clock_tickPeriod}.
1562 *
1563 * After the specified period of time has elapsed, the task reverts to
1564 * the {@link #Mode_READY} mode and is scheduled for execution.
1565 *
1566 * A task switch always occurs when calling Task_sleep if nticks > 0.
1567 *
1568 * @param(nticks) number of system clock ticks to sleep
1569 *
1570 * @a(constraints)
1571 * Task_sleep cannot be called from a Swi or Hwi, or within a
1572 * {@link #disable} / {@link #restore} block.
1573 *
1574 * Task_sleep cannot be called from the program's main() function.
1575 *
1576 * Task_sleep should not be called from within an Idle function. Doing
1577 * so prevents analysis tools from gathering run-time information.
1578 *
1579 * nticks cannot be {@link ti.sysbios.BIOS#WAIT_FOREVER BIOS_WAIT_FOREVER}.
1580 */
1581
1582 Void sleep(UInt32 nticks);
1583
1584 /*!
1585 * ======== yield ========
1586 * Yield processor to equal priority task.
1587 *
1588 * Task_yield yields the processor to another task of equal priority.
1589 *
1590 * A task switch occurs when you call Task_yield if there is an equal
1591 * priority task ready to run.
1592 *
1593 * Tasks of higher priority preempt the currently running task without
1594 * the need for a call to Task_yield. If only lower-priority tasks are
1595 * ready to run when you call Task_yield, the current task continues to
1596 * run. Control does not pass to a lower-priority task.
1597 *
1598 * @a(constraints)
1599 * When called within an Hwi, the code sequence calling Task_yield
1600 * must be invoked by the Hwi dispatcher.
1601 *
1602 * Task_yield cannot be called from the program's main() function.
1603 */
1604 Void yield();
1605
1606 /*!
1607 * ======== getIdleTask ========
1608 * returns a handle to the idle task object (for core 0)
1609 */
1610 Handle getIdleTask();
1611
1612 /*!
1613 * ======== getIdleTaskHandle ========
1614 * returns a handle to the idle task object for the specified coreId
1615 * (should be used only in applications built with
1616 * {@link ti.sysbios.BIOS#smpEnabled} set to true)
1617 *
1618 * @a(Note)
1619 * If this function is called in a non-SMP application, coreId should
1620 * always be 0.
1621 */
1622 Handle getIdleTaskHandle(UInt coreId);
1623
1624 /*!
1625 * @_nodoc
1626 * ======== startCore ========
1627 * begin tasking on a core
1628 */
1629 Void startCore(UInt coreId);
1630
1631 /*!
1632 * ======== getNickName ========
1633 *
1634 */
1635 metaonly String getNickName(Any tskView);
1636
1637 instance:
1638
1639 /*!
1640 * ======== create ========
1641 * Create a Task.
1642 *
1643 * Task_create creates a new task object. If successful, Task_create
1644 * returns the handle of the new task object. If unsuccessful,
1645 * Task_create returns NULL unless it aborts.
1646 *
1647 * The fxn parameter uses the {@link #FuncPtr} type to pass a pointer to
1648 * the function the Task object should run. For example, if myFxn is a
1649 * function in your program, your C code can create a Task object
1650 * to call that
1651 * function as follows:
1652 *
1653 * @p(code)
1654 * Task_Params taskParams;
1655 *
1656 * // Create task with priority 15
1657 * Task_Params_init(&taskParams);
1658 * taskParams.stackSize = 512;
1659 * taskParams.priority = 15;
1660 * Task_create((Task_FuncPtr)myFxn, &taskParams, &eb);
1661 * @p
1662 *
1663 * The following statements statically create a task in the
1664 * configuration file:
1665 *
1666 * @p(code)
1667 * var params = new Task.Params;
1668 * params.instance.name = "tsk0";
1669 * params.arg0 = 1;
1670 * params.arg1 = 2;
1671 * params.priority = 1;
1672 * Task.create('&tsk0_func', params);
1673 * @p
1674 *
1675 * If NULL is passed instead of a pointer to an actual Task_Params
1676 * struct, a
1677 * default set of parameters is used. The "eb" is an error block that
1678 * you can use
1679 * to handle errors that may occur during Task object creation.
1680 *
1681 * The newly created task is placed in {@link #Mode_READY} mode, and is
1682 * scheduled to begin concurrent execution of the following function
1683 * call:
1684 *
1685 * @p(code)
1686 * (*fxn)(arg1, arg2);
1687 * @p
1688 *
1689 * As a result of being made ready to run, the task runs any
1690 * application-wide Ready functions that have been specified.
1691 *
1692 * Task_exit is automatically called if and when the task returns
1693 * from fxn.
1694 *
1695 * @p(html)
1696 * <B>Create Hook Functions</B>
1697 * @p
1698 *
1699 * You can specify application-wide Create hook functions in your config
1700 * file that run whenever a task is created. This includes tasks that
1701 * are created statically and those created dynamically using
1702 * Task_create.
1703 *
1704 * For Task objects created statically, Create functions are called
1705 * during the Task module initialization phase of the program startup
1706 * process prior to main().
1707 *
1708 * For Task objects created dynamically, Create functions
1709 * are called after the task handle has been initialized but before the
1710 * task has been placed on its ready queue.
1711 *
1712 * Any SYS/BIOS function can be called from Create functions.
1713 * SYS/BIOS passes the task handle of the task being created to each of
1714 * the Create functions.
1715 *
1716 * All Create function declarations should be similar to this:
1717 * @p(code)
1718 * Void myCreateFxn(Task_Handle task);
1719 * @p
1720 *
1721 * @param(fxn) Task Function
1722 *
1723 * @a(constraints)
1724 * @p(blist)
1725 * - The fxn parameter and the name attribute cannot be NULL.
1726 * - The priority attribute must be less than or equal to
1727 * ({@link #numPriorities} - 1) and greater than or equal to one (1)
1728 * (priority 0 is owned by the Idle task).
1729 * - The priority can be set to -1 for tasks that will not execute
1730 * until another task changes the priority to a positive value.
1731 * - The stackHeap attribute must identify a valid memory Heap.
1732 * @p
1733 */
1734 create(FuncPtr fxn);
1735
1736
1737
1738
1739 /*! Task function argument. Default is 0 */
1740 config UArg arg0 = 0;
1741
1742 /*! Task function argument. Default is 0 */
1743 config UArg arg1 = 0;
1744
1745 /*!
1746 * Task priority (0 to Task.numPriorities-1, or -1).
1747 * Default is 1.
1748 */
1749 config Int priority = 1;
1750
1751 /*!
1752 * Task stack pointer. Default = null.
1753 *
1754 * Null indicates that the stack is to be allocated by create().
1755 *
1756 * @a(Static Configuration Usage Warning)
1757 * This parameter can only be assigned a non-null value
1758 * during runtime Task creates or constructs.
1759 *
1760 * Static configuration of the 'stack' parameter is not supported.
1761 *
1762 * Note that if {@link ti.sysbios.BIOS#runtimeCreatesEnabled
1763 * BIOS.runtimeCreatesEnabled} is set to false, then the user is required
1764 * to provide the stack buffer when constructing the Task object.
1765 * If 'stack' is not provided, then Task_construct() will fail.
1766 */
1767 config Ptr stack = null;
1768
1769 /*!
1770 * Task stack size in MAUs.
1771 *
1772 * The default value of 0 means that the module config
1773 * {@link #defaultStackSize} is used.
1774 */
1775 config SizeT stackSize = 0;
1776
1777 /*!
1778 * Mem section used for statically created task stacks.
1779 *
1780 * Default is inherited from module config defaultStackSection.
1781 */
1782 metaonly config String stackSection;
1783
1784 /*!
1785 * Mem heap used for dynamically created task stack.
1786 *
1787 * The default value of NULL means that the module config
1788 * {@link #defaultStackHeap} is used.
1789 */
1790 config IHeap.Handle stackHeap = null;
1791
1792 /*! Environment data struct. */
1793 config Ptr env = null;
1794
1795 /*!
1796 * Exit system immediately when the last task with this
1797 * flag set to TRUE has terminated.
1798 *
1799 * Default is true.
1800 */
1801 config Bool vitalTaskFlag = true;
1802
1803 /*!
1804 * The core which this task is to run on. Default is Task_AFFINITY_NONE
1805 *
1806 * If there is a compelling reason for a task to be pinned to a
1807 * particular core, then setting 'affinity' to the corresponding core
1808 * id will force the task to only be run on that core.
1809 *
1810 * The default affinity is inherited from {@link #defaultAffinity
1811 * Task.defaultAffinity}
1812 * which in turn defaults to {@link #AFFINITY_NONE Task_AFFINITY_NONE},
1813 * which means the task can be run on either core.
1814 *
1815 * Furthermore, Task_AFFINITY_NONE implies that the task can be moved
1816 * from core to core as deemed necessary by the Task scheduler in order
1817 * to keep the two highest priority ready tasks running simultaneously.
1818 */
1819 config UInt affinity;
1820
1821
1822
1823 /*!
1824 * @_nodoc
1825 * ======== getArg0 ========
1826 * Returns arg0 passed via params to create.
1827 *
1828 * @b(returns) task's arg0
1829 */
1830 UArg getArg0();
1831
1832 /*!
1833 * @_nodoc
1834 * ======== getArg1 ========
1835 * Returns arg1 passed via params to create.
1836 *
1837 * @b(returns) task's arg1
1838 */
1839 UArg getArg1();
1840
1841 /*!
1842 * ======== getEnv ========
1843 * Get task environment pointer.
1844 *
1845 * Task_getEnv returns the environment pointer of the specified task. The
1846 * environment pointer references an arbitrary application-defined data
1847 * structure.
1848 *
1849 * If your program uses multiple hook sets, {@link #getHookContext}
1850 * allows you to get environment pointers you have set for a particular
1851 * hook set and Task object combination.
1852 *
1853 * @b(returns) task environment pointer
1854 */
1855 Ptr getEnv();
1856
1857 /*!
1858 * ======== getFunc ========
1859 * Get Task function and arguments
1860 *
1861 * If either arg0 or arg1 is NULL, then the corresponding argument is not
1862 * returned.
1863 *
1864 * @param(arg0) pointer for returning Task's first function argument
1865 * @param(arg1) pointer for returning Task's second function argument
1866 *
1867 * @b(returns) Task function
1868 */
1869
1870 FuncPtr getFunc(UArg *arg0, UArg *arg1);
1871
1872 /*!
1873 * ======== getHookContext ========
1874 * Get hook set's context for a task.
1875 *
1876 * For example, this C code gets the HookContext, prints it,
1877 * and sets a new value for the HookContext.
1878 *
1879 * @p(code)
1880 * Ptr pEnv;
1881 * Task_Handle myTask;
1882 * Int myHookSetId1;
1883 *
1884 * pEnv = Task_getHookContext(task, myHookSetId1);
1885 *
1886 * System_printf("myEnd1: pEnv = 0x%lx, time = %ld\n",
1887 * (ULong)pEnv, (ULong)Timestamp_get32());
1888 *
1889 * Task_setHookContext(task, myHookSetId1, (Ptr)0xc0de1);
1890 * @p
1891 *
1892 * See {@link #hookfunc Hook Functions} for more details.
1893 *
1894 * @param(id) hook set ID
1895 * @b(returns) hook set context for task
1896 */
1897
1898 Ptr getHookContext(Int id);
1899
1900 /*!
1901 * ======== getPri ========
1902 * Get task priority.
1903 *
1904 * Task_getPri returns the priority of the referenced task.
1905 *
1906 * @b(returns) task priority
1907 */
1908
1909 Int getPri();
1910
1911 /*!
1912 * @_nodoc
1913 * ======== setArg0 ========
1914 * Set arg0 (used primarily for legacy support)
1915 */
1916 Void setArg0(UArg arg);
1917
1918 /*!
1919 * @_nodoc
1920 * ======== setArg1 ========
1921 * Set arg1 (used primarily for legacy support)
1922 */
1923 Void setArg1(UArg arg);
1924
1925 /*!
1926 * ======== setEnv ========
1927 * Set task environment.
1928 *
1929 * Task_setEnv sets the task environment pointer to env. The
1930 * environment pointer references an arbitrary application-defined
1931 * data structure.
1932 *
1933 * If your program uses multiple hook sets, {@link #setHookContext}
1934 * allows you to set environment pointers for any
1935 * hook set and Task object combination.
1936 *
1937 * @param(env) task environment pointer
1938 */
1939 Void setEnv(Ptr env);
1940
1941 /*!
1942 * ======== setHookContext ========
1943 * Set hook instance's context for a task.
1944 *
1945 * For example, this C code gets the HookContext, prints it,
1946 * and sets a new value for the HookContext.
1947 *
1948 * @p(code)
1949 * Ptr pEnv;
1950 * Task_Handle myTask;
1951 * Int myHookSetId1;
1952 *
1953 * pEnv = Task_getHookContext(task, myHookSetId1);
1954 *
1955 * System_printf("myEnd1: pEnv = 0x%lx, time = %ld\n",
1956 * (ULong)pEnv, (ULong)Timestamp_get32());
1957 *
1958 * Task_setHookContext(task, myHookSetId1, (Ptr)0xc0de1);
1959 * @p
1960 *
1961 * See {@link #hookfunc Hook Functions} for more details.
1962 *
1963 * @param(id) hook set ID
1964 * @param(hookContext) value to write to context
1965 */
1966
1967 Void setHookContext(Int id, Ptr hookContext);
1968
1969 /*!
1970 * ======== setPri ========
1971 * Set a task's priority
1972 *
1973 * Task_setpri sets the execution priority of task to newpri, and returns
1974 * that task's old priority value. Raising or lowering a task's priority
1975 * does not necessarily force preemption and re-scheduling of the caller:
1976 * tasks in the {@link #Mode_BLOCKED} mode remain suspended despite a
1977 * change in priority; and tasks in the {@link #Mode_READY} mode gain
1978 * control only if their new priority is greater than that of the
1979 * currently executing task.
1980 *
1981 * newpri should be set to a value greater than or equal to 1 and
1982 * less than or equal to ({@link #numPriorities} - 1). newpri can also
1983 * be set to -1 which puts the the task into the INACTIVE state and the
1984 * task will not run until its priority is raised at a later time by
1985 * another task. Priority 0 is reserved for the idle task.
1986 * If newpri equals ({@link #numPriorities} - 1), execution of the task
1987 * effectively locks out all other program activity, except for the
1988 * handling of interrupts.
1989 *
1990 * The current task can change its own priority (and possibly preempt its
1991 * execution) by passing the output of {@link #self} as the value of the
1992 * task parameter.
1993 *
1994 * A context switch occurs when calling Task_setpri if a currently
1995 * running task priority is set lower than the priority of another
1996 * currently ready task, or if another ready task is made to have a
1997 * higher priority than the currently running task.
1998 *
1999 * Task_setpri can be used for mutual exclusion.
2000 *
2001 * If a task's new priority is different than its previous priority,
2002 * then its relative placement in its new ready task priority
2003 * queue can be different than the one it was removed from. This can
2004 * effect the relative order in which it becomes the running task.
2005 *
2006 * The effected task is placed at the head of its new priority queue
2007 * if it is the currently running task. Otherwise it is placed at
2008 * at the end of its new task priority queue.
2009 *
2010 * @param(newpri) task's new priority
2011 * @b(returns) task's old priority
2012 *
2013 * @a(constraints)
2014 * newpri must be a value between 1 and ({@link #numPriorities} - 1) or -1.
2015 *
2016 * The task cannot be in the {@link #Mode_TERMINATED} mode.
2017 *
2018 * The new priority should not be zero (0). This priority level is
2019 * reserved for the Idle task.
2020 */
2021
2022 Int setPri(Int newpri);
2023
2024 /*!
2025 * ======== stat ========
2026 * Retrieve the status of a task.
2027 *
2028 * Task_stat retrieves attribute values and status information about a
2029 * task.
2030 *
2031 * Status information is returned through statbuf, which references a
2032 * structure of type {@link #Stat}.
2033 *
2034 * When a task is preempted by a software or hardware interrupt, the task
2035 * execution mode returned for that task by Task_stat is still
2036 * {@link #Mode_RUNNING} because the task runs when the preemption ends.
2037 *
2038 * The current task can inquire about itself by passing the output of
2039 * {@link #self} as the first argument to Task_stat. However, the task
2040 * stack pointer (sp) in the {@link #Stat} structure is the value from
2041 * the previous context switch.
2042 *
2043 * Task_stat has a non-deterministic execution time. As such, it is not
2044 * recommended to call this API from Swis or Hwis.
2045 *
2046 * @param(statbuf) pointer to task status structure
2047 *
2048 * @a(constraints)
2049 * statbuf cannot be NULL;
2050 */
2051 Void stat(Stat *statbuf);
2052
2053 /*!
2054 * ======== getMode ========
2055 * Retrieve the {@link #Mode} of a task.
2056 */
2057 Mode getMode();
2058
2059 /*!
2060 * ======== setAffinity ========
2061 * Set task's core affinity (should be used only in applications built
2062 * with {@link ti.sysbios.BIOS#smpEnabled BIOS.smpEnabled} set to true)
2063 *
2064 * If the new core ID is different than the current core affinity
2065 * a reschedule will be performed immediately.
2066 *
2067 * @a(constraints)
2068 * Must NOT be called with interrupts disabled
2069 * (ie within a Hwi_disable()/Hwi_restore() block).
2070 *
2071 * Must NOT be called with tasking disabled
2072 * (ie within a Task_disable()/Task_restore() block).
2073 *
2074 * @b(returns) task's previous core affinity
2075 */
2076 UInt setAffinity(UInt coreId);
2077
2078 /*!
2079 * ======== getAffinity ========
2080 * Return task's core affinity (should be used only in applications built
2081 * with {@link ti.sysbios.BIOS#smpEnabled} set to true)
2082 *
2083 * @b(returns) task's current core affinity
2084 */
2085 UInt getAffinity();
2086
2087 /*!
2088 * @_nodoc
2089 * ======== block ========
2090 * Block a task.
2091 *
2092 * Remove a task from its ready list.
2093 * The effect of this API is manifest the next time the internal
2094 * Task scheduler is invoked.
2095 * This can be done directly by embedding the call within a
2096 * {@link #disable}/{@link #restore} block.
2097 * Otherwise, the effect will be manifest as a result of processing
2098 * the next dispatched interrupt, or by posting a Swi, or by falling
2099 * through the task function.
2100 *
2101 * @a(constraints)
2102 * If called from within a Hwi or a Swi, or main(), there is no need
2103 * to embed the call within a {@link #disable}/{@link #restore} block.
2104 */
2105 Void block();
2106
2107 /*!
2108 * @_nodoc
2109 * ======== unblock ========
2110 * Unblock a task.
2111 *
2112 * Place task in its ready list.
2113 * The effect of this API is manifest the next time the internal
2114 * Task scheduler is invoked.
2115 * This can be done directly by embedding the call within a
2116 * {@link #disable}/{@link #restore} block.
2117 * Otherwise, the effect will be manifest as a result of processing
2118 * the next dispatched interrupt, or by posting a Swi, or by falling
2119 * through the task function.
2120 *
2121 * @a(constraints)
2122 * If called from within a Hwi or a Swi, or main(), there is no need
2123 * to embed the call within a {@link #disable}/{@link #restore} block.
2124 */
2125 Void unblock();
2126
2127 /*!
2128 * @_nodoc
2129 * ======== blockI ========
2130 * Block a task.
2131 *
2132 * Remove a task from its ready list.
2133 * Must be called within Task_disable/Task_restore block
2134 * with interrupts disabled.
2135 * This API is meant to be used internally.
2136 */
2137 Void blockI();
2138
2139 /*!
2140 * @_nodoc
2141 * ======== unblockI ========
2142 * Unblock a task.
2143 *
2144 * Place task in its ready list.
2145 * Must be called within Task_disable/Task_restore block
2146 * with interrupts disabled.
2147 * This API is meant to be used internally.
2148 *
2149 * @param(hwiKey) key returned from Hwi_disable()
2150 */
2151 Void unblockI(UInt hwiKey);
2152
2153 internal:
2154
2155 /*! Target-specific support functions. */
2156 proxy SupportProxy inherits ti.sysbios.interfaces.ITaskSupport;
2157
2158 2159 2160 2161 2162 2163
2164
2165 Void schedule();
2166
2167 2168 2169 2170
2171 Void enter();
2172
2173 2174 2175 2176
2177 Void sleepTimeout(UArg arg);
2178
2179 2180 2181 2182
2183 Int postInit(Object *task, Error.Block *eb);
2184
2185 2186 2187 2188 2189
2190 config UInt numConstructedTasks = 0;
2191
2192 2193 2194 2195
2196 Void allBlockedFunction();
2197
2198 2199 2200 2201 2202
2203 Void deleteTerminatedTasksFunc();
2204
2205 2206 2207 2208 2209
2210 Void processVitalTaskFlag(Object *task);
2211
2212 2213 2214
2215 Int moduleStateCheck(Task.Module_State *moduleState, UInt32 checkValue);
2216
2217 2218 2219
2220 UInt32 getModuleStateCheckValue(Task.Module_State *moduleState);
2221
2222 2223 2224
2225 Int objectCheck(Task.Handle handle, UInt32 checkValue);
2226
2227 2228 2229
2230 UInt32 getObjectCheckValue(Task.Handle handle);
2231
2232 2233 2234 2235
2236 config Void (*startupHookFunc)(Void) = null;
2237
2238 2239 2240 2241
2242 struct PendElem {
2243 Queue.Elem qElem;
2244 Task.Handle task;
2245 Clock.Handle clock;
2246 };
2247
2248 struct Instance_State {
2249 Queue.Elem qElem;
2250 volatile Int priority;
2251 UInt mask;
2252 Ptr context;
2253
2254 Mode mode;
2255 PendElem *pendElem;
2256
2257 SizeT stackSize;
2258 Char stack[];
2259 IHeap.Handle stackHeap;
2260 FuncPtr fxn;
2261 UArg arg0;
2262 UArg arg1;
2263 Ptr env;
2264 Ptr hookEnv[];
2265 Bool vitalTaskFlag;
2266
2267 Queue.Handle readyQ;
2268 UInt curCoreId;
2269 UInt affinity;
2270
2271 };
2272
2273 struct Module_State {
2274 volatile Bool locked;
2275 volatile UInt curSet;
2276 volatile Bool workFlag;
2277
2278
2279 UInt vitalTasks;
2280
2281 Handle curTask;
2282 Queue.Handle curQ;
2283 Queue.Object readyQ[];
2284
2285 volatile UInt smpCurSet[];
2286
2287
2288 volatile UInt smpCurMask[];
2289 Handle smpCurTask[];
2290 Queue.Handle smpReadyQ[];
2291
2292
2293
2294 Queue.Object inactiveQ;
2295 Queue.Object terminatedQ;
2296
2297 Handle idleTask[];
2298 Handle constructedTasks[];
2299
2300 };
2301
2302 struct RunQEntry {
2303 Queue.Elem elem;
2304 UInt coreId;
2305 Int priority;
2306 };
2307
2308 struct Module_StateSmp {
2309 Queue.Object *sortedRunQ;
2310
2311 volatile RunQEntry smpRunQ[];
2312
2313 };
2314 }