TNeo
v1.06
|
In TNeo, a task is a branch of code that runs concurrently with other tasks from the programmer's point of view. Indeed, tasks are actually executed using processor time sharing. Each task can be considered to be an independed program, which executes in its own context (processor registers, stack pointer, etc.).
Actually, the term thread is more accurate than task, but the term task historically was used in TNKernel, so TNeo keeps this convention.
When kernel decides that it's time to run another task, it performs context switch: current context (at least, values of all registers) gets saved to the preempted task's stack, pointer to currently running task is altered as well as stack pointer, and context gets restored from the stack of newly running task.
For list of task states and their description, refer to enum TN_TaskState
.
Create task and start task are two separate actions; although you can perform both of them in one step by passing TN_TASK_CREATE_OPT_START
flag to the tn_task_create()
function.
Stop task and delete task are two separate actions. If task was just stopped but not deleted, it can be just restarted again by calling tn_task_activate()
. If task was deleted, it can't be just activated: it should be re-created by tn_task_create()
first.
Task stops execution when:
tn_task_exit()
;tn_task_exit(0)
)tn_task_terminate()
passing appropriate pointer to struct TN_Task
.TNeo always runs the most privileged task in state RUNNABLE
. In no circumstances can task run while there is at least one task is in the RUNNABLE
state with higher priority. Task will run until:
Tasks with the same priority may be scheduled in round robin fashion by getting a predetermined time slice for each task with this priority. Time slice is set separately for each priority. By default, round robin is turned off for all priorities.
TNeo has one system task: an idle task, which has lowest priority. It is always in the state RUNNABLE
, and it runs only when there are no other runnable tasks.
User can provide a callback function to be called from idle task, see TN_CBIdle. It is useful to bring the processor to some kind of real idle state, so that device draws less current.
Definition in file tn_tasks.h.
Go to the source code of this file.
Data Structures | |
struct | TN_TaskTiming |
Timing structure that is managed by profiler and can be read by tn_task_profiler_timing_get() function. More... | |
struct | _TN_TaskProfiler |
Internal kernel structure for profiling data of task. More... | |
struct | TN_Task |
Task. More... | |
Enumerations | |
enum | TN_TaskState { TN_TASK_STATE_NONE = 0, TN_TASK_STATE_RUNNABLE = (1 << 0), TN_TASK_STATE_WAIT = (1 << 1), TN_TASK_STATE_SUSPEND = (1 << 2), TN_TASK_STATE_WAITSUSP = (TN_TASK_STATE_WAIT | TN_TASK_STATE_SUSPEND), TN_TASK_STATE_DORMANT = (1 << 3) } |
Task state. More... | |
enum | TN_WaitReason { TN_WAIT_REASON_NONE, TN_WAIT_REASON_SLEEP, TN_WAIT_REASON_SEM, TN_WAIT_REASON_EVENT, TN_WAIT_REASON_DQUE_WSEND, TN_WAIT_REASON_DQUE_WRECEIVE, TN_WAIT_REASON_MUTEX_C, TN_WAIT_REASON_MUTEX_I, TN_WAIT_REASON_WFIXMEM, TN_WAIT_REASONS_CNT } |
Task wait reason. More... | |
enum | TN_TaskCreateOpt { TN_TASK_CREATE_OPT_START = (1 << 0), _TN_TASK_CREATE_OPT_IDLE = (1 << 1) } |
Options for tn_task_create() More... | |
enum | TN_TaskExitOpt { TN_TASK_EXIT_OPT_DELETE = (1 << 0) } |
Options for tn_task_exit() More... | |
Functions | |
enum TN_RCode | tn_task_create (struct TN_Task *task, TN_TaskBody *task_func, int priority, TN_UWord *task_stack_low_addr, int task_stack_size, void *param, enum TN_TaskCreateOpt opts) |
Construct task and probably start it (depends on options, see below). More... | |
enum TN_RCode | tn_task_create_wname (struct TN_Task *task, TN_TaskBody *task_func, int priority, TN_UWord *task_stack_low_addr, int task_stack_size, void *param, enum TN_TaskCreateOpt opts, const char *name) |
The same as tn_task_create() but with additional argument name , which could be very useful for debug. | |
enum TN_RCode | tn_task_suspend (struct TN_Task *task) |
If the task is RUNNABLE , it is moved to the SUSPEND state. More... | |
enum TN_RCode | tn_task_resume (struct TN_Task *task) |
Release task from SUSPEND state. More... | |
enum TN_RCode | tn_task_sleep (TN_TickCnt timeout) |
Put current task to sleep for at most timeout ticks. More... | |
enum TN_RCode | tn_task_wakeup (struct TN_Task *task) |
Wake up task from sleep. More... | |
enum TN_RCode | tn_task_iwakeup (struct TN_Task *task) |
The same as tn_task_wakeup() but for using in the ISR. More... | |
enum TN_RCode | tn_task_activate (struct TN_Task *task) |
Activate task that is in DORMANT state, that is, it was either just created by tn_task_create() without TN_TASK_CREATE_OPT_START option, or terminated. More... | |
enum TN_RCode | tn_task_iactivate (struct TN_Task *task) |
The same as tn_task_activate() but for using in the ISR. More... | |
enum TN_RCode | tn_task_release_wait (struct TN_Task *task) |
Release task from WAIT state, independently of the reason of waiting. More... | |
enum TN_RCode | tn_task_irelease_wait (struct TN_Task *task) |
The same as tn_task_release_wait() but for using in the ISR. More... | |
void | tn_task_exit (enum TN_TaskExitOpt opts) |
This function terminates the currently running task. More... | |
enum TN_RCode | tn_task_terminate (struct TN_Task *task) |
This function is similar to tn_task_exit() but it terminates any task other than currently running one. More... | |
enum TN_RCode | tn_task_delete (struct TN_Task *task) |
This function deletes the task specified by the task. More... | |
enum TN_RCode | tn_task_state_get (struct TN_Task *task, enum TN_TaskState *p_state) |
Get current state of the task; note that returned state is a bitmask, that is, states could be combined with each other. More... | |
enum TN_RCode | tn_task_profiler_timing_get (const struct TN_Task *task, struct TN_TaskTiming *tgt) |
Read profiler timing data of the task. More... | |
enum TN_RCode | tn_task_change_priority (struct TN_Task *task, int new_priority) |
Set new priority for task. More... | |
enum TN_TaskState |
Task state.
Enumerator | |
---|---|
TN_TASK_STATE_NONE |
This state should never be publicly available. It may be stored in task_state only temporarily, while some system service is in progress. |
TN_TASK_STATE_RUNNABLE |
Task is ready to run (it doesn't mean that it is running at the moment) |
TN_TASK_STATE_WAIT |
Task is waiting. The reason of waiting can be obtained from
|
TN_TASK_STATE_SUSPEND |
Task is suspended (by some other task) |
TN_TASK_STATE_WAITSUSP |
Task was previously waiting, and after this it was suspended. |
TN_TASK_STATE_DORMANT |
Task isn't yet activated or it was terminated by |
Definition at line 141 of file tn_tasks.h.
enum TN_WaitReason |
Task wait reason.
Enumerator | |
---|---|
TN_WAIT_REASON_NONE |
Task isn't waiting for anything. |
TN_WAIT_REASON_SLEEP |
Task has called |
TN_WAIT_REASON_SEM |
Task waits to acquire a semaphore.
|
TN_WAIT_REASON_EVENT |
Task waits for some event in the event group to be set.
|
TN_WAIT_REASON_DQUE_WSEND |
Task wants to put some data to the data queue, and there's no space in the queue.
|
TN_WAIT_REASON_DQUE_WRECEIVE |
Task wants to receive some data to the data queue, and there's no data in the queue.
|
TN_WAIT_REASON_MUTEX_C |
Task wants to lock a mutex with priority ceiling.
|
TN_WAIT_REASON_MUTEX_I |
Task wants to lock a mutex with priority inheritance.
|
TN_WAIT_REASON_WFIXMEM |
Task wants to get memory block from memory pool, and there's no free memory blocks.
|
TN_WAIT_REASONS_CNT |
Wait reasons count. |
Definition at line 173 of file tn_tasks.h.
enum TN_TaskCreateOpt |
Options for tn_task_create()
Enumerator | |
---|---|
TN_TASK_CREATE_OPT_START |
whether task should be activated right after it is created. If this flag is not set, user must activate task manually by calling |
_TN_TASK_CREATE_OPT_IDLE |
for internal kernel usage only: this option must be provided when creating idle task |
Definition at line 221 of file tn_tasks.h.
enum TN_TaskExitOpt |
Options for tn_task_exit()
Enumerator | |
---|---|
TN_TASK_EXIT_OPT_DELETE |
whether task should be deleted right after it is exited. If this flag is not set, user must either delete it manually by calling |
Definition at line 236 of file tn_tasks.h.
enum TN_RCode tn_task_create | ( | struct TN_Task * | task, |
TN_TaskBody * | task_func, | ||
int | priority, | ||
TN_UWord * | task_stack_low_addr, | ||
int | task_stack_size, | ||
void * | param, | ||
enum TN_TaskCreateOpt | opts | ||
) |
Construct task and probably start it (depends on options, see below).
id_task
member should not contain TN_ID_TASK
, otherwise, TN_RC_WPARAM
is returned.
Usage example:
And then, somewhere from other task or from the callback TN_CBUserTaskCreate
given to tn_sys_start()
:
task | Ready-allocated struct TN_Task structure. id_task member should not contain TN_ID_TASK , otherwise TN_RC_WPARAM is returned. |
task_func | Pointer to task body function. |
priority | Priority for new task. NOTE: the lower value, the higher priority. Must be > 0 and < (TN_PRIORITIES_CNT - 1) . |
task_stack_low_addr | Pointer to the stack for task. User must either use the macro TN_STACK_ARR_DEF() for the definition of stack array, or allocate it manually as an array of TN_UWord with TN_ARCH_STK_ATTR_BEFORE and TN_ARCH_STK_ATTR_AFTER macros. |
task_stack_size | Size of task stack array, in words (TN_UWord ), not in bytes. |
param | Parameter that is passed to task_func . |
opts | Options for task creation, refer to enum TN_TaskCreateOpt |
TN_RC_OK
on success;TN_RC_WCONTEXT
if called from wrong context;TN_RC_WPARAM
if wrong params were given;If the task is RUNNABLE
, it is moved to the SUSPEND
state.
If the task is in the WAIT
state, it is moved to the WAIT+SUSPEND
state. (waiting + suspended)
task | Task to suspend |
TN_RC_OK
on success;TN_RC_WCONTEXT
if called from wrong context;TN_RC_WSTATE
if task is already suspended or dormant;TN_CHECK_PARAM
is non-zero, additional return codes are available: TN_RC_WPARAM
and TN_RC_INVALID_OBJ
.enum TN_TaskState
Release task from SUSPEND
state.
If the given task is in the SUSPEND
state, it is moved to RUNNABLE
state; afterwards it has the lowest precedence among runnable tasks with the same priority. If the task is in WAIT+SUSPEND
state, it is moved to WAIT
state.
task | Task to release from suspended state |
TN_RC_OK
on success;TN_RC_WCONTEXT
if called from wrong context;TN_RC_WSTATE
if task is not suspended;TN_CHECK_PARAM
is non-zero, additional return codes are available: TN_RC_WPARAM
and TN_RC_INVALID_OBJ
.enum TN_RCode tn_task_sleep | ( | TN_TickCnt | timeout | ) |
Put current task to sleep for at most timeout ticks.
When the timeout expires and the task was not suspended during the sleep, it is switched to runnable state. If the timeout value is TN_WAIT_INFINITE
and the task was not suspended during the sleep, the task will sleep until another function call (like tn_task_wakeup()
or similar) will make it runnable.
timeout | Refer to TN_TickCnt |
TN_RC_TIMEOUT
if task has slept specified timeout;TN_RC_OK
if task was woken up from other task by tn_task_wakeup()
TN_RC_FORCED
if task was released from wait forcibly by tn_task_release_wait()
TN_RC_WCONTEXT
if called from wrong contextWake up task from sleep.
Task is woken up if only it sleeps because of call to tn_task_sleep()
. If task sleeps for some another reason, task won't be woken up, and tn_task_wakeup()
returns TN_RC_WSTATE
.
After this call, tn_task_sleep()
returns TN_RC_OK
.
task | sleeping task to wake up |
TN_RC_OK
if successfulTN_RC_WSTATE
if task is not sleeping, or it is sleeping for some reason other than tn_task_sleep()
call.TN_RC_WCONTEXT
if called from wrong context;TN_CHECK_PARAM
is non-zero, additional return codes are available: TN_RC_WPARAM
and TN_RC_INVALID_OBJ
. Activate task that is in DORMANT
state, that is, it was either just created by tn_task_create()
without TN_TASK_CREATE_OPT_START
option, or terminated.
Task is moved from DORMANT
state to the RUNNABLE
state.
task | dormant task to activate |
TN_RC_OK
if successfulTN_RC_WSTATE
if task is not dormantTN_RC_WCONTEXT
if called from wrong context;TN_CHECK_PARAM
is non-zero, additional return codes are available: TN_RC_WPARAM
and TN_RC_INVALID_OBJ
.Release task from WAIT
state, independently of the reason of waiting.
If task is in WAIT
state, it is moved to RUNNABLE
state. If task is in WAIT+SUSPEND
state, it is moved to SUSPEND
state.
TN_RC_FORCED
is returned to the waiting task.
task | task waiting for anything |
TN_RC_OK
if successfulTN_RC_WSTATE
if task is not waiting for anythingTN_RC_WCONTEXT
if called from wrong context;TN_CHECK_PARAM
is non-zero, additional return codes are available: TN_RC_WPARAM
and TN_RC_INVALID_OBJ
.void tn_task_exit | ( | enum TN_TaskExitOpt | opts | ) |
This function terminates the currently running task.
The task is moved to the DORMANT
state.
After exiting, the task may be either deleted by the tn_task_delete()
function call or reactivated by the tn_task_activate()
/ tn_task_iactivate()
function call. In this case task starts execution from beginning (as after creation/activation). The task will have the lowest precedence among all tasks with the same priority in the RUNNABLE
state.
If this function is invoked with TN_TASK_EXIT_OPT_DELETE
option set, the task will be deleted after termination and cannot be reactivated (needs recreation).
Please note that returning from task body function has the same effect as calling tn_task_exit(0)
.
This function is similar to tn_task_exit()
but it terminates any task other than currently running one.
After task is terminated, the task may be either deleted by the tn_task_delete()
function call or reactivated by the tn_task_activate()
/ tn_task_iactivate()
function call. In this case task starts execution from beginning (as after creation/activation). The task will have the lowest precedence among all tasks with the same priority in the RUNNABLE
state.
task | task to terminate |
TN_RC_OK
if successfulTN_RC_WSTATE
if task is already dormantTN_RC_WCONTEXT
if called from wrong context;TN_CHECK_PARAM
is non-zero, additional return codes are available: TN_RC_WPARAM
and TN_RC_INVALID_OBJ
. This function deletes the task specified by the task.
The task must be in the DORMANT
state, otherwise TN_RC_WCONTEXT
will be returned.
This function resets the id_task
field in the task structure to 0 and removes the task from the system tasks list. The task can not be reactivated after this function call (the task must be recreated).
task | dormant task to delete |
TN_RC_OK
if successfulTN_RC_WSTATE
if task is not dormantTN_RC_WCONTEXT
if called from wrong context;TN_CHECK_PARAM
is non-zero, additional return codes are available: TN_RC_WPARAM
and TN_RC_INVALID_OBJ
. enum TN_RCode tn_task_state_get | ( | struct TN_Task * | task, |
enum TN_TaskState * | p_state | ||
) |
Get current state of the task; note that returned state is a bitmask, that is, states could be combined with each other.
Currently, only WAIT
and SUSPEND
states are allowed to be set together. Nevertheless, it would be probably good idea to test individual bits in the returned value instead of plain comparing values.
Note that if something goes wrong, variable pointed to by p_state
isn't touched.
task | task to get state of |
p_state | pointer to the location where to store state of the task |
enum TN_RCode tn_task_profiler_timing_get | ( | const struct TN_Task * | task, |
struct TN_TaskTiming * | tgt | ||
) |
Read profiler timing data of the task.
See struct TN_TaskTiming
for details on timing data.
task | Task to get timing data of |
tgt | Target structure to fill with data, should be allocated by caller |