1 #ifndef _KE_TASK_H_
2 #define _KE_TASK_H_
3 
4 /**
5  ****************************************************************************************
6  * @defgroup TASK Task and Process
7  * @ingroup KERNEL
8  * @brief Task management module.
9  *
10  * This module implements the functions used for managing tasks.
11  *
12  * @{
13  ****************************************************************************************
14  */
15 
16 /*
17  * INCLUDE FILES
18  ****************************************************************************************
19  */
20 #include <stdint.h>          // standard integer
21 #include <stdbool.h>         // standard boolean
22 
23 #include "rwip_config.h"     // stack configuration
24 #include "compiler.h"        // compiler defines, INLINE
25 #include "ke_msg.h"          // kernel message defines
26 
27 /* Default Message handler code to handle several message type in same handler. */
28 #define KE_MSG_DEFAULT_HANDLER  (0xFFFF)
29 /* Invalid task */
30 #define KE_TASK_INVALID         (0xFFFF)
31 /* Used to know if a message is not present in kernel queue */
32 #define KE_MSG_NOT_IN_QUEUE     ((struct co_list_hdr *) 0xFFFFFFFF)
33 
34 /// Status of ke_task API functions
35 enum KE_TASK_STATUS
36 {
37     KE_TASK_OK = 0,
38     KE_TASK_FAIL,
39     KE_TASK_UNKNOWN,
40     KE_TASK_CAPA_EXCEEDED,
41     KE_TASK_ALREADY_EXISTS,
42 };
43 
44 
45 #define MSG_T(msg)         ((ke_task_id_t)((msg) >> 8))
46 #define MSG_I(msg)         ((msg) & ((1<<8)-1))
47 
48 /// Format of a task message handler function
49 typedef int (*ke_msg_func_t)(ke_msg_id_t const msgid, void const *param,
50                              ke_task_id_t const dest_id, ke_task_id_t const src_id);
51 
52 /// Macro for message handler function declaration or definition
53 #define KE_MSG_HANDLER(msg_name, param_struct)   __STATIC int msg_name##_handler(ke_msg_id_t const msgid,     \
54                                                                                 param_struct const *param,  \
55                                                                                 ke_task_id_t const dest_id, \
56                                                                                 ke_task_id_t const src_id)
57 
58 #define KE_MSG_HANDLER_NO_STATIC(msg_name, param_struct)   int msg_name##_handler(ke_msg_id_t const msgid,     \
59                                                                                 param_struct const *param,  \
60                                                                                 ke_task_id_t const dest_id, \
61                                                                                 ke_task_id_t const src_id)
62 
63 /// Macro for message handlers table declaration or definition
64 #define KE_MSG_HANDLER_TAB(task)   __STATIC const struct ke_msg_handler task##_msg_handler_tab[] =
65 
66 /// Element of a message handler table.
67 struct ke_msg_handler
68 {
69     /// Id of the handled message.
70     ke_msg_id_t id;
71     /// Pointer to the handler function for the msgid above.
72     ke_msg_func_t func;
73 };
74 
75 /// Element of a state handler table.
76 struct ke_state_handler
77 {
78     /// Pointer to the message handler table of this state.
79     const struct ke_msg_handler *msg_table;
80     /// Number of messages handled in this state.
81     uint16_t msg_cnt;
82 };
83 
84 /// Task descriptor grouping all information required by the kernel for the scheduling.
85 struct ke_task_desc
86 {
87     /// Pointer to the message handler table
88     const struct ke_msg_handler* msg_handler_tab;
89     /// Pointer to the state table (one element for each instance).
90     ke_state_t* state;
91     /// Maximum index of supported instances of the task.
92     uint16_t idx_max;
93     /// Number of messages handled
94     uint16_t msg_cnt;
95 };
96 
97 /*
98  * FUNCTION PROTOTYPES
99  ****************************************************************************************
100  */
101 
102 
103 /**
104  ****************************************************************************************
105  * @brief Initialize Kernel task module.
106  ****************************************************************************************
107  */
108 void ke_task_init(void);
109 
110 /**
111  ****************************************************************************************
112  * @brief Create a task.
113  *
114  * @param[in]  task_type       Task type.
115  * @param[in]  p_task_desc     Pointer to task descriptor.
116  *
117  * @return                     Status
118  ****************************************************************************************
119  */
120 uint8_t ke_task_create(uint8_t task_type, struct ke_task_desc const * p_task_desc);
121 
122 /**
123  ****************************************************************************************
124  * @brief Delete a task.
125  *
126  * @param[in]  task_type       Task type.
127  *
128  * @return                     Status
129  ****************************************************************************************
130  */
131 uint8_t ke_task_delete(uint8_t task_type);
132 
133 /**
134  ****************************************************************************************
135  * @brief Retrieve the state of a task.
136  *
137  * @param[in]  id   Task id.
138  *
139  * @return          Current state of the task
140  ****************************************************************************************
141  */
142 ke_state_t ke_state_get(ke_task_id_t const id);
143 
144 /**
145  ****************************************************************************************
146  * @brief Set the state of the task identified by its Task Id.
147  *
148  * In this function we also handle the SAVE service: when a task state changes we
149  * try to activate all the messages currently saved in the save queue for the given
150  * task identifier.
151  *
152  * @param[in]  id          Identifier of the task instance whose state is going to be modified
153  * @param[in]  state_id    New State
154  *
155  ****************************************************************************************
156  */
157 void ke_state_set(ke_task_id_t const id, ke_state_t const state_id);
158 
159 /**
160  ****************************************************************************************
161  * @brief Generic message handler to consume message without handling it in the task.
162  *
163  * @param[in] msgid Id of the message received (probably unused)
164  * @param[in] param Pointer to the parameters of the message.
165  * @param[in] dest_id TaskId of the receiving task.
166  * @param[in] src_id TaskId of the sending task.
167  *
168  * @return KE_MSG_CONSUMED
169  ****************************************************************************************
170  */
171 int ke_msg_discard(ke_msg_id_t const msgid, void const *param,
172                    ke_task_id_t const dest_id, ke_task_id_t const src_id);
173 
174 /**
175  ****************************************************************************************
176  * @brief Generic message handler to consume message without handling it in the task.
177  *
178  * @param[in] msgid Id of the message received (probably unused)
179  * @param[in] param Pointer to the parameters of the message.
180  * @param[in] dest_id TaskId of the receiving task.
181  * @param[in] src_id TaskId of the sending task.
182  *
183  * @return KE_MSG_CONSUMED
184  ****************************************************************************************
185  */
186 int ke_msg_save(ke_msg_id_t const msgid, void const *param,
187                 ke_task_id_t const dest_id, ke_task_id_t const src_id);
188 
189 
190 
191 /**
192  ****************************************************************************************
193  * @brief This function flushes all messages, currently pending in the kernel for a
194  * specific task.
195  *
196  * @param[in] task The Task Identifier that shall be flushed.
197  ****************************************************************************************
198  */
199 void ke_task_msg_flush(ke_task_id_t task);
200 
201 
202 /**
203  ****************************************************************************************
204  * @brief Check validity of a task. If task type or task instance does not exist,
205  * return invalid task
206  *
207  * @param[in] task Task Identifier to check.
208  *
209  * @return Task identifier if valid, invalid identifier else.
210  ****************************************************************************************
211  */
212 ke_task_id_t ke_task_check(ke_task_id_t task);
213 
214 void ke_task_msg_retrieve(ke_task_id_t const id);
215 
216 /// @} TASK
217 
218 #endif // _KE_TASK_H_
219 
220