rt_System.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /*----------------------------------------------------------------------------
  2. * RL-ARM - RTX
  3. *----------------------------------------------------------------------------
  4. * Name: RT_SYSTEM.C
  5. * Purpose: System Task Manager
  6. * Rev.: V4.70
  7. *----------------------------------------------------------------------------
  8. *
  9. * Copyright (c) 1999-2009 KEIL, 2009-2013 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_Task.h"
  37. #include "rt_System.h"
  38. #include "rt_Event.h"
  39. #include "rt_List.h"
  40. #include "rt_Mailbox.h"
  41. #include "rt_Semaphore.h"
  42. #include "rt_Time.h"
  43. #include "rt_Timer.h"
  44. #include "rt_Robin.h"
  45. #include "rt_HAL_CM.h"
  46. /*----------------------------------------------------------------------------
  47. * Global Variables
  48. *---------------------------------------------------------------------------*/
  49. int os_tick_irqn;
  50. /*----------------------------------------------------------------------------
  51. * Local Variables
  52. *---------------------------------------------------------------------------*/
  53. static volatile BIT os_lock;
  54. static volatile BIT os_psh_flag;
  55. static U8 pend_flags;
  56. /*----------------------------------------------------------------------------
  57. * Global Functions
  58. *---------------------------------------------------------------------------*/
  59. #if defined (__CC_ARM)
  60. __asm void $$RTX$$version (void) {
  61. /* Export a version number symbol for a version control. */
  62. EXPORT __RL_RTX_VER
  63. __RL_RTX_VER EQU 0x450
  64. }
  65. #endif
  66. /*--------------------------- rt_suspend ------------------------------------*/
  67. U32 rt_suspend (void) {
  68. /* Suspend OS scheduler */
  69. U32 delta = 0xFFFF;
  70. rt_tsk_lock();
  71. if (os_dly.p_dlnk) {
  72. delta = os_dly.delta_time;
  73. }
  74. #ifndef __CMSIS_RTOS
  75. if (os_tmr.next) {
  76. if (os_tmr.tcnt < delta) delta = os_tmr.tcnt;
  77. }
  78. #endif
  79. return (delta);
  80. }
  81. /*--------------------------- rt_resume -------------------------------------*/
  82. void rt_resume (U32 sleep_time) {
  83. /* Resume OS scheduler after suspend */
  84. P_TCB next;
  85. U32 delta;
  86. os_tsk.run->state = READY;
  87. rt_put_rdy_first (os_tsk.run);
  88. os_robin.task = NULL;
  89. /* Update delays. */
  90. if (os_dly.p_dlnk) {
  91. delta = sleep_time;
  92. if (delta >= os_dly.delta_time) {
  93. delta -= os_dly.delta_time;
  94. os_time += os_dly.delta_time;
  95. os_dly.delta_time = 1;
  96. while (os_dly.p_dlnk) {
  97. rt_dec_dly();
  98. if (delta == 0) break;
  99. delta--;
  100. os_time++;
  101. }
  102. } else {
  103. os_time += delta;
  104. os_dly.delta_time -= delta;
  105. }
  106. } else {
  107. os_time += sleep_time;
  108. }
  109. #ifndef __CMSIS_RTOS
  110. /* Check the user timers. */
  111. if (os_tmr.next) {
  112. delta = sleep_time;
  113. if (delta >= os_tmr.tcnt) {
  114. delta -= os_tmr.tcnt;
  115. os_tmr.tcnt = 1;
  116. while (os_tmr.next) {
  117. rt_tmr_tick();
  118. if (delta == 0) break;
  119. delta--;
  120. }
  121. } else {
  122. os_tmr.tcnt -= delta;
  123. }
  124. }
  125. #endif
  126. /* Switch back to highest ready task */
  127. next = rt_get_first (&os_rdy);
  128. rt_switch_req (next);
  129. rt_tsk_unlock();
  130. }
  131. /*--------------------------- rt_tsk_lock -----------------------------------*/
  132. void rt_tsk_lock (void) {
  133. /* Prevent task switching by locking out scheduler */
  134. if (os_tick_irqn < 0) {
  135. OS_LOCK();
  136. os_lock = __TRUE;
  137. OS_UNPEND (&pend_flags);
  138. } else {
  139. OS_X_LOCK(os_tick_irqn);
  140. os_lock = __TRUE;
  141. OS_X_UNPEND (&pend_flags);
  142. }
  143. }
  144. /*--------------------------- rt_tsk_unlock ---------------------------------*/
  145. void rt_tsk_unlock (void) {
  146. /* Unlock scheduler and re-enable task switching */
  147. if (os_tick_irqn < 0) {
  148. OS_UNLOCK();
  149. os_lock = __FALSE;
  150. OS_PEND (pend_flags, os_psh_flag);
  151. os_psh_flag = __FALSE;
  152. } else {
  153. OS_X_UNLOCK(os_tick_irqn);
  154. os_lock = __FALSE;
  155. OS_X_PEND (pend_flags, os_psh_flag);
  156. os_psh_flag = __FALSE;
  157. }
  158. }
  159. /*--------------------------- rt_psh_req ------------------------------------*/
  160. void rt_psh_req (void) {
  161. /* Initiate a post service handling request if required. */
  162. if (os_lock == __FALSE) {
  163. OS_PEND_IRQ ();
  164. }
  165. else {
  166. os_psh_flag = __TRUE;
  167. }
  168. }
  169. /*--------------------------- rt_pop_req ------------------------------------*/
  170. void rt_pop_req (void) {
  171. /* Process an ISR post service requests. */
  172. struct OS_XCB *p_CB;
  173. P_TCB next;
  174. U32 idx;
  175. os_tsk.run->state = READY;
  176. rt_put_rdy_first (os_tsk.run);
  177. idx = os_psq->last;
  178. while (os_psq->count) {
  179. p_CB = os_psq->q[idx].id;
  180. if (p_CB->cb_type == TCB) {
  181. /* Is of TCB type */
  182. rt_evt_psh ((P_TCB)p_CB, (U16)os_psq->q[idx].arg);
  183. }
  184. else if (p_CB->cb_type == MCB) {
  185. /* Is of MCB type */
  186. rt_mbx_psh ((P_MCB)p_CB, (void *)os_psq->q[idx].arg);
  187. }
  188. else {
  189. /* Must be of SCB type */
  190. rt_sem_psh ((P_SCB)p_CB);
  191. }
  192. if (++idx == os_psq->size) idx = 0;
  193. rt_dec (&os_psq->count);
  194. }
  195. os_psq->last = idx;
  196. next = rt_get_first (&os_rdy);
  197. rt_switch_req (next);
  198. }
  199. /*--------------------------- os_tick_init ----------------------------------*/
  200. __weak int os_tick_init (void) {
  201. /* Initialize SysTick timer as system tick timer. */
  202. rt_systick_init();
  203. return (-1); /* Return IRQ number of SysTick timer */
  204. }
  205. /*--------------------------- os_tick_val -----------------------------------*/
  206. __weak U32 os_tick_val (void) {
  207. /* Get SysTick timer current value (0 .. OS_TRV). */
  208. return rt_systick_val();
  209. }
  210. /*--------------------------- os_tick_ovf -----------------------------------*/
  211. __weak U32 os_tick_ovf (void) {
  212. /* Get SysTick timer overflow flag */
  213. return rt_systick_ovf();
  214. }
  215. /*--------------------------- os_tick_irqack --------------------------------*/
  216. __weak void os_tick_irqack (void) {
  217. /* Acknowledge timer interrupt. */
  218. }
  219. /*--------------------------- rt_systick ------------------------------------*/
  220. extern void sysTimerTick(void);
  221. void rt_systick (void) {
  222. /* Check for system clock update, suspend running task. */
  223. P_TCB next;
  224. os_tsk.run->state = READY;
  225. rt_put_rdy_first (os_tsk.run);
  226. /* Check Round Robin timeout. */
  227. rt_chk_robin ();
  228. /* Update delays. */
  229. os_time++;
  230. rt_dec_dly ();
  231. /* Check the user timers. */
  232. #ifdef __CMSIS_RTOS
  233. sysTimerTick();
  234. #else
  235. rt_tmr_tick ();
  236. #endif
  237. /* Switch back to highest ready task */
  238. next = rt_get_first (&os_rdy);
  239. rt_switch_req (next);
  240. }
  241. /*--------------------------- rt_stk_check ----------------------------------*/
  242. __weak void rt_stk_check (void) {
  243. /* Check for stack overflow. */
  244. if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) ||
  245. (os_tsk.run->stack[0] != MAGIC_WORD)) {
  246. os_error (OS_ERR_STK_OVF);
  247. }
  248. }
  249. /*----------------------------------------------------------------------------
  250. * end of file
  251. *---------------------------------------------------------------------------*/