Keyboard firmwares for Atmel AVR and Cortex-M
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rt_Semaphore.c 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*----------------------------------------------------------------------------
  2. * RL-ARM - RTX
  3. *----------------------------------------------------------------------------
  4. * Name: RT_SEMAPHORE.C
  5. * Purpose: Implements binary and counting semaphores
  6. * Rev.: V4.60
  7. *----------------------------------------------------------------------------
  8. *
  9. * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH
  10. * All rights reserved.
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions are met:
  13. * - Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * - Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. * - Neither the name of ARM nor the names of its contributors may be used
  19. * to endorse or promote products derived from this software without
  20. * specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25. * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
  26. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  27. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  28. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  29. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  30. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  31. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32. * POSSIBILITY OF SUCH DAMAGE.
  33. *---------------------------------------------------------------------------*/
  34. #include "rt_TypeDef.h"
  35. #include "RTX_Config.h"
  36. #include "rt_System.h"
  37. #include "rt_List.h"
  38. #include "rt_Task.h"
  39. #include "rt_Semaphore.h"
  40. #ifdef __CORTEX_A9
  41. #include "rt_HAL_CA.h"
  42. #else
  43. #include "rt_HAL_CM.h"
  44. #endif
  45. /*----------------------------------------------------------------------------
  46. * Functions
  47. *---------------------------------------------------------------------------*/
  48. /*--------------------------- rt_sem_init -----------------------------------*/
  49. void rt_sem_init (OS_ID semaphore, U16 token_count) {
  50. /* Initialize a semaphore */
  51. P_SCB p_SCB = semaphore;
  52. p_SCB->cb_type = SCB;
  53. p_SCB->p_lnk = NULL;
  54. p_SCB->tokens = token_count;
  55. }
  56. /*--------------------------- rt_sem_delete ---------------------------------*/
  57. #ifdef __CMSIS_RTOS
  58. OS_RESULT rt_sem_delete (OS_ID semaphore) {
  59. /* Delete semaphore */
  60. P_SCB p_SCB = semaphore;
  61. P_TCB p_TCB;
  62. __DMB();
  63. while (p_SCB->p_lnk != NULL) {
  64. /* A task is waiting for token */
  65. p_TCB = rt_get_first ((P_XCB)p_SCB);
  66. rt_ret_val(p_TCB, 0);
  67. rt_rmv_dly(p_TCB);
  68. p_TCB->state = READY;
  69. rt_put_prio (&os_rdy, p_TCB);
  70. }
  71. if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) {
  72. /* preempt running task */
  73. rt_put_prio (&os_rdy, os_tsk.run);
  74. os_tsk.run->state = READY;
  75. rt_dispatch (NULL);
  76. }
  77. p_SCB->cb_type = 0;
  78. return (OS_R_OK);
  79. }
  80. #endif
  81. /*--------------------------- rt_sem_send -----------------------------------*/
  82. OS_RESULT rt_sem_send (OS_ID semaphore) {
  83. /* Return a token to semaphore */
  84. P_SCB p_SCB = semaphore;
  85. P_TCB p_TCB;
  86. __DMB();
  87. if (p_SCB->p_lnk != NULL) {
  88. /* A task is waiting for token */
  89. p_TCB = rt_get_first ((P_XCB)p_SCB);
  90. #ifdef __CMSIS_RTOS
  91. rt_ret_val(p_TCB, 1);
  92. #else
  93. rt_ret_val(p_TCB, OS_R_SEM);
  94. #endif
  95. rt_rmv_dly (p_TCB);
  96. rt_dispatch (p_TCB);
  97. }
  98. else {
  99. /* Store token. */
  100. p_SCB->tokens++;
  101. }
  102. return (OS_R_OK);
  103. }
  104. /*--------------------------- rt_sem_wait -----------------------------------*/
  105. OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout) {
  106. /* Obtain a token; possibly wait for it */
  107. P_SCB p_SCB = semaphore;
  108. if (p_SCB->tokens) {
  109. p_SCB->tokens--;
  110. __DMB();
  111. return (OS_R_OK);
  112. }
  113. /* No token available: wait for one */
  114. if (timeout == 0) {
  115. return (OS_R_TMO);
  116. }
  117. if (p_SCB->p_lnk != NULL) {
  118. rt_put_prio ((P_XCB)p_SCB, os_tsk.run);
  119. }
  120. else {
  121. p_SCB->p_lnk = os_tsk.run;
  122. os_tsk.run->p_lnk = NULL;
  123. os_tsk.run->p_rlnk = (P_TCB)p_SCB;
  124. }
  125. rt_block(timeout, WAIT_SEM);
  126. return (OS_R_TMO);
  127. }
  128. /*--------------------------- isr_sem_send ----------------------------------*/
  129. void isr_sem_send (OS_ID semaphore) {
  130. /* Same function as "os_sem"send", but to be called by ISRs */
  131. P_SCB p_SCB = semaphore;
  132. rt_psq_enq (p_SCB, 0);
  133. rt_psh_req ();
  134. }
  135. /*--------------------------- rt_sem_psh ------------------------------------*/
  136. void rt_sem_psh (P_SCB p_CB) {
  137. /* Check if task has to be waken up */
  138. P_TCB p_TCB;
  139. __DMB();
  140. if (p_CB->p_lnk != NULL) {
  141. /* A task is waiting for token */
  142. p_TCB = rt_get_first ((P_XCB)p_CB);
  143. rt_rmv_dly (p_TCB);
  144. p_TCB->state = READY;
  145. #ifdef __CMSIS_RTOS
  146. rt_ret_val(p_TCB, 1);
  147. #else
  148. rt_ret_val(p_TCB, OS_R_SEM);
  149. #endif
  150. rt_put_prio (&os_rdy, p_TCB);
  151. }
  152. else {
  153. /* Store token */
  154. p_CB->tokens++;
  155. }
  156. }
  157. /*----------------------------------------------------------------------------
  158. * end of file
  159. *---------------------------------------------------------------------------*/