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