| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| |
| /** |
| * @addtogroup OSKernel |
| * @{ |
| * @defgroup OSTask Tasks |
| * @{ |
| */ |
| |
| #ifndef _OS_TASK_H |
| #define _OS_TASK_H |
| |
| #include "os/os.h" |
| #include "os/os_sanity.h" |
| #include "os/os_arch.h" |
| #include "os/queue.h" |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| #define OS_TASK_STACK_DEFINE_NOSTATIC(__name, __size) \ |
| os_stack_t __name [OS_STACK_ALIGN(__size)] \ |
| __attribute__((aligned(OS_STACK_ALIGNMENT))) |
| |
| #define OS_TASK_STACK_DEFINE(__name, __size) \ |
| static OS_TASK_STACK_DEFINE_NOSTATIC(__name, __size); |
| |
| /** Highest priority task */ |
| #define OS_TASK_PRI_HIGHEST (0) |
| /** Lowest priority task */ |
| #define OS_TASK_PRI_LOWEST (0xff) |
| |
| /* |
| * Generic "object" structure. All objects that a task can wait on must |
| * have a SLIST_HEAD(, os_task) head_name as the first element in the object |
| * structure. The element 'head_name' can be any name. See os_mutex.h or |
| * os_sem.h for an example. |
| */ |
| struct os_task_obj { |
| SLIST_HEAD(, os_task) obj_head; /* chain of waiting tasks */ |
| }; |
| |
| /** Task states */ |
| typedef enum os_task_state { |
| /** Task is ready to run */ |
| OS_TASK_READY = 1, |
| /** Task is sleeping */ |
| OS_TASK_SLEEP = 2, |
| } os_task_state_t; |
| |
| /* Task flags */ |
| #define OS_TASK_FLAG_NO_TIMEOUT (0x01U) |
| /** Task waiting on a semaphore */ |
| #define OS_TASK_FLAG_SEM_WAIT (0x02U) |
| /** Task waiting on a mutex */ |
| #define OS_TASK_FLAG_MUTEX_WAIT (0x04U) |
| /** Task waiting on a event queue */ |
| #define OS_TASK_FLAG_EVQ_WAIT (0x08U) |
| |
| typedef void (*os_task_func_t)(void *); |
| |
| #define OS_TASK_MAX_NAME_LEN (32) |
| |
| /** |
| * Structure containing information about a running task |
| */ |
| struct os_task { |
| /* |
| * t_stackptr and t_stackbottom fields may be accessed directly from |
| * assembly code and should never be moved in this structure. |
| */ |
| |
| /** Current stack pointer for this task */ |
| os_stack_t *t_stackptr; |
| /** Pointer to bottom of this task's stack */ |
| os_stack_t *t_stackbottom; |
| /** Size of this task's stack */ |
| uint16_t t_stacksize; |
| /** Task ID */ |
| uint8_t t_taskid; |
| /** Task Priority */ |
| uint8_t t_prio; |
| /* Task state, either READY or SLEEP */ |
| uint8_t t_state; |
| /** Task flags, bitmask */ |
| uint8_t t_flags; |
| uint8_t t_lockcnt; |
| uint8_t t_pad; |
| |
| /** Task name */ |
| const char *t_name; |
| /** Task function that executes */ |
| os_task_func_t t_func; |
| /** Argument to pass to task function when called */ |
| void *t_arg; |
| |
| /** Current object task is waiting on, either a semaphore or mutex */ |
| void *t_obj; |
| |
| /** Default sanity check for this task */ |
| struct os_sanity_check t_sanity_check; |
| |
| /** Next scheduled wakeup if this task is sleeping */ |
| os_time_t t_next_wakeup; |
| /** Total task run time */ |
| os_time_t t_run_time; |
| /** |
| * Total number of times this task has been context switched during |
| * execution. |
| */ |
| uint32_t t_ctx_sw_cnt; |
| |
| STAILQ_ENTRY(os_task) t_os_task_list; |
| TAILQ_ENTRY(os_task) t_os_list; |
| SLIST_ENTRY(os_task) t_obj_list; |
| }; |
| |
| /** @cond INTERNAL_HIDDEN */ |
| STAILQ_HEAD(os_task_stailq, os_task); |
| |
| extern struct os_task_stailq g_os_task_list; |
| /** @endcond */ |
| |
| /** |
| * Initialize a task. |
| * |
| * This function initializes the task structure pointed to by t, |
| * clearing and setting it's stack pointer, provides sane defaults |
| * and sets the task as ready to run, and inserts it into the operating |
| * system scheduler. |
| * |
| * @param t The task to initialize |
| * @param name The name of the task to initialize |
| * @param func The task function to call |
| * @param arg The argument to pass to this task function |
| * @param prio The priority at which to run this task |
| * @param sanity_itvl The time at which this task should check in with the |
| * sanity task. OS_WAIT_FOREVER means never check in |
| * here. |
| * @param stack_bottom A pointer to the bottom of a task's stack |
| * @param stack_size The overall size of the task's stack. |
| * |
| * @return 0 on success, non-zero on failure. |
| */ |
| int os_task_init(struct os_task *, const char *, os_task_func_t, void *, |
| uint8_t, os_time_t, os_stack_t *, uint16_t); |
| |
| /** |
| * Removes specified task |
| * XXX |
| * NOTE: This interface is currently experimental and not ready for common use |
| */ |
| int os_task_remove(struct os_task *t); |
| |
| /** |
| * Return pointer to top of stack for given task |
| * |
| * @param t The task |
| * |
| * @return pointer to top of stack |
| */ |
| os_stack_t *os_task_stacktop_get(struct os_task *t); |
| |
| /** |
| * Return the number of tasks initialized. |
| * |
| * @return number of tasks initialized |
| */ |
| uint8_t os_task_count(void); |
| |
| /** |
| * Information about an individual task, returned for management APIs. |
| */ |
| struct os_task_info { |
| /** Task priority */ |
| uint8_t oti_prio; |
| /** Task identifier */ |
| uint8_t oti_taskid; |
| /** Task state, either READY or SLEEP */ |
| uint8_t oti_state; |
| /** Task stack usage */ |
| uint16_t oti_stkusage; |
| /** Task stack size */ |
| uint16_t oti_stksize; |
| /** Task context switch count */ |
| uint32_t oti_cswcnt; |
| /** Task runtime */ |
| uint32_t oti_runtime; |
| /** Last time this task checked in with sanity */ |
| os_time_t oti_last_checkin; |
| /** Next time this task is scheduled to check-in with sanity */ |
| os_time_t oti_next_checkin; |
| /** Name of this task */ |
| char oti_name[OS_TASK_MAX_NAME_LEN]; |
| }; |
| |
| /** |
| * Iterate through tasks, and return the following information about them: |
| * |
| * - Priority |
| * - Task ID |
| * - State (READY, SLEEP) |
| * - Total Stack Usage |
| * - Stack Size |
| * - Context Switch Count |
| * - Runtime |
| * - Last & Next Sanity checkin |
| * - Task Name |
| * |
| * To get the first task in the list, call os_task_info_get_next() with a |
| * NULL pointer in the prev argument, and os_task_info_get_next() will |
| * return a pointer to the task structure, and fill out the os_task_info |
| * structure pointed to by oti. |
| * |
| * To get the next task in the list, provide the task structure returned |
| * by the previous call to os_task_info_get_next(), and os_task_info_get_next() |
| * will fill out the task structure pointed to by oti again, and return |
| * the next task in the list. |
| * |
| * @param prev The previous task returned by os_task_info_get_next(), or NULL |
| * to begin iteration. |
| * @param oti The OS task info structure to fill out. |
| * |
| * @return A pointer to the OS task that has been read, or NULL when finished |
| * iterating through all tasks. |
| */ |
| struct os_task *os_task_info_get_next(const struct os_task *, |
| struct os_task_info *); |
| |
| /** |
| * Get following info about specified task |
| * - Priority |
| * - Task ID |
| * - State (READY, SLEEP) |
| * - Total Stack Usage |
| * - Stack Size |
| * - Context Switch Count |
| * - Runtime |
| * - Last & Next Sanity checkin |
| * - Task Name |
| * |
| * @param task The task to get info about |
| * @param oti The OS task info structure to fill out. |
| */ |
| void os_task_info_get(const struct os_task *task, struct os_task_info *oti); |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* _OS_TASK_H */ |
| |
| |
| /** |
| * @} OSTask |
| * @} OSKernel |
| */ |