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

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