All tasks executing within a single program share a common set of
global variables, accessed according to the standard rules of scope
defined for C functions.
Each task is in one of five modes of execution at any point in time:
running, ready, blocked, terminated, or inactive. By design, there is
always one
(and only one) task currently running, even if it is only the idle task
managed internally by Task. The current task can be suspended from
execution by calling certain Task functions, as well as functions
provided by other modules like the Semaphore or Event Modules.
The current task
can also terminate its own execution. In either case, the processor
is switched to the highest priority task that is ready to run.
You can assign numeric priorities to tasks. Tasks are
readied for execution in strict priority order; tasks of the same
priority are scheduled on a first-come, first-served basis.
The priority of the currently running task is never lower
than the priority of any ready task. Conversely, the running task
is preempted and re-scheduled for execution whenever there exists
some ready task of higher priority.
When you create a task, it is provided with its own run-time stack,
used for storing local variables as well as for further nesting of
function calls. Each stack must be large enough to handle normal
subroutine calls and one task preemption context.
A task preemption context is the context that gets saved when one task
preempts another as a result of an interrupt thread readying
a higher-priority task.
See sections 3.5.3 and 7.5 of the BIOS User's Guide for further
discussions regarding task stack sizing.
Task_delete() removes the task from all internal queues and calls
Memory_free() is used to free the task object and its stack.
Memory_free() must acquire a lock to the memory before proceeding.
If another task already holds a lock to the memory, then the thread
performing the delete will be blocked until the memory is unlocked.
Note:
Task_delete() should be called with extreme care.
As mentioned above, the scope of Task_delete() is limited to
freeing the Task object itself, freeing the task's stack memory
if it was allocated at create time, and removing the task from
any SYS/BIOS-internal state structures.
SYS/BIOS does not keep track of any resources the task may have
acquired or used during its lifetime.
It is the application's responsibility to guarantee the integrity
of a task's partnerships prior to deleting that task.
For example, if a task has obtained exclusive access to a resource,
deleting that task will make the resource forever unavailable.
Task_delete() sets the referenced task handle to NULL. Any subsequent
call to a Task instance API using that null task handle will behave
unpredictably and will usually result in an application crash.
Assuming a task completely cleans up after itself prior to calling
Task_exit() (or falling through the the bottom of the task
function), it is then safest to use Task_delete() only when a task
is in the 'Task_Mode_TERMINATED' state.
Delete hooks:
You can specify application-wide Delete hook functions that
run whenever a task is deleted. See the discussion of Hook Functions
below for details.
Stack size parameters for both static and dynamic tasks are rounded
up to the nearest integer multiple of a target-specific alignment
requirement.
In the case of Task's which are created with a user-provided stack,
both the base address and the stackSize are aligned. The base address
is increased to the nearest aligned address. The stack size is decreased
accordingly and then rounded down to the nearest integer multiple of the
target-specific required alignment.
Sets of hook functions can be specified for the Task module. Each
set can contain these hook functions:
Hook functions can only be configured statically.
If you define more than one set of hook functions, all the functions
of a particular type will be run when a Task triggers that type of
hook.
Configuring ANY Task hook function will have the side effect of allowing
up to two interrupt contexts beings saved on a task stack. Be careful
to size your task stacks accordingly.
The create and delete functions are called whenever a Task is created
or deleted. They are called with interrupts enabled (unless called
at boot time or from main()).
If a switch function is specified, it is invoked just before the new task
is switched to. The switch function is called with interrupts enabled.
This function can be used to save/restore additional task context (for
example, external hardware registers), to check for task stack overflow,
to monitor the time used by each task, etc.
To properly handle the switch to the first task your switchFxn should
check for "prev == NULL" before using prev:
If a ready function is specified, it is invoked whenever a task is made
ready to run. The ready function is called with interrupts enabled
(unless called at boot time or from main()).
If an exit function is specified, it is invoked when a task exits (via
call to Task_exit() or when a task returns from its' main function).
The Exit Function is called with interrupts enabled.
const Task_AFFINITY_NONE |
|
"Don't care" task affinity
#define Task_AFFINITY_NONE (UInt)~(0)
enum Task_Mode |
|
Task execution modes
typedef enum Task_Mode {
Task_Mode_RUNNING,
// Task is currently executing
Task_Mode_READY,
// Task is scheduled for execution
Task_Mode_BLOCKED,
// Task is suspended from execution
Task_Mode_TERMINATED,
// Task is terminated from execution
Task_Mode_INACTIVE
// Task is on inactive task list
} Task_Mode;
DETAILS
These enumerations are the range of modes or states that
a task can be in. A task's current mode can be gotten using
stat.
typedef Task_AllBlockedFuncPtr |
|
"All Task Blocked" function type definition
typedef Void (*Task_AllBlockedFuncPtr)(Void);
typedef Task_FuncPtr |
|
Task function type definition
typedef Void (*Task_FuncPtr)(UArg,UArg);
typedef Task_ModStateCheckFuncPtr |
|
Data Integrity Check function type definition
typedef Task_ModStateCheckValueFuncPtr |
|
Check value computation function type definition
typedef Task_ObjectCheckFuncPtr |
|
Task object data integrity check function type definition
typedef Int (*
Task_ObjectCheckFuncPtr)(
Task_Handle,
UInt32);
typedef Task_ObjectCheckValueFuncPtr |
|
Check value computation function type definition
typedef UInt32 (*
Task_ObjectCheckValueFuncPtr)(
Task_Handle);
struct Task_HookSet |
|
Task hook set type definition
typedef struct Task_HookSet {
Void (*registerFxn)(Int);
} Task_HookSet;
DETAILS
Sets of hook functions can be specified for the Task module.
See
Hook Functions for details.
struct Task_Stat |
|
Task Status Buffer
typedef struct Task_Stat {
Int priority;
// Task priority
Ptr stack;
// Task stack
SizeT stackSize;
// Task stack size
// Heap used to alloc stack
Ptr env;
// Global environment struct
// Task's current mode
Ptr sp;
// Task's current stack pointer
SizeT used;
// Maximum number of bytes used on stack
} Task_Stat;
DETAILS
Passed to and filled in by
stat;
config Task_A_badAffinity // module-wide |
|
Asserted in Task_setAffinity
config Task_A_badPriority // module-wide |
|
Asserted in Task_create
config Task_A_badTaskState // module-wide |
|
Asserted in Task_delete
config Task_A_badThreadType // module-wide |
|
Asserted in Task_create and Task_delete
config Task_A_badTimeout // module-wide |
|
Asserted in Task_sleep
config Task_A_invalidCoreId // module-wide |
|
Asserted in Task_getIdleTaskHandle
config Task_A_noPendElem // module-wide |
|
Asserted in Task_delete
config Task_A_sleepTaskDisabled // module-wide |
|
Asserted in Task_sleep
extern const Assert_Id Task_A_sleepTaskDisabled;
config Task_A_taskDisabled // module-wide |
|
Asserted in Task_create
config Task_E_deleteNotAllowed // module-wide |
|
extern const Error_Id Task_E_deleteNotAllowed;
config Task_E_moduleStateCheckFailed // module-wide |
|
Error raised when the check value of the Task module state does not
match the stored check value (computed during startup). This indicates
that the Task module state was corrupted
extern const Error_Id Task_E_moduleStateCheckFailed;
config Task_E_objectCheckFailed // module-wide |
|
Error raised when the check value of the Task object does not match
the stored check value (computed during startup). This indicates
that the Task object was corrupted
extern const Error_Id Task_E_objectCheckFailed;
config Task_E_spOutOfBounds // module-wide |
|
Error raised when a task's stack pointer (SP) does not point
somewhere within the task's stack
extern const Error_Id Task_E_spOutOfBounds;
DETAILS
This error is raised by kernel's stack checking function. This
function checks the SPs before every task switch to make sure
they point within the task's stack.
The stack checking logic is enabled by the
initStackFlag and
checkStackFlag configuration parameters. If both of these
flags are set to true, the kernel will validate the stack pointers.
config Task_E_stackOverflow // module-wide |
|
Error raised when a stack overflow (or corruption) is detected
extern const Error_Id Task_E_stackOverflow;
DETAILS
This error is raised by kernel's stack checking function. This
function checks the stacks before every task switch to make sure
that reserved word at top of stack has not been modified.
The stack checking logic is enabled by the
initStackFlag and
checkStackFlag configuration parameters. If both of these
flags are set to true, the kernel will validate the stacks.
config Task_LD_block // module-wide |
|
Logged when a task is blocked (ie Semaphore_pend())
config Task_LD_exit // module-wide |
|
Logged when Task functions fall thru the bottom
or when Task_exit() is explicitly called
config Task_LD_ready // module-wide |
|
Logged when a task is made ready to run (ie Semaphore_post())
config Task_LM_noWork // module-wide |
|
Logged when no scheduling work was found
config Task_LM_schedule // module-wide |
|
Logged on every task schedule entry
config Task_LM_setAffinity // module-wide |
|
Logged on calls to Task_setAffinity
config Task_LM_setPri // module-wide |
|
Logged on calls to Task_setPri
config Task_LM_sleep // module-wide |
|
Logged on calls to Task_sleep
config Task_LM_switch // module-wide |
|
Logged on every task switch
config Task_LM_yield // module-wide |
|
Logged on calls to Task_yield
config Task_allBlockedFunc // module-wide |
|
Function to call while all tasks are blocked
DETAILS
This function will be called repeatedly while no tasks are
ready to run.
Ordinarily (in applications that have tasks ready to run at startup),
the function will run in the context of the last task to block.
In an application where there are no tasks ready to run
when BIOS_start() is called, the allBlockedFunc function is
called within the BIOS_start() thread which runs on the system/ISR
stack.
By default, allBlockedFunc is initialized to point to an internal
function that simply returns.
By adding the following lines to the config script, the Idle
functions will run whenever all tasks are blocked:
Task.enableIdleTask = false;
Task.allBlockedFunc = Idle.run;
SEE
CONSTRAINTS
The configured allBlockedFunc is designed to be called repeatedly.
It must return in order for the task scheduler to check if all
tasks are STILL blocked and if not, run the highest priority task
currently ready to run.
The configured allBlockedFunc function is called with interrupts
disabled. If your function must run with interrupts enabled,
surround the body of your code with Hwi_enable()/Hwi_restore()
function calls per the following example:
Void yourFunc() {
UInt hwiKey;
hwiKey = Hwi_enable();
... // your code here
Hwi_restore(hwiKey);
}
config Task_checkStackFlag // module-wide |
|
Check 'from' and 'to' task stacks before task context switch
extern const Bool Task_checkStackFlag;
DETAILS
The check consists of testing the top of stack value against
its initial value (see
initStackFlag). If it is no
longer at this value, the assumption is that the task has
overrun its stack. If the test fails, then the
E_stackOverflow error is raised.
Default is true.
To enable or disable full stack checking, you should set both this
flag and the
ti.sysbios.hal.Hwi.checkStackFlag.
NOTE
Enabling stack checking will add some interrupt latency because the
checks are made within the Task scheduler while interrupts are
disabled.
config Task_defaultStackHeap // module-wide |
|
Default Mem heap used for all dynamically created task stacks
DETAILS
Default is null.
config Task_defaultStackSize // module-wide |
|
Default stack size (in MAUs) used for all tasks
extern const SizeT Task_defaultStackSize;
DETAILS
Default is obtained from the family-specific TaskSupport module
(e.g.
ti.sysbios.family.arm.m3.TaskSupport,
ti.sysbios.family.c62.TaskSupport).
config Task_deleteTerminatedTasks // module-wide |
|
Automatically delete terminated tasks
extern const Bool Task_deleteTerminatedTasks;
DETAILS
If this feature is enabled, an Idle function is installed that
deletes dynamically created Tasks that have terminated either
by falling through their task function or by explicitly calling
Task_exit().
A list of terminated Tasks that were created dynmically is
maintained internally. Each invocation of the installed Idle function
deletes the first Task on this list. This one-at-a-time process
continues until the list is empty.
NOTE
This feature is disabled by default.
WARNING
When this feature is enabled, an error will be raised if the user's
application attempts to delete a terminated task. If a terminated task
has already been automatically deleted and THEN the user's application
attempts to delete it (ie: using a stale Task handle), the results are
undefined and probably catastrophic!
config Task_hooks // module-wide |
|
Const array that holds the HookSet objects
DETAILS
See
Hook Functions for details about HookSets.
config Task_initStackFlag // module-wide |
|
Initialize stack with known value for stack checking at runtime
(see checkStackFlag).
If this flag is set to false, while the
ti.sysbios.hal.Hwi.checkStackFlag is set to true, only the
first byte of the stack is initialized
extern const Bool Task_initStackFlag;
DETAILS
This is also useful for inspection of stack in debugger or core
dump utilities.
Default is true.
config Task_moduleStateCheckFlag // module-wide |
|
Perform a runtime data integrity check on the Task module state
extern const Bool Task_moduleStateCheckFlag;
DETAILS
This configuration parameter determines whether a data integrity
check is performed on the Task module state in order to detect
data corruption.
If this field is set to true, a check value of the static fields in
the Task module state (i.e. fields that do not change during the
lifetime of the application) is computed during startup. The
computed check value is stored for use by the Task module state check
function. The application can implement its own check value
computation function (see
moduleStateCheckValueFxn).
By default, SYS/BIOS installs a check value computation function that
computes a 32-bit checksum of the static fields in the Task module
state.
The module state check function (see
moduleStateCheckFxn)
is called from within the Task_disable() function. The application
can provide its own implementation of this function. By default,
SYS/BIOS installs a check function that computes the check value
for select module state fields and compares the resulting check
value against the stored value.
If the module state check function returns a '-1' (i.e. check failed),
then the SYS/BIOS kernel will raise an error.
config Task_moduleStateCheckFxn // module-wide |
|
Function called to perform module state data integrity check
DETAILS
If
moduleStateCheckFlag is set to true, SYS/BIOS kernel
will call this function each time Task_disable() function is called.
SYS/BIOS provides a default implementation of this function that
computes the check value for the static module state fields and
compares the resulting check value against the stored value. In
addition, the check function validates some of the pointers used
by the Task scheduler. The application can install its own
implementation of the module state check function.
Here's an example module state check function:
*.cfg
var Task = xdc.useModule('ti.sysbios.knl.Task');
// Enable Task module state data integrity check
Task.moduleStateCheckFlag = true;
// Install custom module state check function
Task.moduleStateCheckFxn = "&myCheckFunc";
*.c
#define ti_sysbios_knl_Task__internalaccess
#include <ti/sysbios/knl/Task.h>
Int myCheckFunc(Task_Module_State *moduleState, UInt32 checkValue)
{
UInt32 newCheckValue;
newCheckValue = Task_moduleStateCheckValueFxn(moduleState);
if (newCheckValue != checkValue) {
// Return '-1' to indicate data corruption. SYS/BIOS kernel
// will raise an error.
return (-1);
}
return (0);
}
config Task_moduleStateCheckValueFxn // module-wide |
|
Function called to compute module state check value
DETAILS
If
moduleStateCheckFlag is set to true, SYS/BIOS kernel
will call this function during startup to compute the Task module
state's check value.
SYS/BIOS provides a default implementation of this function that
computes a 32-bit checksum for the static module state fields (i.e.
module state fields that do not change during the lifetime of the
application). The application can install its own implementation
of this function.
Here's an example module state check value computation function:
*.cfg
var Task = xdc.useModule('ti.sysbios.knl.Task');
// Enable Task module state data integrity check
Task.moduleStateCheckFlag = true;
// Install custom module state check value function
Task.moduleStateCheckValueFxn = "&myCheckValueFunc";
*.c
#define ti_sysbios_knl_Task__internalaccess
#include <ti/sysbios/knl/Task.h>
UInt32 myCheckValueFunc(Task_Module_State *moduleState)
{
UInt64 checksum;
checksum = (uintptr_t)moduleState->readyQ +
(uintptr_t)moduleState->smpCurSet +
(uintptr_t)moduleState->smpCurMask +
(uintptr_t)moduleState->smpCurTask +
(uintptr_t)moduleState->smpReadyQ +
(uintptr_t)moduleState->idleTask +
(uintptr_t)moduleState->constructedTasks;
checksum = (checksum >> 32) + (checksum & 0xFFFFFFFF);
checksum = checksum + (checksum >> 32);
return ((UInt32)(~checksum));
}
config Task_numPriorities // module-wide |
|
Number of Task priorities supported. Default is 16
extern const UInt Task_numPriorities;
DETAILS
The maximum number of priorities supported is
target specific and depends on the number of
bits in a UInt data type. For 6x and ARM devices
the maximum number of priorities is therefore 32.
For 28x, 55x, and MSP430 devices, the maximum number of
priorities is 16.
config Task_objectCheckFlag // module-wide |
|
Perform a runtime data integrity check on each Task object
extern const Bool Task_objectCheckFlag;
DETAILS
This configuration parameter determines whether a data integrity
check is performed on each Task object in the system in order to detect
data corruption.
If this field is set to true, a check value of the static fields in
the Task object (i.e. fields that do not change during the lifetime
of the Task) is computed when the Task is created. The computed check
value is stored for use by the Task object check function. The
application can implement its own check value computation function
(see
objectCheckValueFxn). By default, SYS/BIOS installs a
check value computation function that computes a 32-bit checksum of
the static fields in the Task object.
The Task object check function (see
objectCheckFxn)
is called from within a Task switch hook if stack checking
(see
checkStackFlag) is enabled. It is also called when
a task blocks or unblocks. The application can provide its own
implementation of this function. By default, SYS/BIOS installs a
check function that computes the check value for select Task
object fields and compares the resulting check value against the
stored value.
If the Task object check function returns a '-1' (i.e. check failed),
then the SYS/BIOS kernel will raise an error.
config Task_objectCheckFxn // module-wide |
|
Function called to perform Task object data integrity check
DETAILS
If
objectCheckFlag is set to true, SYS/BIOS kernel
will call this function from within a Task switch hook and
each time a Task blocks or unblocks. SYS/BIOS provides a default
implementation of this function that computes the check value
for the static Task object fields and compares the resulting
check value against the stored value. The application can install
its own implementation of the object check function.
Here's an example Task object check function:
*.cfg
var Task = xdc.useModule('ti.sysbios.knl.Task');
// Enable Task object data integrity check
Task.objectCheckFlag = true;
// Install custom Task object check function
Task.objectCheckFxn = "&myCheckFunc";
*.c
#define ti_sysbios_knl_Task__internalaccess
#include <ti/sysbios/knl/Task.h>
Int myCheckFunc(Task_Handle handle, UInt32 checkValue)
{
UInt32 newCheckValue;
newCheckValue = Task_objectCheckValueFxn(handle);
if (newCheckValue != checkValue) {
// Return '-1' to indicate data corruption. SYS/BIOS kernel
// will raise an error.
return (-1);
}
return (0);
}
config Task_objectCheckValueFxn // module-wide |
|
Function called to compute Task object check value
DETAILS
If
objectCheckFlag is set to true, SYS/BIOS kernel
will call this function to compute the Task object's check value
each time a Task is created.
SYS/BIOS provides a default implementation of this function that
computes a 32-bit checksum for the static Task object fields (i.e.
Task object fields that do not change during the lifetime of the
Task). The application can install its own implementation of this
function.
Here's an example Task object check value computation function:
*.cfg
var Task = xdc.useModule('ti.sysbios.knl.Task');
// Enable Task object data integrity check
Task.objectCheckFlag = true;
// Install custom Task object check value function
Task.objectCheckValueFxn = "&myCheckValueFunc";
*.c
#define ti_sysbios_knl_Task__internalaccess
#include <ti/sysbios/knl/Task.h>
UInt32 myCheckValueFunc(Task_Handle taskHandle)
{
UInt64 checksum;
checksum = taskHandle->stackSize +
(uintptr_t)taskHandle->stack +
(uintptr_t)taskHandle->stackHeap +
#if defined(__IAR_SYSTEMS_ICC__)
(UInt64)taskHandle->fxn +
#else
(uintptr_t)taskHandle->fxn +
#endif
taskHandle->arg0 +
taskHandle->arg1 +
(uintptr_t)taskHandle->hookEnv +
taskHandle->vitalTaskFlag;
checksum = (checksum >> 32) + (checksum & 0xFFFFFFFF);
checksum = checksum + (checksum >> 32);
return ((UInt32)(~checksum));
}
Task_disable() // module-wide |
|
Disable the task scheduler
RETURNS
DETAILS
disable and
restore control Task scheduling.
disable disables all other Tasks from running until
restore is called. Hardware and Software interrupts
can still run.
disable and
restore allow you to ensure that
statements
that must be performed together during critical processing are not
preempted by other Tasks.
The value of the key returned is opaque to applications and is meant
to be passed to Task_restore().
In the following example, the critical section is
not preempted by any Tasks.
key = Task_disable();
`critical section`
Task_restore(key);
You can also use
disable and
restore to
create several Tasks and allow them to be invoked in
priority order.
disable calls can be nested.
CONSTRAINTS
Do not call any function that can cause the current task to block
within a
disable/
restore block. For example,
Semaphore_pend
(if timeout is non-zero),
sleep,
yield, and Memory_alloc can all
cause blocking.
Task_exit() // module-wide |
|
Terminate execution of the current task
DETAILS
Task_exit terminates execution of the current task, changing its mode
from
Mode_RUNNING to
Mode_TERMINATED. If all tasks
have been terminated, or if all remaining tasks have their
vitalTaskFlag attribute set to FALSE, then SYS/BIOS terminates the
program as a whole by calling the function System_exit with a status
code of 0.
Task_exit is automatically called whenever a task returns from its
top-level function.
Exit Hooks (see exitFxn in
HookSet) can be used to provide
functions that run whenever a task is terminated. The exitFxn Hooks
are called before the task has been blocked and marked
Mode_TERMINATED.
See
Hook Functions for more information.
Any SYS/BIOS function can be called from an Exit Hook function.
Calling
self within an Exit function returns the task
being exited. Your Exit function declaration should be similar to
the following:
A task switch occurs when calling Task_exit unless the program as a
whole is terminated
CONSTRAINTS
Task_exit cannot be called from a Swi or Hwi.
Task_exit cannot be called from the program's main() function.
Task_getIdleTask() // module-wide |
|
returns a handle to the idle task object (for core 0)
Task_getIdleTaskHandle() // module-wide |
|
returns a handle to the idle task object for the specified coreId
(should be used only in applications built with
ti.sysbios.BIOS.smpEnabled set to true)
NOTE
If this function is called in a non-SMP application, coreId should
always be 0.
Task_restore() // module-wide |
|
Restore Task scheduling state
Void Task_restore(UInt key);
ARGUMENTS
key
key to restore previous Task scheduler state
DETAILS
disable and
restore control Task scheduling
disable disables all other Tasks from running until
restore is called. Hardware and Software interrupts
can still run.
disable and
restore allow you to ensure that
statements
that must be performed together during critical processing are not
preempted.
In the following example, the critical section is not preempted
by any Tasks.
key = Task_disable();
`critical section`
Task_restore(key);
You can also use
disable and
restore to create
several Tasks and allow them to be performed in priority order.
disable calls can be nested.
restore returns with interrupts enabled if the key unlocks
the scheduler
CONSTRAINTS
Do not call any function that can cause the current task to block
within a
disable/
restore block. For example,
Semaphore_pend()
(if timeout is non-zero),
sleep,
yield, and Memory_alloc can all
cause blocking.
restore internally calls Hwi_enable() if the key passed
to it results in the unlocking of the Task scheduler (ie if this
is root Task_disable/Task_restore pair).
Task_self() // module-wide |
|
Returns a handle to the currently executing Task object
RETURNS
address of currently executing task object
DETAILS
Task_self returns the object handle for the currently executing task.
This function is useful when inspecting the object or when the current
task changes its own priority through
setPri.
No task switch occurs when calling Task_self.
Task_self will return NULL until Tasking is initiated at the end of
BIOS_start().
Task_selfMacro() // module-wide |
|
Returns a handle to the currently executing Task object
RETURNS
address of currently executing task object
DETAILS
Task_selfMacro is identical to
self but is implemented as
and inline macro.
Task_sleep() // module-wide |
|
Delay execution of the current task
Void Task_sleep(UInt32 nticks);
ARGUMENTS
nticks
number of system clock ticks to sleep
DETAILS
Task_sleep changes the current task's mode from
Mode_RUNNING
to
Mode_BLOCKED, and delays its execution for nticks
increments of the
system clock. The actual time
delayed can be up to 1 system clock tick less than nticks due to
granularity in system timekeeping and the time elapsed per
tick is determined by
Clock_tickPeriod.
After the specified period of time has elapsed, the task reverts to
the
Mode_READY mode and is scheduled for execution.
A task switch always occurs when calling Task_sleep if nticks > 0.
CONSTRAINTS
Task_sleep cannot be called from a Swi or Hwi, or within a
disable /
restore block.
Task_sleep cannot be called from the program's main() function.
Task_sleep should not be called from within an Idle function. Doing
so prevents analysis tools from gathering run-time information.
nticks cannot be
BIOS_WAIT_FOREVER.
Task_yield() // module-wide |
|
Yield processor to equal priority task
DETAILS
Task_yield yields the processor to another task of equal priority.
A task switch occurs when you call Task_yield if there is an equal
priority task ready to run.
Tasks of higher priority preempt the currently running task without
the need for a call to Task_yield. If only lower-priority tasks are
ready to run when you call Task_yield, the current task continues to
run. Control does not pass to a lower-priority task.
CONSTRAINTS
When called within an Hwi, the code sequence calling Task_yield
must be invoked by the Hwi dispatcher.
Task_yield cannot be called from the program's main() function.
Module-Wide Built-Ins |
|
// Get this module's unique id
Bool Task_Module_startupDone();
// Test if this module has completed startup
// The heap from which this module allocates memory
Bool Task_Module_hasMask();
// Test whether this module has a diagnostics mask
Bits16 Task_Module_getMask();
// Returns the diagnostics mask for this module
Void Task_Module_setMask(Bits16 mask);
// Set the diagnostics mask for this module
Instance Object Types |
|
typedef struct Task_Object Task_Object;
// Opaque internal representation of an instance object
// Client reference to an instance object
typedef struct Task_Struct Task_Struct;
// Opaque client structure large enough to hold an instance object
// Convert this instance structure pointer into an instance handle
// Convert this instance handle into an instance structure pointer
Instance Config Parameters |
|
typedef struct Task_Params {
// Instance config-params structure
// Common per-instance configs
UInt affinity;
// The core which this task is to run on. Default is Task_AFFINITY_NONE
UArg arg0;
// Task function argument. Default is 0
UArg arg1;
// Task function argument. Default is 0
Ptr env;
// Environment data struct
Int priority;
// Task priority (0 to Task.numPriorities-1, or -1).
Default is 1
Ptr stack;
// Task stack pointer. Default = null
// Mem heap used for dynamically created task stack
SizeT stackSize;
// Task stack size in MAUs
Bool vitalTaskFlag;
// Exit system immediately when the last task with this
flag set to TRUE has terminated
} Task_Params;
// Initialize this config-params structure with supplier-specified defaults before instance creation
config Task_Params.affinity // instance |
|
The core which this task is to run on. Default is Task_AFFINITY_NONE
DETAILS
If there is a compelling reason for a task to be pinned to a
particular core, then setting 'affinity' to the corresponding core
id will force the task to only be run on that core.
The default affinity is inherited from
Task.defaultAffinity
which in turn defaults to
Task_AFFINITY_NONE,
which means the task can be run on either core.
Furthermore, Task_AFFINITY_NONE implies that the task can be moved
from core to core as deemed necessary by the Task scheduler in order
to keep the two highest priority ready tasks running simultaneously.
config Task_Params.arg0 // instance |
|
Task function argument. Default is 0
config Task_Params.arg1 // instance |
|
Task function argument. Default is 0
config Task_Params.env // instance |
|
Environment data struct
config Task_Params.priority // instance |
|
Task priority (0 to Task.numPriorities-1, or -1).
Default is 1
config Task_Params.stack // instance |
|
Task stack pointer. Default = null
DETAILS
Null indicates that the stack is to be allocated by create().
STATIC CONFIGURATION USAGE WARNING
This parameter can only be assigned a non-null value
during runtime Task creates or constructs.
Static configuration of the 'stack' parameter is not supported.
Note that if
BIOS.runtimeCreatesEnabled is set to false, then the user is required
to provide the stack buffer when constructing the Task object.
If 'stack' is not provided, then Task_construct() will fail.
config Task_Params.stackHeap // instance |
|
Mem heap used for dynamically created task stack
DETAILS
The default value of NULL means that the module config
defaultStackHeap is used.
config Task_Params.stackSize // instance |
|
Task stack size in MAUs
DETAILS
The default value of 0 means that the module config
defaultStackSize is used.
config Task_Params.vitalTaskFlag // instance |
|
Exit system immediately when the last task with this
flag set to TRUE has terminated
DETAILS
Default is true.
Runtime Instance Creation |
|
// Allocate and initialize a new instance object and return its handle
// Initialize a new instance object inside the provided structure
ARGUMENTS
fxn
Task Function
params
per-instance config params, or NULL to select default values (target-domain only)
eb
active error-handling block, or NULL to select default policy (target-domain only)
DETAILS
Task_create creates a new task object. If successful, Task_create
returns the handle of the new task object. If unsuccessful,
Task_create returns NULL unless it aborts.
The fxn parameter uses the
FuncPtr type to pass a pointer to
the function the Task object should run. For example, if myFxn is a
function in your program, your C code can create a Task object
to call that
function as follows:
Task_Params taskParams;
// Create task with priority 15
Task_Params_init(&taskParams);
taskParams.stackSize = 512;
taskParams.priority = 15;
Task_create((Task_FuncPtr)myFxn, &taskParams, &eb);
The following statements statically create a task in the
configuration file:
var params = new Task.Params;
params.instance.name = "tsk0";
params.arg0 = 1;
params.arg1 = 2;
params.priority = 1;
Task.create('&tsk0_func', params);
If NULL is passed instead of a pointer to an actual Task_Params
struct, a
default set of parameters is used. The "eb" is an error block that
you can use
to handle errors that may occur during Task object creation.
The newly created task is placed in
Mode_READY mode, and is
scheduled to begin concurrent execution of the following function
call:
As a result of being made ready to run, the task runs any
application-wide Ready functions that have been specified.
Task_exit is automatically called if and when the task returns
from fxn.
Create Hook Functions
You can specify application-wide Create hook functions in your config
file that run whenever a task is created. This includes tasks that
are created statically and those created dynamically using
Task_create.
For Task objects created statically, Create functions are called
during the Task module initialization phase of the program startup
process prior to main().
For Task objects created dynamically, Create functions
are called after the task handle has been initialized but before the
task has been placed on its ready queue.
Any SYS/BIOS function can be called from Create functions.
SYS/BIOS passes the task handle of the task being created to each of
the Create functions.
All Create function declarations should be similar to this:
Void myCreateFxn(Task_Handle task);
CONSTRAINTS
- The fxn parameter and the name attribute cannot be NULL.
- The priority attribute must be less than or equal to
(numPriorities - 1) and greater than or equal to one (1)
(priority 0 is owned by the Idle task).
- The priority can be set to -1 for tasks that will not execute
until another task changes the priority to a positive value.
- The stackHeap attribute must identify a valid memory Heap.
Instance Deletion |
|
// Finalize and free this previously allocated instance object, setting the referenced handle to NULL
// Finalize the instance object inside the provided structure
Task_getAffinity() // instance |
|
Return task's core affinity (should be used only in applications built
with ti.sysbios.BIOS.smpEnabled set to true)
ARGUMENTS
handle
handle of a previously-created Task instance object
RETURNS
task's current core affinity
Task_getEnv() // instance |
|
Get task environment pointer
ARGUMENTS
handle
handle of a previously-created Task instance object
RETURNS
task environment pointer
DETAILS
Task_getEnv returns the environment pointer of the specified task. The
environment pointer references an arbitrary application-defined data
structure.
If your program uses multiple hook sets,
getHookContext
allows you to get environment pointers you have set for a particular
hook set and Task object combination.
Task_getFunc() // instance |
|
Get Task function and arguments
ARGUMENTS
handle
handle of a previously-created Task instance object
arg0
pointer for returning Task's first function argument
arg1
pointer for returning Task's second function argument
RETURNS
Task function
DETAILS
If either arg0 or arg1 is NULL, then the corresponding argument is not
returned.
Task_getHookContext() // instance |
|
Get hook set's context for a task
ARGUMENTS
handle
handle of a previously-created Task instance object
id
hook set ID
RETURNS
hook set context for task
DETAILS
For example, this C code gets the HookContext, prints it,
and sets a new value for the HookContext.
Ptr pEnv;
Task_Handle myTask;
Int myHookSetId1;
pEnv = Task_getHookContext(task, myHookSetId1);
System_printf("myEnd1: pEnv = 0x%lx, time = %ld\n",
(ULong)pEnv, (ULong)Timestamp_get32());
Task_setHookContext(task, myHookSetId1, (Ptr)0xc0de1);
See
Hook Functions for more details.
Task_getMode() // instance |
|
Retrieve the Mode of a task
ARGUMENTS
handle
handle of a previously-created Task instance object
Task_getPri() // instance |
|
Get task priority
ARGUMENTS
handle
handle of a previously-created Task instance object
RETURNS
task priority
DETAILS
Task_getPri returns the priority of the referenced task.
Task_setAffinity() // instance |
|
Set task's core affinity (should be used only in applications built
with BIOS.smpEnabled set to true)
UInt Task_setAffinity(
Task_Handle handle,
UInt coreId);
ARGUMENTS
handle
handle of a previously-created Task instance object
RETURNS
task's previous core affinity
DETAILS
If the new core ID is different than the current core affinity
a reschedule will be performed immediately.
CONSTRAINTS
Must NOT be called with interrupts disabled
(ie within a Hwi_disable()/Hwi_restore() block).
Must NOT be called with tasking disabled
(ie within a Task_disable()/Task_restore() block).
Task_setEnv() // instance |
|
Set task environment
ARGUMENTS
handle
handle of a previously-created Task instance object
env
task environment pointer
DETAILS
Task_setEnv sets the task environment pointer to env. The
environment pointer references an arbitrary application-defined
data structure.
If your program uses multiple hook sets,
setHookContext
allows you to set environment pointers for any
hook set and Task object combination.
Task_setHookContext() // instance |
|
Set hook instance's context for a task
Void Task_setHookContext(
Task_Handle handle,
Int id,
Ptr hookContext);
ARGUMENTS
handle
handle of a previously-created Task instance object
id
hook set ID
hookContext
value to write to context
DETAILS
For example, this C code gets the HookContext, prints it,
and sets a new value for the HookContext.
Ptr pEnv;
Task_Handle myTask;
Int myHookSetId1;
pEnv = Task_getHookContext(task, myHookSetId1);
System_printf("myEnd1: pEnv = 0x%lx, time = %ld\n",
(ULong)pEnv, (ULong)Timestamp_get32());
Task_setHookContext(task, myHookSetId1, (Ptr)0xc0de1);
See
Hook Functions for more details.
Task_setPri() // instance |
|
Set a task's priority
ARGUMENTS
handle
handle of a previously-created Task instance object
newpri
task's new priority
RETURNS
task's old priority
DETAILS
Task_setpri sets the execution priority of task to newpri, and returns
that task's old priority value. Raising or lowering a task's priority
does not necessarily force preemption and re-scheduling of the caller:
tasks in the
Mode_BLOCKED mode remain suspended despite a
change in priority; and tasks in the
Mode_READY mode gain
control only if their new priority is greater than that of the
currently executing task.
newpri should be set to a value greater than or equal to 1 and
less than or equal to (
numPriorities - 1). newpri can also
be set to -1 which puts the the task into the INACTIVE state and the
task will not run until its priority is raised at a later time by
another task. Priority 0 is reserved for the idle task.
If newpri equals (
numPriorities - 1), execution of the task
effectively locks out all other program activity, except for the
handling of interrupts.
The current task can change its own priority (and possibly preempt its
execution) by passing the output of
self as the value of the
task parameter.
A context switch occurs when calling Task_setpri if a currently
running task priority is set lower than the priority of another
currently ready task, or if another ready task is made to have a
higher priority than the currently running task.
Task_setpri can be used for mutual exclusion.
If a task's new priority is different than its previous priority,
then its relative placement in its new ready task priority
queue can be different than the one it was removed from. This can
effect the relative order in which it becomes the running task.
The effected task is placed at the head of its new priority queue
if it is the currently running task. Otherwise it is placed at
at the end of its new task priority queue.
CONSTRAINTS
newpri must be a value between 1 and (
numPriorities - 1) or -1.
The task cannot be in the
Mode_TERMINATED mode.
The new priority should not be zero (0). This priority level is
reserved for the Idle task.
Task_stat() // instance |
|
Retrieve the status of a task
ARGUMENTS
handle
handle of a previously-created Task instance object
statbuf
pointer to task status structure
DETAILS
Task_stat retrieves attribute values and status information about a
task.
Status information is returned through statbuf, which references a
structure of type
Stat.
When a task is preempted by a software or hardware interrupt, the task
execution mode returned for that task by Task_stat is still
Mode_RUNNING because the task runs when the preemption ends.
The current task can inquire about itself by passing the output of
self as the first argument to Task_stat. However, the task
stack pointer (sp) in the
Stat structure is the value from
the previous context switch.
Task_stat has a non-deterministic execution time. As such, it is not
recommended to call this API from Swis or Hwis.
CONSTRAINTS
statbuf cannot be NULL;
Instance Built-Ins |
|
Int Task_Object_count();
// The number of statically-created instance objects
// The handle of the i-th statically-created instance object (array == NULL)
// The handle of the first dynamically-created instance object, or NULL
// The handle of the next dynamically-created instance object, or NULL
// The heap used to allocate dynamically-created instance objects
// The label associated with this instance object
// The name of this instance object
const Task.AFFINITY_NONE |
|
"Don't care" task affinity
const Task.AFFINITY_NONE = ~(0);
C SYNOPSIS
enum Task.Mode |
|
Task execution modes
values of type Task.Mode
const Task.Mode_RUNNING;
// Task is currently executing
const Task.Mode_READY;
// Task is scheduled for execution
const Task.Mode_BLOCKED;
// Task is suspended from execution
const Task.Mode_TERMINATED;
// Task is terminated from execution
const Task.Mode_INACTIVE;
// Task is on inactive task list
DETAILS
These enumerations are the range of modes or states that
a task can be in. A task's current mode can be gotten using
stat.
C SYNOPSIS
struct Task.HookSet |
|
Task hook set type definition
var obj = new Task.HookSet;
obj.registerFxn = Void(*)(Int) ...
DETAILS
Sets of hook functions can be specified for the Task module.
See
Hook Functions for details.
C SYNOPSIS
struct Task.Stat |
|
Task Status Buffer
var obj = new Task.Stat;
obj.priority = Int ...
// Task priority
obj.stack = Ptr ...
// Task stack
obj.stackSize = SizeT ...
// Task stack size
// Heap used to alloc stack
obj.env = Ptr ...
// Global environment struct
// Task's current mode
obj.sp = Ptr ...
// Task's current stack pointer
obj.used = SizeT ...
// Maximum number of bytes used on stack
DETAILS
Passed to and filled in by
stat;
C SYNOPSIS
config Task.A_badAffinity // module-wide |
|
Asserted in Task_setAffinity
msg: "A_badAffinity: Invalid affinity."
};
C SYNOPSIS
config Task.A_badPriority // module-wide |
|
Asserted in Task_create
msg: "A_badPriority: An invalid task priority was used."
};
C SYNOPSIS
config Task.A_badTaskState // module-wide |
|
Asserted in Task_delete
msg: "A_badTaskState: Can't delete a task in RUNNING state."
};
C SYNOPSIS
config Task.A_badThreadType // module-wide |
|
Asserted in Task_create and Task_delete
msg: "A_badThreadType: Cannot create/delete a task from Hwi or Swi thread."
};
C SYNOPSIS
config Task.A_badTimeout // module-wide |
|
Asserted in Task_sleep
msg: "A_badTimeout: Can't sleep FOREVER."
};
C SYNOPSIS
config Task.A_invalidCoreId // module-wide |
|
Asserted in Task_getIdleTaskHandle
msg: "A_invalidCoreId: Cannot pass a non-zero CoreId in a non-SMP application."
};
C SYNOPSIS
config Task.A_noPendElem // module-wide |
|
Asserted in Task_delete
msg: "A_noPendElem: Not enough info to delete BLOCKED task."
};
C SYNOPSIS
config Task.A_sleepTaskDisabled // module-wide |
|
Asserted in Task_sleep
msg: "A_sleepTaskDisabled: Cannot call Task_sleep() while the Task scheduler is disabled."
};
C SYNOPSIS
config Task.A_taskDisabled // module-wide |
|
Asserted in Task_create
msg: "A_taskDisabled: Cannot create a task when tasking is disabled."
};
C SYNOPSIS
config Task.E_deleteNotAllowed // module-wide |
|
msg: "E_deleteNotAllowed: Task 0x%x."
};
C SYNOPSIS
config Task.E_moduleStateCheckFailed // module-wide |
|
Error raised when the check value of the Task module state does not
match the stored check value (computed during startup). This indicates
that the Task module state was corrupted
msg: "E_moduleStateCheckFailed: Task module state data integrity check failed."
};
C SYNOPSIS
config Task.E_objectCheckFailed // module-wide |
|
Error raised when the check value of the Task object does not match
the stored check value (computed during startup). This indicates
that the Task object was corrupted
msg: "E_objectCheckFailed: Task 0x%x object data integrity check failed."
};
C SYNOPSIS
config Task.E_spOutOfBounds // module-wide |
|
Error raised when a task's stack pointer (SP) does not point
somewhere within the task's stack
msg: "E_spOutOfBounds: Task 0x%x stack error, SP = 0x%x."
};
DETAILS
This error is raised by kernel's stack checking function. This
function checks the SPs before every task switch to make sure
they point within the task's stack.
The stack checking logic is enabled by the
initStackFlag and
checkStackFlag configuration parameters. If both of these
flags are set to true, the kernel will validate the stack pointers.
C SYNOPSIS
config Task.E_stackOverflow // module-wide |
|
Error raised when a stack overflow (or corruption) is detected
msg: "E_stackOverflow: Task 0x%x stack overflow."
};
DETAILS
This error is raised by kernel's stack checking function. This
function checks the stacks before every task switch to make sure
that reserved word at top of stack has not been modified.
The stack checking logic is enabled by the
initStackFlag and
checkStackFlag configuration parameters. If both of these
flags are set to true, the kernel will validate the stacks.
C SYNOPSIS
config Task.LD_block // module-wide |
|
Logged when a task is blocked (ie Semaphore_pend())
msg: "LD_block: tsk: 0x%x, func: 0x%x"
};
C SYNOPSIS
config Task.LD_exit // module-wide |
|
Logged when Task functions fall thru the bottom
or when Task_exit() is explicitly called
msg: "LD_exit: tsk: 0x%x, func: 0x%x"
};
C SYNOPSIS
config Task.LD_ready // module-wide |
|
Logged when a task is made ready to run (ie Semaphore_post())
msg: "LD_ready: tsk: 0x%x, func: 0x%x, pri: %d"
};
C SYNOPSIS
config Task.LM_noWork // module-wide |
|
Logged when no scheduling work was found
msg: "LD_noWork: coreId: %d, curSetLocal: %d, curSetX: %d, curMaskLocal: %d"
};
C SYNOPSIS
config Task.LM_schedule // module-wide |
|
Logged on every task schedule entry
msg: "LD_schedule: coreId: %d, workFlag: %d, curSetLocal: %d, curSetX: %d, curMaskLocal: %d"
};
C SYNOPSIS
config Task.LM_setAffinity // module-wide |
|
Logged on calls to Task_setAffinity
msg: "LM_setAffinity: tsk: 0x%x, func: 0x%x, oldCore: %d, oldAffinity %d, newAffinity %d"
};
C SYNOPSIS
config Task.LM_setPri // module-wide |
|
Logged on calls to Task_setPri
msg: "LM_setPri: tsk: 0x%x, func: 0x%x, oldPri: %d, newPri %d"
};
C SYNOPSIS
config Task.LM_sleep // module-wide |
|
Logged on calls to Task_sleep
msg: "LM_sleep: tsk: 0x%x, func: 0x%x, timeout: %d"
};
C SYNOPSIS
config Task.LM_switch // module-wide |
|
Logged on every task switch
msg: "LM_switch: oldtsk: 0x%x, oldfunc: 0x%x, newtsk: 0x%x, newfunc: 0x%x"
};
C SYNOPSIS
config Task.LM_yield // module-wide |
|
Logged on calls to Task_yield
msg: "LM_yield: tsk: 0x%x, func: 0x%x, currThread: %d"
};
C SYNOPSIS
config Task.allBlockedFunc // module-wide |
|
Function to call while all tasks are blocked
Task.allBlockedFunc = Void(*)(Void) null;
DETAILS
This function will be called repeatedly while no tasks are
ready to run.
Ordinarily (in applications that have tasks ready to run at startup),
the function will run in the context of the last task to block.
In an application where there are no tasks ready to run
when BIOS_start() is called, the allBlockedFunc function is
called within the BIOS_start() thread which runs on the system/ISR
stack.
By default, allBlockedFunc is initialized to point to an internal
function that simply returns.
By adding the following lines to the config script, the Idle
functions will run whenever all tasks are blocked:
Task.enableIdleTask = false;
Task.allBlockedFunc = Idle.run;
SEE
CONSTRAINTS
The configured allBlockedFunc is designed to be called repeatedly.
It must return in order for the task scheduler to check if all
tasks are STILL blocked and if not, run the highest priority task
currently ready to run.
The configured allBlockedFunc function is called with interrupts
disabled. If your function must run with interrupts enabled,
surround the body of your code with Hwi_enable()/Hwi_restore()
function calls per the following example:
Void yourFunc() {
UInt hwiKey;
hwiKey = Hwi_enable();
... // your code here
Hwi_restore(hwiKey);
}
C SYNOPSIS
config Task.checkStackFlag // module-wide |
|
Check 'from' and 'to' task stacks before task context switch
Task.checkStackFlag = Bool true;
DETAILS
The check consists of testing the top of stack value against
its initial value (see
initStackFlag). If it is no
longer at this value, the assumption is that the task has
overrun its stack. If the test fails, then the
E_stackOverflow error is raised.
Default is true.
To enable or disable full stack checking, you should set both this
flag and the
ti.sysbios.hal.Hwi.checkStackFlag.
NOTE
Enabling stack checking will add some interrupt latency because the
checks are made within the Task scheduler while interrupts are
disabled.
C SYNOPSIS
config Task.defaultStackHeap // module-wide |
|
Default Mem heap used for all dynamically created task stacks
DETAILS
Default is null.
C SYNOPSIS
config Task.defaultStackSize // module-wide |
|
Default stack size (in MAUs) used for all tasks
Task.defaultStackSize = SizeT undefined;
DETAILS
Default is obtained from the family-specific TaskSupport module
(e.g.
ti.sysbios.family.arm.m3.TaskSupport,
ti.sysbios.family.c62.TaskSupport).
C SYNOPSIS
config Task.deleteTerminatedTasks // module-wide |
|
Automatically delete terminated tasks
Task.deleteTerminatedTasks = Bool false;
DETAILS
If this feature is enabled, an Idle function is installed that
deletes dynamically created Tasks that have terminated either
by falling through their task function or by explicitly calling
Task_exit().
A list of terminated Tasks that were created dynmically is
maintained internally. Each invocation of the installed Idle function
deletes the first Task on this list. This one-at-a-time process
continues until the list is empty.
NOTE
This feature is disabled by default.
WARNING
When this feature is enabled, an error will be raised if the user's
application attempts to delete a terminated task. If a terminated task
has already been automatically deleted and THEN the user's application
attempts to delete it (ie: using a stale Task handle), the results are
undefined and probably catastrophic!
C SYNOPSIS
config Task.hooks // module-wide |
|
Const array that holds the HookSet objects
DETAILS
See
Hook Functions for details about HookSets.
C SYNOPSIS
config Task.initStackFlag // module-wide |
|
Initialize stack with known value for stack checking at runtime
(see checkStackFlag).
If this flag is set to false, while the
ti.sysbios.hal.Hwi.checkStackFlag is set to true, only the
first byte of the stack is initialized
Task.initStackFlag = Bool true;
DETAILS
This is also useful for inspection of stack in debugger or core
dump utilities.
Default is true.
C SYNOPSIS
config Task.moduleStateCheckFlag // module-wide |
|
Perform a runtime data integrity check on the Task module state
Task.moduleStateCheckFlag = Bool false;
DETAILS
This configuration parameter determines whether a data integrity
check is performed on the Task module state in order to detect
data corruption.
If this field is set to true, a check value of the static fields in
the Task module state (i.e. fields that do not change during the
lifetime of the application) is computed during startup. The
computed check value is stored for use by the Task module state check
function. The application can implement its own check value
computation function (see
moduleStateCheckValueFxn).
By default, SYS/BIOS installs a check value computation function that
computes a 32-bit checksum of the static fields in the Task module
state.
The module state check function (see
moduleStateCheckFxn)
is called from within the Task_disable() function. The application
can provide its own implementation of this function. By default,
SYS/BIOS installs a check function that computes the check value
for select module state fields and compares the resulting check
value against the stored value.
If the module state check function returns a '-1' (i.e. check failed),
then the SYS/BIOS kernel will raise an error.
C SYNOPSIS
config Task.moduleStateCheckFxn // module-wide |
|
Function called to perform module state data integrity check
DETAILS
If
moduleStateCheckFlag is set to true, SYS/BIOS kernel
will call this function each time Task_disable() function is called.
SYS/BIOS provides a default implementation of this function that
computes the check value for the static module state fields and
compares the resulting check value against the stored value. In
addition, the check function validates some of the pointers used
by the Task scheduler. The application can install its own
implementation of the module state check function.
Here's an example module state check function:
*.cfg
var Task = xdc.useModule('ti.sysbios.knl.Task');
// Enable Task module state data integrity check
Task.moduleStateCheckFlag = true;
// Install custom module state check function
Task.moduleStateCheckFxn = "&myCheckFunc";
*.c
#define ti_sysbios_knl_Task__internalaccess
#include <ti/sysbios/knl/Task.h>
Int myCheckFunc(Task_Module_State *moduleState, UInt32 checkValue)
{
UInt32 newCheckValue;
newCheckValue = Task_moduleStateCheckValueFxn(moduleState);
if (newCheckValue != checkValue) {
// Return '-1' to indicate data corruption. SYS/BIOS kernel
// will raise an error.
return (-1);
}
return (0);
}
C SYNOPSIS
config Task.moduleStateCheckValueFxn // module-wide |
|
Function called to compute module state check value
DETAILS
If
moduleStateCheckFlag is set to true, SYS/BIOS kernel
will call this function during startup to compute the Task module
state's check value.
SYS/BIOS provides a default implementation of this function that
computes a 32-bit checksum for the static module state fields (i.e.
module state fields that do not change during the lifetime of the
application). The application can install its own implementation
of this function.
Here's an example module state check value computation function:
*.cfg
var Task = xdc.useModule('ti.sysbios.knl.Task');
// Enable Task module state data integrity check
Task.moduleStateCheckFlag = true;
// Install custom module state check value function
Task.moduleStateCheckValueFxn = "&myCheckValueFunc";
*.c
#define ti_sysbios_knl_Task__internalaccess
#include <ti/sysbios/knl/Task.h>
UInt32 myCheckValueFunc(Task_Module_State *moduleState)
{
UInt64 checksum;
checksum = (uintptr_t)moduleState->readyQ +
(uintptr_t)moduleState->smpCurSet +
(uintptr_t)moduleState->smpCurMask +
(uintptr_t)moduleState->smpCurTask +
(uintptr_t)moduleState->smpReadyQ +
(uintptr_t)moduleState->idleTask +
(uintptr_t)moduleState->constructedTasks;
checksum = (checksum >> 32) + (checksum & 0xFFFFFFFF);
checksum = checksum + (checksum >> 32);
return ((UInt32)(~checksum));
}
C SYNOPSIS
config Task.numPriorities // module-wide |
|
Number of Task priorities supported. Default is 16
Task.numPriorities = UInt 16;
DETAILS
The maximum number of priorities supported is
target specific and depends on the number of
bits in a UInt data type. For 6x and ARM devices
the maximum number of priorities is therefore 32.
For 28x, 55x, and MSP430 devices, the maximum number of
priorities is 16.
C SYNOPSIS
config Task.objectCheckFlag // module-wide |
|
Perform a runtime data integrity check on each Task object
Task.objectCheckFlag = Bool false;
DETAILS
This configuration parameter determines whether a data integrity
check is performed on each Task object in the system in order to detect
data corruption.
If this field is set to true, a check value of the static fields in
the Task object (i.e. fields that do not change during the lifetime
of the Task) is computed when the Task is created. The computed check
value is stored for use by the Task object check function. The
application can implement its own check value computation function
(see
objectCheckValueFxn). By default, SYS/BIOS installs a
check value computation function that computes a 32-bit checksum of
the static fields in the Task object.
The Task object check function (see
objectCheckFxn)
is called from within a Task switch hook if stack checking
(see
checkStackFlag) is enabled. It is also called when
a task blocks or unblocks. The application can provide its own
implementation of this function. By default, SYS/BIOS installs a
check function that computes the check value for select Task
object fields and compares the resulting check value against the
stored value.
If the Task object check function returns a '-1' (i.e. check failed),
then the SYS/BIOS kernel will raise an error.
C SYNOPSIS
config Task.objectCheckFxn // module-wide |
|
Function called to perform Task object data integrity check
DETAILS
If
objectCheckFlag is set to true, SYS/BIOS kernel
will call this function from within a Task switch hook and
each time a Task blocks or unblocks. SYS/BIOS provides a default
implementation of this function that computes the check value
for the static Task object fields and compares the resulting
check value against the stored value. The application can install
its own implementation of the object check function.
Here's an example Task object check function:
*.cfg
var Task = xdc.useModule('ti.sysbios.knl.Task');
// Enable Task object data integrity check
Task.objectCheckFlag = true;
// Install custom Task object check function
Task.objectCheckFxn = "&myCheckFunc";
*.c
#define ti_sysbios_knl_Task__internalaccess
#include <ti/sysbios/knl/Task.h>
Int myCheckFunc(Task_Handle handle, UInt32 checkValue)
{
UInt32 newCheckValue;
newCheckValue = Task_objectCheckValueFxn(handle);
if (newCheckValue != checkValue) {
// Return '-1' to indicate data corruption. SYS/BIOS kernel
// will raise an error.
return (-1);
}
return (0);
}
C SYNOPSIS
config Task.objectCheckValueFxn // module-wide |
|
Function called to compute Task object check value
DETAILS
If
objectCheckFlag is set to true, SYS/BIOS kernel
will call this function to compute the Task object's check value
each time a Task is created.
SYS/BIOS provides a default implementation of this function that
computes a 32-bit checksum for the static Task object fields (i.e.
Task object fields that do not change during the lifetime of the
Task). The application can install its own implementation of this
function.
Here's an example Task object check value computation function:
*.cfg
var Task = xdc.useModule('ti.sysbios.knl.Task');
// Enable Task object data integrity check
Task.objectCheckFlag = true;
// Install custom Task object check value function
Task.objectCheckValueFxn = "&myCheckValueFunc";
*.c
#define ti_sysbios_knl_Task__internalaccess
#include <ti/sysbios/knl/Task.h>
UInt32 myCheckValueFunc(Task_Handle taskHandle)
{
UInt64 checksum;
checksum = taskHandle->stackSize +
(uintptr_t)taskHandle->stack +
(uintptr_t)taskHandle->stackHeap +
#if defined(__IAR_SYSTEMS_ICC__)
(UInt64)taskHandle->fxn +
#else
(uintptr_t)taskHandle->fxn +
#endif
taskHandle->arg0 +
taskHandle->arg1 +
(uintptr_t)taskHandle->hookEnv +
taskHandle->vitalTaskFlag;
checksum = (checksum >> 32) + (checksum & 0xFFFFFFFF);
checksum = checksum + (checksum >> 32);
return ((UInt32)(~checksum));
}
C SYNOPSIS
metaonly config Task.common$ // module-wide |
|
Common module configuration parameters
DETAILS
All modules have this configuration parameter. Its name
contains the '$' character to ensure it does not conflict with
configuration parameters declared by the module. This allows
new configuration parameters to be added in the future without
any chance of breaking existing modules.
metaonly config Task.defaultAffinity // module-wide |
|
Default core affinity for newly created tasks
DETAILS
Default is Task_AFFINITY_NONE, meaning don't care.
metaonly config Task.defaultStackSection // module-wide |
|
Default memory section used for all statically created task stacks
Task.defaultStackSection = String undefined;
DETAILS
The default stack section name is target/device specific.
For C6x targets it is ".far:taskStackSection".
For C28x targets it is ".taskStackSection".
For GNU targets it is ".bss".
For all other targets it is ".bss:taskStackSection".
By default, all statically created task stacks are grouped together
into the defaultStackSection and placed where ever
the target specific defaultStackSection base section name
(ie .bss, .far, .ebss) is placed.
To place all task stacks into a different memory segment,
add the following to your config script:
Program.sectMap[Task.defaultStackSection] = new Program.SectionSpec();
Program.sectMap[Task.defaultStackSection].loadSegment =
"yourMemorySegment";
To group all task stacks into a different section AND place that
section into a specific memory segment, add the following to your
config script:
Task.defaultStackSection = ".yourSectionName";
Program.sectMap[Task.defaultStackSection] = new Program.SectionSpec();
Program.sectMap[Task.defaultStackSection].loadSegment =
"yourMemorySegment";
Where "yourSectionName" can be just about anything, and
"yourMemorySegment"
must be a memory segment defined for your board.
metaonly config Task.enableIdleTask // module-wide |
|
Create a task (of priority 0) to run the Idle functions in
Task.enableIdleTask = Bool true;
DETAILS
When set to true, a task is created that continuously calls the
Idle_run() function, which, in turn calls each of
the configured Idle functions.
When set to false, no Idle Task is created and it is up to the
user to call the Idle_run() function if the configured Idle
functions need to be run. Or, by adding the following lines to
the config script, the Idle functions will run whenever all
tasks are blocked (
Task.allBlockedFunc):
Task.enableIdleTask = false;
Task.allBlockedFunc = Idle.run;
Default is true.
SEE
metaonly config Task.idleTaskStackSection // module-wide |
|
Idle task stack section
Task.idleTaskStackSection = String undefined;
DETAILS
Default is inherited from module config defaultStackSection;
metaonly config Task.idleTaskStackSize // module-wide |
|
Idle task stack size in MAUs
Task.idleTaskStackSize = SizeT undefined;
DETAILS
Default is inherited from module config defaultStackSize.
metaonly config Task.idleTaskVitalTaskFlag // module-wide |
|
Idle task's vitalTaskFlag.
(see vitalTaskFlag)
Task.idleTaskVitalTaskFlag = Bool true;
DETAILS
Default is true.
metaonly config Task.minimizeLatency // module-wide |
|
Reduce interrupt latency by enabling interrupts
within the Task scheduler
Task.minimizeLatency = Bool false;
DETAILS
By default, interrupts are disabled within certain critical
sections of the task scheduler when switching to a different
task thread. This default behavior guarantees that a task stack
will only ever absorb ONE ISR context. Nested interrupts all run
on the shared Hwi stack.
While most users find this behavior desirable, the resulting
impact on interrupt latency is too great for certain applications.
By setting this parameter to 'true', the worst case interrupt latency
imposed by the kernel will be reduced but will result in task stacks
needing to be sized to accommodate one additional interrupt context.
See sections 3.5.3 and 7.5 of the BIOS User's Guide for further
discussions regarding task stack sizing.
Also see
BIOS.logsEnabled
and the discussion on Task hooks.
metaonly Task.addHookSet() // module-wide |
|
addHookSet is used in a config file to add a hook set
ARGUMENTS
hook
structure of type HookSet
DETAILS
Configures a set of hook functions for the
Task module. Each set contains these hook functions:
- Register: A function called before any statically created tasks
are initialized at runtime. The register hook is called at boot time
before main() and before interrupts are enabled.
- Create: A function that is called when a task is created.
This includes tasks that are created statically and those
created dynamically using create or construct.
The create hook is called outside of a Task_disable/enable block and
before the task has been added to the ready list.
- Ready: A function that is called when a task becomes ready to run.
The ready hook is called from within a Task_disable/enable block with
interrupts enabled.
- Switch: A function that is called just before a task switch
occurs. The 'prev' and 'next' task handles are passed to the Switch
hook. 'prev' is set to NULL for the initial task switch that occurs
during SYS/BIOS startup. The Switch hook is called from within a
Task_disable/enable block with interrupts enabled.
- Exit: A function that is called when a task exits using
exit. The exit hook is passed the handle of the exiting
task. The exit hook is called outside of a Task_disable/enable block
and before the task has been removed from the kernel lists.
- Delete: A function that is called when any task is deleted at
run-time with delete. The delete hook is called outside
of a Task_disable/enable block.
Hook functions can only be configured statically.
See
Hook Functions for more details.
HookSet structure elements may be omitted, in which case those
elements will not exist.
For example, the following configuration code defines a HookSet:
// Hook Set 1
Task.addHookSet({
registerFxn: '&myRegister1',
createFxn: '&myCreate1',
readyFxn: '&myReady1',
switchFxn: '&mySwitch1',
exitFxn: '&myExit1',
deleteFxn: '&myDelete1'
});
metaonly Task.getNickName() // module-wide |
|
Task.getNickName(Any tskView) returns String
Instance Config Parameters |
|
var params = new Task.Params;
// Instance config-params object
params.affinity = UInt undefined;
// The core which this task is to run on. Default is Task_AFFINITY_NONE
params.arg0 = UArg 0;
// Task function argument. Default is 0
params.arg1 = UArg 0;
// Task function argument. Default is 0
params.env = Ptr null;
// Environment data struct
params.priority = Int 1;
// Task priority (0 to Task.numPriorities-1, or -1).
Default is 1
params.stack = Ptr null;
// Task stack pointer. Default = null
// Mem heap used for dynamically created task stack
params.stackSection = String undefined;
// Mem section used for statically created task stacks
params.stackSize = SizeT 0;
// Task stack size in MAUs
params.vitalTaskFlag = Bool true;
// Exit system immediately when the last task with this
flag set to TRUE has terminated
config Task.Params.affinity // instance |
|
The core which this task is to run on. Default is Task_AFFINITY_NONE
var params = new Task.Params;
...
params.affinity = UInt undefined;
DETAILS
If there is a compelling reason for a task to be pinned to a
particular core, then setting 'affinity' to the corresponding core
id will force the task to only be run on that core.
The default affinity is inherited from
Task.defaultAffinity
which in turn defaults to
Task_AFFINITY_NONE,
which means the task can be run on either core.
Furthermore, Task_AFFINITY_NONE implies that the task can be moved
from core to core as deemed necessary by the Task scheduler in order
to keep the two highest priority ready tasks running simultaneously.
C SYNOPSIS
config Task.Params.arg0 // instance |
|
Task function argument. Default is 0
var params = new Task.Params;
...
params.arg0 = UArg 0;
C SYNOPSIS
config Task.Params.arg1 // instance |
|
Task function argument. Default is 0
var params = new Task.Params;
...
params.arg1 = UArg 0;
C SYNOPSIS
config Task.Params.env // instance |
|
Environment data struct
var params = new Task.Params;
...
params.env = Ptr null;
C SYNOPSIS
config Task.Params.priority // instance |
|
Task priority (0 to Task.numPriorities-1, or -1).
Default is 1
var params = new Task.Params;
...
params.priority = Int 1;
C SYNOPSIS
config Task.Params.stack // instance |
|
Task stack pointer. Default = null
var params = new Task.Params;
...
params.stack = Ptr null;
DETAILS
Null indicates that the stack is to be allocated by create().
STATIC CONFIGURATION USAGE WARNING
This parameter can only be assigned a non-null value
during runtime Task creates or constructs.
Static configuration of the 'stack' parameter is not supported.
Note that if
BIOS.runtimeCreatesEnabled is set to false, then the user is required
to provide the stack buffer when constructing the Task object.
If 'stack' is not provided, then Task_construct() will fail.
C SYNOPSIS
config Task.Params.stackHeap // instance |
|
Mem heap used for dynamically created task stack
var params = new Task.Params;
...
DETAILS
The default value of NULL means that the module config
defaultStackHeap is used.
C SYNOPSIS
config Task.Params.stackSize // instance |
|
Task stack size in MAUs
var params = new Task.Params;
...
params.stackSize = SizeT 0;
DETAILS
The default value of 0 means that the module config
defaultStackSize is used.
C SYNOPSIS
config Task.Params.vitalTaskFlag // instance |
|
Exit system immediately when the last task with this
flag set to TRUE has terminated
var params = new Task.Params;
...
params.vitalTaskFlag = Bool true;
DETAILS
Default is true.
C SYNOPSIS
metaonly config Task.Params.stackSection // instance |
|
Mem section used for statically created task stacks
var params = new Task.Params;
...
params.stackSection = String undefined;
DETAILS
Default is inherited from module config defaultStackSection.
Static Instance Creation |
|
// Allocate instance config-params
params.config = ...
// Assign individual configs
var inst = Task.create(Void(*)(UArg,UArg) fxn, params);
// Create an instance-object
ARGUMENTS
fxn
Task Function
params
per-instance config params, or NULL to select default values (target-domain only)
eb
active error-handling block, or NULL to select default policy (target-domain only)
DETAILS
Task_create creates a new task object. If successful, Task_create
returns the handle of the new task object. If unsuccessful,
Task_create returns NULL unless it aborts.
The fxn parameter uses the
FuncPtr type to pass a pointer to
the function the Task object should run. For example, if myFxn is a
function in your program, your C code can create a Task object
to call that
function as follows:
Task_Params taskParams;
// Create task with priority 15
Task_Params_init(&taskParams);
taskParams.stackSize = 512;
taskParams.priority = 15;
Task_create((Task_FuncPtr)myFxn, &taskParams, &eb);
The following statements statically create a task in the
configuration file:
var params = new Task.Params;
params.instance.name = "tsk0";
params.arg0 = 1;
params.arg1 = 2;
params.priority = 1;
Task.create('&tsk0_func', params);
If NULL is passed instead of a pointer to an actual Task_Params
struct, a
default set of parameters is used. The "eb" is an error block that
you can use
to handle errors that may occur during Task object creation.
The newly created task is placed in
Mode_READY mode, and is
scheduled to begin concurrent execution of the following function
call:
As a result of being made ready to run, the task runs any
application-wide Ready functions that have been specified.
Task_exit is automatically called if and when the task returns
from fxn.
Create Hook Functions
You can specify application-wide Create hook functions in your config
file that run whenever a task is created. This includes tasks that
are created statically and those created dynamically using
Task_create.
For Task objects created statically, Create functions are called
during the Task module initialization phase of the program startup
process prior to main().
For Task objects created dynamically, Create functions
are called after the task handle has been initialized but before the
task has been placed on its ready queue.
Any SYS/BIOS function can be called from Create functions.
SYS/BIOS passes the task handle of the task being created to each of
the Create functions.
All Create function declarations should be similar to this:
Void myCreateFxn(Task_Handle task);
CONSTRAINTS
- The fxn parameter and the name attribute cannot be NULL.
- The priority attribute must be less than or equal to
(numPriorities - 1) and greater than or equal to one (1)
(priority 0 is owned by the Idle task).
- The priority can be set to -1 for tasks that will not execute
until another task changes the priority to a positive value.
- The stackHeap attribute must identify a valid memory Heap.