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_System.c 8.0KB

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