rt_Event.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*----------------------------------------------------------------------------
  2. * CMSIS-RTOS - RTX
  3. *----------------------------------------------------------------------------
  4. * Name: RT_EVENT.C
  5. * Purpose: Implements waits and wake-ups for event flags
  6. * Rev.: V4.79
  7. *----------------------------------------------------------------------------
  8. *
  9. * Copyright (c) 1999-2009 KEIL, 2009-2017 ARM Germany GmbH. All rights reserved.
  10. *
  11. * SPDX-License-Identifier: Apache-2.0
  12. *
  13. * Licensed under the Apache License, Version 2.0 (the License); you may
  14. * not use this file except in compliance with the License.
  15. * You may obtain a copy of the License at
  16. *
  17. * www.apache.org/licenses/LICENSE-2.0
  18. *
  19. * Unless required by applicable law or agreed to in writing, software
  20. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  21. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22. * See the License for the specific language governing permissions and
  23. * limitations under the License.
  24. *---------------------------------------------------------------------------*/
  25. #include "rt_TypeDef.h"
  26. #include "RTX_Config.h"
  27. #include "rt_System.h"
  28. #include "rt_Event.h"
  29. #include "rt_List.h"
  30. #include "rt_Task.h"
  31. #include "rt_HAL_CM.h"
  32. /*----------------------------------------------------------------------------
  33. * Functions
  34. *---------------------------------------------------------------------------*/
  35. /*--------------------------- rt_evt_wait -----------------------------------*/
  36. OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait) {
  37. /* Wait for one or more event flags with optional time-out. */
  38. /* "wait_flags" identifies the flags to wait for. */
  39. /* "timeout" is the time-out limit in system ticks (0xffff if no time-out) */
  40. /* "and_wait" specifies the AND-ing of "wait_flags" as condition to be met */
  41. /* to complete the wait. (OR-ing if set to 0). */
  42. U32 block_state;
  43. if (and_wait) {
  44. /* Check for AND-connected events */
  45. if ((os_tsk.run->events & wait_flags) == wait_flags) {
  46. os_tsk.run->events &= ~wait_flags;
  47. return (OS_R_EVT);
  48. }
  49. block_state = WAIT_AND;
  50. }
  51. else {
  52. /* Check for OR-connected events */
  53. if (os_tsk.run->events & wait_flags) {
  54. os_tsk.run->waits = os_tsk.run->events & wait_flags;
  55. os_tsk.run->events &= ~wait_flags;
  56. return (OS_R_EVT);
  57. }
  58. block_state = WAIT_OR;
  59. }
  60. /* Task has to wait */
  61. os_tsk.run->waits = wait_flags;
  62. rt_block (timeout, (U8)block_state);
  63. return (OS_R_TMO);
  64. }
  65. /*--------------------------- rt_evt_set ------------------------------------*/
  66. void rt_evt_set (U16 event_flags, OS_TID task_id) {
  67. /* Set one or more event flags of a selectable task. */
  68. P_TCB p_tcb;
  69. p_tcb = os_active_TCB[task_id-1U];
  70. if (p_tcb == NULL) {
  71. return;
  72. }
  73. p_tcb->events |= event_flags;
  74. event_flags = p_tcb->waits;
  75. /* If the task is not waiting for an event, it should not be put */
  76. /* to ready state. */
  77. if (p_tcb->state == WAIT_AND) {
  78. /* Check for AND-connected events */
  79. if ((p_tcb->events & event_flags) == event_flags) {
  80. goto wkup;
  81. }
  82. }
  83. if (p_tcb->state == WAIT_OR) {
  84. /* Check for OR-connected events */
  85. if (p_tcb->events & event_flags) {
  86. p_tcb->waits &= p_tcb->events;
  87. wkup: p_tcb->events &= ~event_flags;
  88. rt_rmv_dly (p_tcb);
  89. p_tcb->state = READY;
  90. #ifdef __CMSIS_RTOS
  91. rt_ret_val2(p_tcb, 0x08U/*osEventSignal*/, p_tcb->waits);
  92. #else
  93. rt_ret_val (p_tcb, OS_R_EVT);
  94. #endif
  95. rt_dispatch (p_tcb);
  96. }
  97. }
  98. }
  99. /*--------------------------- rt_evt_clr ------------------------------------*/
  100. void rt_evt_clr (U16 clear_flags, OS_TID task_id) {
  101. /* Clear one or more event flags (identified by "clear_flags") of a */
  102. /* selectable task (identified by "task"). */
  103. P_TCB task = os_active_TCB[task_id-1U];
  104. if (task == NULL) {
  105. return;
  106. }
  107. task->events &= ~clear_flags;
  108. }
  109. /*--------------------------- isr_evt_set -----------------------------------*/
  110. void isr_evt_set (U16 event_flags, OS_TID task_id) {
  111. /* Same function as "os_evt_set", but to be called by ISRs. */
  112. P_TCB p_tcb = os_active_TCB[task_id-1U];
  113. if (p_tcb == NULL) {
  114. return;
  115. }
  116. rt_psq_enq (p_tcb, event_flags);
  117. rt_psh_req ();
  118. }
  119. /*--------------------------- rt_evt_get ------------------------------------*/
  120. U16 rt_evt_get (void) {
  121. /* Get events of a running task after waiting for OR connected events. */
  122. return (os_tsk.run->waits);
  123. }
  124. /*--------------------------- rt_evt_psh ------------------------------------*/
  125. void rt_evt_psh (P_TCB p_CB, U16 set_flags) {
  126. /* Check if task has to be waken up */
  127. U16 event_flags;
  128. p_CB->events |= set_flags;
  129. event_flags = p_CB->waits;
  130. if (p_CB->state == WAIT_AND) {
  131. /* Check for AND-connected events */
  132. if ((p_CB->events & event_flags) == event_flags) {
  133. goto rdy;
  134. }
  135. }
  136. if (p_CB->state == WAIT_OR) {
  137. /* Check for OR-connected events */
  138. if (p_CB->events & event_flags) {
  139. p_CB->waits &= p_CB->events;
  140. rdy: p_CB->events &= ~event_flags;
  141. rt_rmv_dly (p_CB);
  142. p_CB->state = READY;
  143. #ifdef __CMSIS_RTOS
  144. rt_ret_val2(p_CB, 0x08U/*osEventSignal*/, p_CB->waits);
  145. #else
  146. rt_ret_val (p_CB, OS_R_EVT);
  147. #endif
  148. rt_put_prio (&os_rdy, p_CB);
  149. }
  150. }
  151. }
  152. /*----------------------------------------------------------------------------
  153. * end of file
  154. *---------------------------------------------------------------------------*/