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