]> git.gir.st - tmk_keyboard.git/blob - tool/mbed/mbed-sdk/libraries/rtos/rtx/TARGET_CORTEX_A/rt_System.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[tmk_keyboard.git] / tool / mbed / mbed-sdk / libraries / rtos / rtx / TARGET_CORTEX_A / rt_System.c
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
35 #include "rt_TypeDef.h"
36 #include "RTX_Config.h"
37 #include "rt_Task.h"
38 #include "rt_System.h"
39 #include "rt_Event.h"
40 #include "rt_List.h"
41 #include "rt_Mailbox.h"
42 #include "rt_Semaphore.h"
43 #include "rt_Time.h"
44 #include "rt_Timer.h"
45 #include "rt_Robin.h"
46 #ifdef __CORTEX_A9
47 #include "rt_HAL_CA.h"
48 #else
49 #include "rt_HAL_CM.h"
50 #endif
51
52 /*----------------------------------------------------------------------------
53 * Global Variables
54 *---------------------------------------------------------------------------*/
55
56 int os_tick_irqn;
57
58 /*----------------------------------------------------------------------------
59 * Local Variables
60 *---------------------------------------------------------------------------*/
61
62 static volatile BIT os_lock;
63 static volatile BIT os_psh_flag;
64 #ifndef __CORTEX_A9
65 static U8 pend_flags;
66 #endif
67 /*----------------------------------------------------------------------------
68 * Global Functions
69 *---------------------------------------------------------------------------*/
70
71 #if defined (__CC_ARM)
72 __asm void $$RTX$$version (void) {
73 /* Export a version number symbol for a version control. */
74
75 EXPORT __RL_RTX_VER
76
77 __RL_RTX_VER EQU 0x450
78 }
79 #endif
80
81
82 /*--------------------------- rt_suspend ------------------------------------*/
83
84 U32 rt_suspend (void) {
85 /* Suspend OS scheduler */
86 U32 delta = 0xFFFF;
87
88 rt_tsk_lock();
89
90 if (os_dly.p_dlnk) {
91 delta = os_dly.delta_time;
92 }
93 #ifndef __CMSIS_RTOS
94 if (os_tmr.next) {
95 if (os_tmr.tcnt < delta) delta = os_tmr.tcnt;
96 }
97 #endif
98
99 return (delta);
100 }
101
102
103 /*--------------------------- rt_resume -------------------------------------*/
104
105 void rt_resume (U32 sleep_time) {
106 /* Resume OS scheduler after suspend */
107 P_TCB next;
108 U32 delta;
109
110 os_tsk.run->state = READY;
111 rt_put_rdy_first (os_tsk.run);
112
113 os_robin.task = NULL;
114
115 /* Update delays. */
116 if (os_dly.p_dlnk) {
117 delta = sleep_time;
118 if (delta >= os_dly.delta_time) {
119 delta -= os_dly.delta_time;
120 os_time += os_dly.delta_time;
121 os_dly.delta_time = 1;
122 while (os_dly.p_dlnk) {
123 rt_dec_dly();
124 if (delta == 0) break;
125 delta--;
126 os_time++;
127 }
128 } else {
129 os_time += delta;
130 os_dly.delta_time -= delta;
131 }
132 } else {
133 os_time += sleep_time;
134 }
135
136 #ifndef __CMSIS_RTOS
137 /* Check the user timers. */
138 if (os_tmr.next) {
139 delta = sleep_time;
140 if (delta >= os_tmr.tcnt) {
141 delta -= os_tmr.tcnt;
142 os_tmr.tcnt = 1;
143 while (os_tmr.next) {
144 rt_tmr_tick();
145 if (delta == 0) break;
146 delta--;
147 }
148 } else {
149 os_tmr.tcnt -= delta;
150 }
151 }
152 #endif
153
154 /* Switch back to highest ready task */
155 next = rt_get_first (&os_rdy);
156 rt_switch_req (next);
157
158 rt_tsk_unlock();
159 }
160
161
162 /*--------------------------- rt_tsk_lock -----------------------------------*/
163
164 void rt_tsk_lock (void) {
165 /* Prevent task switching by locking out scheduler */
166 if (os_tick_irqn < 0) {
167 OS_LOCK();
168 os_lock = __TRUE;
169 OS_UNPEND (&pend_flags);
170 } else {
171 OS_X_LOCK(os_tick_irqn);
172 os_lock = __TRUE;
173 OS_X_UNPEND (&pend_flags);
174 }
175 }
176
177
178 /*--------------------------- rt_tsk_unlock ---------------------------------*/
179
180 void rt_tsk_unlock (void) {
181 /* Unlock scheduler and re-enable task switching */
182 if (os_tick_irqn < 0) {
183 OS_UNLOCK();
184 os_lock = __FALSE;
185 OS_PEND (pend_flags, os_psh_flag);
186 os_psh_flag = __FALSE;
187 } else {
188 OS_X_UNLOCK(os_tick_irqn);
189 os_lock = __FALSE;
190 OS_X_PEND (pend_flags, os_psh_flag);
191 os_psh_flag = __FALSE;
192 }
193 }
194
195
196 /*--------------------------- rt_psh_req ------------------------------------*/
197
198 void rt_psh_req (void) {
199 /* Initiate a post service handling request if required. */
200 if (os_lock == __FALSE) {
201 OS_PEND_IRQ ();
202 }
203 else {
204 os_psh_flag = __TRUE;
205 }
206 }
207
208
209 /*--------------------------- rt_pop_req ------------------------------------*/
210
211 void rt_pop_req (void) {
212 /* Process an ISR post service requests. */
213 struct OS_XCB *p_CB;
214 P_TCB next;
215 U32 idx;
216
217 os_tsk.run->state = READY;
218 rt_put_rdy_first (os_tsk.run);
219
220 idx = os_psq->last;
221 while (os_psq->count) {
222 p_CB = os_psq->q[idx].id;
223 if (p_CB->cb_type == TCB) {
224 /* Is of TCB type */
225 rt_evt_psh ((P_TCB)p_CB, (U16)os_psq->q[idx].arg);
226 }
227 else if (p_CB->cb_type == MCB) {
228 /* Is of MCB type */
229 rt_mbx_psh ((P_MCB)p_CB, (void *)os_psq->q[idx].arg);
230 }
231 else {
232 /* Must be of SCB type */
233 rt_sem_psh ((P_SCB)p_CB);
234 }
235 if (++idx == os_psq->size) idx = 0;
236 rt_dec (&os_psq->count);
237 }
238 os_psq->last = idx;
239
240 next = rt_get_first (&os_rdy);
241 rt_switch_req (next);
242 }
243
244
245 /*--------------------------- os_tick_init ----------------------------------*/
246
247 __weak int os_tick_init (void) {
248 /* Initialize SysTick timer as system tick timer. */
249 rt_systick_init ();
250 return (-1); /* Return IRQ number of SysTick timer */
251 }
252
253
254 /*--------------------------- os_tick_irqack --------------------------------*/
255
256 __weak void os_tick_irqack (void) {
257 /* Acknowledge timer interrupt. */
258 }
259
260
261 /*--------------------------- rt_systick ------------------------------------*/
262
263 extern void sysTimerTick(void);
264
265 void rt_systick (void) {
266 /* Check for system clock update, suspend running task. */
267 P_TCB next;
268
269 os_tsk.run->state = READY;
270 rt_put_rdy_first (os_tsk.run);
271
272 /* Check Round Robin timeout. */
273 rt_chk_robin ();
274
275 /* Update delays. */
276 os_time++;
277 rt_dec_dly ();
278
279 /* Check the user timers. */
280 #ifdef __CMSIS_RTOS
281 sysTimerTick();
282 #else
283 rt_tmr_tick ();
284 #endif
285
286 /* Switch back to highest ready task */
287 next = rt_get_first (&os_rdy);
288 rt_switch_req (next);
289 }
290
291 /*--------------------------- rt_stk_check ----------------------------------*/
292
293 __weak void rt_stk_check (void) {
294 /* Check for stack overflow. */
295 if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) ||
296 (os_tsk.run->stack[0] != MAGIC_WORD)) {
297 os_error (OS_ERR_STK_OVF);
298 }
299 }
300
301 /*----------------------------------------------------------------------------
302 * end of file
303 *---------------------------------------------------------------------------*/
304
Imprint / Impressum