1 /* 2 * Copyright (c) 2022-2024, Texas Instruments Incorporated 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of Texas Instruments Incorporated nor the names of 17 * its contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 /** ============================================================================ 33 * @file TaskP.h 34 * 35 * @brief Task module for the RTOS Porting Interface 36 * 37 * TaskP objects are RTOS threads backed by OS-specific thread or task objects. 38 * Task functions will run according to the rules of the underlying scheduler, 39 * with higher priority tasks executing first. 40 * 41 * Tasks require a stack and a control struct to operate, which can either be 42 * allocated statically with TaskP_construct or dynamically with TaskP_create. 43 * The stack should be large enough to contain at least your deepest call stack 44 * plus an interrupt frame. 45 * 46 * Task Functions: 47 * The void* argument will be NULL by default, but you can set a value using 48 * TaskP_Params. Task functions should never return, as the behaviour after a 49 * task has returned is implementation-dependent and TaskP does not provide a 50 * mechanism for OS-independent task deletion. See your OS documentation for 51 * details. 52 * ============================================================================ 53 */ 54 55 #ifndef ti_dpl_TaskP__include 56 #define ti_dpl_TaskP__include 57 58 #include <stdint.h> 59 #include <stdbool.h> 60 #include <stddef.h> 61 62 63 #ifdef __cplusplus 64 extern "C" { 65 #endif 66 67 /*! 68 * @brief Number of bytes greater than or equal to the size of any RTOS Task object. 69 * 70 * Zephyr: 160 71 */ 72 #define TaskP_STRUCT_SIZE (160) 73 74 /*! 75 * @brief Number of bytes for the default stack size of any RTOS Task object. 76 * 77 */ 78 #define TaskP_DEFAULT_STACK_SIZE (CONFIG_DYNAMIC_THREAD_STACK_SIZE) 79 80 /*! 81 * @brief TaskP structure. 82 * 83 * Opaque structure that should be large enough to hold any of the RTOS specific TaskP objects. 84 */ 85 typedef union TaskP_Struct 86 { 87 uint32_t dummy; /*!< Align object */ 88 uint8_t data[TaskP_STRUCT_SIZE]; 89 } TaskP_Struct; 90 91 /*! 92 * @brief Enum returned from TaskP_getState(). 93 */ 94 typedef enum 95 { 96 /*! This task is actively running */ 97 TaskP_State_RUNNING, 98 /*! The task is ready to run, but not currently running */ 99 TaskP_State_READY, 100 /*! The task is blocked */ 101 TaskP_State_BLOCKED, 102 /*! The task has been deleted */ 103 TaskP_State_DELETED, 104 /*! The task is inactive */ 105 TaskP_State_INACTIVE, 106 /*! The task is not found or in an otherwise invalid state */ 107 TaskP_State_INVALID 108 } TaskP_State; 109 110 /*! 111 * @brief Opaque client reference to an instance of a TaskP 112 * 113 * A TaskP_Handle returned from create or construct represents that instance. 114 */ 115 typedef TaskP_Struct *TaskP_Handle; 116 117 typedef struct 118 { 119 /*! Task name. Default: NAME */ 120 char *name; 121 /*! Task function argument. Default: NULL */ 122 void *arg; 123 /*! Task priority. Higher values represent higher priorities. Default: 0 */ 124 int priority; 125 /*! Task stack size. Default: TaskP_DEFAULT_STACK_SIZE */ 126 size_t stackSize; 127 /*! @brief Task stack pointer. NULL should be used when calling TaskP_create. 128 * A pointer to a current stack should be passed for TaskP_construct. Default: NULL 129 */ 130 void *stack; 131 } TaskP_Params; 132 133 /*! 134 * @brief Task function definition, passed to create and construct 135 * 136 * This function should never return. 137 */ 138 typedef void (*TaskP_Function)(void *); 139 140 /*! 141 * @brief Create a TaskP, allocating memory on the heap. 142 * 143 * Creates a new TaskP and registers it with the OS scheduler. The task object 144 * and the entire stack will be allocated on the heap - make sure you have a 145 * sufficiently large heap. Stack allocation size is controlled by params. 146 * 147 * If the program is already executing a task and the new task has a higher 148 * priority the new task will be scheduled immediately; in this case 149 * TaskP_create() will not return until the new task blocks. To avoid this (for 150 * example when creating interdependent tasks at once) use 151 * TaskP_disableScheduler() and TaskP_restoreScheduler() to prevent the context 152 * switch. 153 * 154 * \note This API cannot be called from interrupt contexts. 155 * 156 * @retval TaskP handle (NULL on failure) 157 */ 158 extern TaskP_Handle TaskP_create(TaskP_Function fxn, const TaskP_Params *params); 159 160 /*! 161 * @brief Delete a TaskP. 162 * 163 * Deletes a TaskP. 164 * 165 * \note This API cannot be called from interrupt contexts. 166 * 167 * 168 */ 169 extern void TaskP_delete(TaskP_Handle task); 170 171 /*! 172 * @brief Construct a TaskP from statically allocated memory. 173 * 174 * TaskP_construct creates a new task object. TaskP_construct returns the handle 175 * of the new task object or NULL if the task could not be created. 176 * 177 * To use TaskP_construct you must set both point @c params.stack to a valid 178 * preallocated memory location of at least @c params.stackSize. 179 * 180 * \note This API cannot be called from interrupt contexts. 181 * 182 * 183 * @retval TaskP handle (NULL on failure) 184 */ 185 extern TaskP_Handle TaskP_construct(TaskP_Struct *obj, TaskP_Function fxn, const TaskP_Params *params); 186 187 /*! 188 * @brief Destruct a TaskP. 189 * 190 * TaskP_destruct destructs a task object. 191 * 192 * \note This API cannot be called from interrupt contexts. 193 */ 194 extern void TaskP_destruct(TaskP_Struct *obj); 195 196 /*! 197 * @brief Get the current state of a task handle. 198 * 199 * Returns the state of the referenced task at the time this function was 200 * called. The return value is not guaranteed to match the state of the task 201 * when the calling function tests the return value. For example, the referenced 202 * task might have unblocked as a result of an interrupt, but the value may 203 * still read TaskP_State_BLOCKED. 204 * 205 * The conversion of task states between DPL, FreeRTOS and TI-RTOS is: 206 * DPL: FreeRTOS: TI-RTOS: 207 * TaskP_State_RUNNING - eRunning - Task_Mode_RUNNING 208 * TaskP_State_READY - eReady - Task_Mode_READY 209 * TaskP_State_BLOCKED - eBlocked - Task_Mode_BLOCKED 210 * TaskP_State_DELETED - eDeleted - Task_Mode_TERMINATED 211 * TaskP_State_INACTIVE - eSuspended - Task_Mode_INACTIVE 212 * TaskP_State_INVALID - eInvalid - N.A 213 * 214 * 215 * @retval Current state of the task pointed to by the task parameter 216 */ 217 extern TaskP_State TaskP_getState(TaskP_Handle task); 218 219 /*! 220 * @brief Get the currently executing task handle. 221 * 222 * \note Must be called from task context. 223 * 224 * 225 * @retval The handle for the calling task 226 */ 227 extern TaskP_Handle TaskP_getCurrentTask(void); 228 229 /*! 230 * @brief Function to disable task scheduling 231 * 232 * This function can be called multiple times, but must unwound in the reverse 233 * order. For example 234 * @code 235 * uintptr_t key1, key2; 236 * key1 = TaskP_disableScheduler(); 237 * key2 = TaskP_disableScheduler(); 238 * TaskP_restoreScheduler(key2); 239 * TaskP_restoreScheduler(key1); 240 * @endcode 241 * 242 * \note This API cannot be called from interrupt contexts. 243 * 244 * @return A key to pass to TaskP_restoreScheduler to re-enable the scheduler. 245 */ 246 extern uintptr_t TaskP_disableScheduler(void); 247 248 /*! 249 * @brief Function to re-enable task scheduling 250 * 251 * \note This API cannot be called from interrupt contexts. 252 * 253 * @param key returned from TaskP_disableScheduler 254 */ 255 extern void TaskP_restoreScheduler(uintptr_t key); 256 257 /*! 258 * @brief Create a scheduler point, yielding to equal priority tasks. 259 * 260 * Task_yield yields the processor to another task of equal priority. A task 261 * switch occurs when you call Task_yield if there is an equal priority task 262 * ready to run. 263 */ 264 extern void TaskP_yield(void); 265 266 /*! 267 * @brief Initialize params structure to default values. 268 * 269 * Initialize the parameter struct with default values. 270 * 271 * @param params pointer to the task parameter struct 272 * 273 */ 274 extern void TaskP_Params_init(TaskP_Params *params); 275 276 #ifdef __cplusplus 277 } 278 #endif 279 280 #endif /* ti_dpl_TaskP__include */