1 /** 2 * Copyright (c) 2015, Realtek Semiconductor Corporation. All rights reserved. 3 */ 4 5 #ifndef _OS_TASK_H_ 6 #define _OS_TASK_H_ 7 8 #include <stdint.h> 9 #include <stdbool.h> 10 11 #ifdef __cplusplus 12 extern "C" { 13 #endif 14 15 /** 16 * \addtogroup OS OSIF 17 * \defgroup Task Task Management 18 * 19 * \brief Define, create, and control task functions. 20 * \details The Task Management function group allows to create, delete, and control tasks 21 * in the system.\n 22 * Tasks can be in the following states:\n 23 * \arg <b>RUNNING:</b> The task that is currently running is in the <b>RUNNING</b> state. 24 * Only one task at a time can be in this state. 25 * \arg <b>READY:</b> Tasks which are ready to run are in the <b>READY</b> state. Once the 26 * <b>RUNNING</b> task has terminated or is <b>WAITING</b>, the next 27 * <b>READY</b> task with the highest priority becomes the <b>RUNNING</b> task. 28 * \arg <b>WAITING:</b> Tasks that are waiting for an event to occur are in the WAITING state. 29 * \arg <b>INACTIVE</b>: Tasks that are not created or terminated are in the <b>INACTIVE</b> state. 30 * These Tasks typically consume no system resources. 31 * 32 * \image html OS-task-state-transition.jpg "Task State Transition" width=526px height=526px 33 * 34 * \ingroup OS 35 */ 36 37 38 /** 39 * os_task.h 40 * 41 * \brief Create a new task and add it to the list of tasks that are ready to run. 42 * 43 * \param[out] pp_handle Used to pass back a handle by which the created task 44 * can be referenced. 45 * 46 * \param[in] p_name A descriptive name for the task. 47 * 48 * \param[in] p_routine Pointer to task routine function that must be implemented 49 * to never return. 50 * 51 * \param[in] p_param Pointer parameter passed to the task routine function. 52 * 53 * \param[in] stack_size The size of the task stack that is specified as the number 54 * of bytes. 55 * 56 * \param[in] priority The priority at which the task should run. Higher priority 57 * task has higher priority value. 58 * 59 * \return The status of the task creation. 60 * \retval true Task was created successfully and added to task ready list. 61 * \retval false Task was failed to create. 62 * 63 * <b>Example usage</b> 64 * \code{.c} 65 * // Task routine implementation. 66 * void task_routine(void *p_param) 67 * { 68 * for (;;) 69 * { 70 * // Task code goes here. 71 * } 72 * } 73 * 74 * // Task to be created. 75 * int test(void) 76 * { 77 * void *p_handle = NULL; 78 * uint32_t task_param; 79 * 80 * if (os_task_create(&p_handle, "task", task_routine, 81 * &task_param, STACK_SIZE, TASK_PRIORITY) == true) 82 * { 83 * // Task created successfully. 84 * } 85 * else 86 * { 87 * // Task failed to create. 88 * return -1; 89 * } 90 * 91 * // Use the handle to delete the task. 92 * os_task_delete(p_handle); 93 * 94 * return 0; 95 * } 96 * \endcode 97 * 98 * \ingroup Task 99 */ 100 bool os_task_create(void **pp_handle, const char *p_name, void (*p_routine)(void *), 101 void *p_param, uint16_t stack_size, uint16_t priority); 102 103 /** 104 * os_task.h 105 * 106 * \brief Remove a task from RTOS's task management. The task being deleted will be removed 107 * from RUNNING, READY or WAITING state. 108 * 109 * \param[in] p_handle The handle of the task to be deleted. 110 * 111 * \return The status of the task deletion. 112 * \retval true Task was deleted successfully. 113 * \retval false Task was failed to delete. 114 * 115 * <b>Example usage</b> 116 * \code{.c} 117 * // Task routine implementation. 118 * void task_routine(void *p_param) 119 * { 120 * for (;;) 121 * { 122 * // Task code goes here. 123 * } 124 * } 125 * 126 * // Task to be created and deleted. 127 * int test(void) 128 * { 129 * void *p_handle = NULL; 130 * uint32_t task_param; 131 * 132 * if (os_task_create(&p_handle, "task", task_routine, 133 * &task_param, STACK_SIZE, TASK_PRIORITY) == true) 134 * { 135 * // Task created successfully. 136 * } 137 * else 138 * { 139 * // Task failed to create. 140 * return -1; 141 * } 142 * 143 * // Use the handle to delete the task. 144 * os_task_delete(p_handle); 145 * 146 * return 0; 147 * } 148 * \endcode 149 * 150 * \ingroup Task 151 */ 152 bool os_task_delete(void *p_handle); 153 154 /** 155 * os_task.h 156 * 157 * \brief Suspend the task. The suspended task will not be scheduled and never get 158 * any microcontroller processing time. 159 * 160 * \param[in] p_handle The handle of the task to be suspended. 161 * 162 * \return The status of the task suspension. 163 * \retval true Task was suspended successfully. 164 * \retval false Task was failed to suspend. 165 * 166 * <b>Example usage</b> 167 * \code{.c} 168 * // Task routine implementation. 169 * void task_routine(void *p_param) 170 * { 171 * for (;;) 172 * { 173 * // Task code goes here. 174 * } 175 * } 176 * 177 * // Task to be created and suspended. 178 * int test(void) 179 * { 180 * void *p_handle = NULL; 181 * uint32_t task_param; 182 * 183 * if (os_task_create(&p_handle, "task", task_routine, 184 * &task_param, STACK_SIZE, TASK_PRIORITY) == true) 185 * { 186 * // Task created successfully. 187 * } 188 * else 189 * { 190 * // Task failed to create. 191 * return -1; 192 * } 193 * 194 * // Use the handle to suspend the created task. 195 * os_task_suspend(p_handle); 196 * 197 * return 0; 198 * } 199 * \endcode 200 * 201 * \ingroup Task 202 */ 203 bool os_task_suspend(void *p_handle); 204 205 /** 206 * os_task.h 207 * 208 * \brief Resume the suspended task. 209 * 210 * \param[in] p_handle The handle of the task to be resumed. 211 * 212 * \return The status of the task resume. 213 * \retval true Task was resumed successfully. 214 * \retval false Task was failed to resume. 215 * 216 * <b>Example usage</b> 217 * \code{.c} 218 * // Task routine implementation. 219 * void task_routine(void *p_param) 220 * { 221 * for (;;) 222 * { 223 * // Task code goes here. 224 * } 225 * } 226 * 227 * // Task to be suspended and resumed. 228 * int test(void) 229 * { 230 * void *p_handle = NULL; 231 * uint32_t task_param; 232 * 233 * if (os_task_create(&p_handle, "task", task_routine, 234 * &task_param, STACK_SIZE, TASK_PRIORITY) == true) 235 * { 236 * // Task created successfully. 237 * } 238 * else 239 * { 240 * // Task failed to create. 241 * return -1; 242 * } 243 * 244 * // Use the handle to suspend the created task. 245 * os_task_suspend(p_handle); 246 * 247 * // Resume the suspended task by ourselves. 248 * os_task_resume(p_handle); 249 * return 0; 250 * } 251 * \endcode 252 * 253 * \ingroup Task 254 */ 255 bool os_task_resume(void *p_handle); 256 257 /** 258 * os_task.h 259 * 260 * \brief Force a context swith and pass control to the next task that is in 261 * READY state. 262 * 263 * \param None 264 * 265 * \return The status of the task resume. 266 * \retval true Task was yielded successfully. 267 * \retval false Task was failed to yield. 268 * 269 * <b>Example usage</b> 270 * \code{.c} 271 * // Task routine implementation. 272 * void task_routine(void *p_param) 273 * { 274 * for (;;) 275 * { 276 * // Force a context switch 277 * os_task_yield(); 278 * } 279 * } 280 * 281 * // Task to be created. 282 * int test(void) 283 * { 284 * void *p_handle = NULL; 285 * uint32_t task_param; 286 * 287 * if (os_task_create(&p_handle, "task", task_routine, 288 * &task_param, STACK_SIZE, TASK_PRIORITY) == true) 289 * { 290 * // Task created successfully. 291 * } 292 * else 293 * { 294 * // Task failed to create. 295 * return -1; 296 * } 297 * 298 * return 0; 299 * } 300 * \endcode 301 * 302 * \ingroup Task 303 */ 304 bool os_task_yield(void); 305 306 /** 307 * os_task.h 308 * 309 * \brief Get the handle of the current running task. 310 * 311 * \param[out] pp_handle Used to pass back a handle by which the current task 312 * can be referenced. 313 * 314 * \return The status of getting the current task handle. 315 * \retval true Task handle was got successfully. 316 * \retval false Task handle was failed to get. 317 * 318 * <b>Example usage</b> 319 * \code{.c} 320 * // Get current task handle. 321 * int test(void) 322 * { 323 * void *p_handle = NULL; 324 * 325 * os_task_handle_get(&p_handle); 326 * 327 * return 0; 328 * } 329 * \endcode 330 * 331 * \ingroup Task 332 */ 333 bool os_task_handle_get(void **pp_handle); 334 335 /** 336 * os_task.h 337 * 338 * \brief Get the priority of the specified task. 339 * 340 * \param[in] p_handle The handle of the task to be queried. Passing a NULL handle 341 * means querying the priority of the current task. 342 * 343 * \param[out] p_priority Used to pass back the priority of the task. 344 * 345 * \return The status of getting the task priority. 346 * \retval true Task priority was got successfully. 347 * \retval false Task priority was failed to get. 348 * 349 * <b>Example usage</b> 350 * \code{.c} 351 * int test(void) 352 * { 353 * void *p_handle = NULL; 354 * uint16_t priority; 355 * 356 * if (os_task_create(&p_handle, "task", task_routine, 357 * NULL, STACK_SIZE, TASK_PRIORITY) == true) 358 * { 359 * // Task created successfully. 360 * } 361 * else 362 * { 363 * // Task failed to create. 364 * return -1; 365 * } 366 * 367 * // Get the task priority. 368 * os_task_priority_get(p_handle, &priority); 369 * 370 * return 0; 371 * } 372 * \endcode 373 * 374 * \ingroup Task 375 */ 376 bool os_task_priority_get(void *p_handle, uint16_t *p_priority); 377 378 /** 379 * os_task.h 380 * 381 * \brief Set the priority of the specified task. 382 * 383 * \param[in] p_handle The handle of the task for which the priority is being set. 384 * Passing a NULL handle means setting the priority of the 385 * current task. 386 * 387 * \param[in] priority The priority to which the task will be set. 388 * 389 * \return The status of setting the task priority. 390 * \retval true Task priority was set successfully. 391 * \retval false Task priority was failed to set. 392 * 393 * <b>Example usage</b> 394 * \code{.c} 395 * int test(void) 396 * { 397 * void *p_handle = NULL; 398 * uint16_t priority; 399 * 400 * if (os_task_create(&p_handle, "task", task_routine, 401 * NULL, STACK_SIZE, TASK_PRIORITY) == true) 402 * { 403 * // Task created successfully. 404 * } 405 * else 406 * { 407 * // Task failed to create. 408 * return -1; 409 * } 410 * 411 * // Use the handle to raise the created task priority. 412 * os_task_priority_set(p_handle, TASK_PRIORITY + 1); 413 * 414 * // Use a NULL handle to raise the current task priority. 415 * os_task_priority_set(NULL, TASK_PRIORITY + 1); 416 * 417 * return 0; 418 * } 419 * \endcode 420 * 421 * \ingroup Task 422 */ 423 bool os_task_priority_set(void *p_handle, uint16_t priority); 424 425 bool os_task_signal_init(void); 426 void os_task_signal_deinit(void); 427 /** 428 * os_task.h 429 * 430 * \brief Send a notification signal to the specified task. 431 * 432 * The notification signal sent to a task will remain pending until it is 433 * cleared by the task calling os_task_signal_recv(). If the task was already 434 * in the WAITING state to wait for the singal, then the task will be removed 435 * from WAITING state and the signal cleared. 436 * 437 * \param[in] p_handle The handle of the task to which the signal is sent. 438 * 439 * \param[in] signal The signal to be sent. 440 * 441 * \return The status of sending the signal. 442 * \retval true Task signal was sent successfully. 443 * \retval false Task signal was failed to send. 444 * 445 * <b>Example usage</b> 446 * \code{.c} 447 * int test(void) 448 * { 449 * void *p_handle = NULL; 450 * uint32_t signal; 451 * 452 * if (os_task_create(&p_handle, "task", task_routine, 453 * NULL, STACK_SIZE, TASK_PRIORITY) == true) 454 * { 455 * // Task created successfully. 456 * } 457 * else 458 * { 459 * // Task failed to create. 460 * return -1; 461 * } 462 * 463 * // Send signal to the created task. 464 * singal = 1; 465 * os_task_signal_send(p_handle, signal); 466 * 467 * return 0; 468 * } 469 * \endcode 470 * 471 * \ingroup Task 472 */ 473 bool os_task_signal_send(void *p_handle, uint32_t signal); 474 475 /** 476 * os_task.h 477 * 478 * \brief Wait for a notification signal. 479 * 480 * \param[out] p_signal Used to pass back the received signal. 481 * 482 * \param[in] wait_ms The timeout in milliseconds to wait for the signal. 483 * \arg \c 0 No blocking and return immediately. 484 * \arg \c 0xFFFFFFFF Block infinitely until the signal received. 485 * \arg \c others The timeout value in milliseconds. 486 * 487 * \return The status of receiving the signal. 488 * \retval true Task signal was received successfully. 489 * \retval false Task signal was failed to receive. 490 * 491 * <b>Example usage</b> 492 * \code{.c} 493 * int test(void) 494 * { 495 * uint32_t signal; 496 * 497 * // Block to wait for the signal sent from other tasks. 498 * os_task_signal_recv(&signal, 0xFFFFFFFF); 499 * 500 * return 0; 501 * } 502 * \endcode 503 * 504 * \ingroup Task 505 */ 506 bool os_task_signal_recv(uint32_t *p_signal, uint32_t wait_ms); 507 508 /** 509 * os_task.h 510 * 511 * \brief Clear the signal of the specified task. 512 * 513 * \param[in] p_handle The handle of the task to which the signal is clear. 514 * 515 * \return The status of clearing the signal. 516 * \retval true Task signal was cleared successfully. 517 * \retval false Task signal was failed to clear. 518 * 519 * <b>Example usage</b> 520 * \code{.c} 521 * int test(void) 522 * { 523 * void *p_handle = NULL; 524 * uint32_t signal; 525 * 526 * if (os_task_create(&p_handle, "task", task_routine, 527 * NULL, STACK_SIZE, TASK_PRIORITY) == true) 528 * { 529 * // Task created successfully. 530 * } 531 * else 532 * { 533 * // Task failed to create. 534 * return -1; 535 * } 536 * 537 * // Send signal to the created task. 538 * singal = 1; 539 * os_task_signal_send(p_handle, signal); 540 * 541 * // Clear signal of the created task. 542 * os_task_signal_clear(p_handle); 543 * 544 * return 0; 545 * } 546 * \endcode 547 * 548 * \ingroup Task 549 */ 550 bool os_task_signal_clear(void *p_handle); 551 552 #ifdef __cplusplus 553 } 554 #endif 555 556 #endif /* _OS_TASK_H_ */ 557