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 */