]>
git.gir.st - tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/rtos/rtx/TARGET_CORTEX_M/rt_System.c
1 /*----------------------------------------------------------------------------
3 *----------------------------------------------------------------------------
5 * Purpose: System Task Manager
7 *----------------------------------------------------------------------------
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.
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 *---------------------------------------------------------------------------*/
35 #include "rt_TypeDef.h"
38 #include "rt_System.h"
41 #include "rt_Mailbox.h"
42 #include "rt_Semaphore.h"
45 #include "rt_HAL_CM.h"
47 /*----------------------------------------------------------------------------
49 *---------------------------------------------------------------------------*/
53 /*----------------------------------------------------------------------------
55 *---------------------------------------------------------------------------*/
57 static volatile BIT os_lock
;
58 static volatile BIT os_psh_flag
;
61 /*----------------------------------------------------------------------------
63 *---------------------------------------------------------------------------*/
65 #if defined (__CC_ARM)
66 __asm
void $$RTX$$
version (void) {
67 /* Export a version number symbol for a version control. */
71 __RL_RTX_VER EQU
0x450
76 /*--------------------------- rt_suspend ------------------------------------*/
77 U32
rt_suspend (void) {
78 /* Suspend OS scheduler */
84 delta
= os_dly
.delta_time
;
88 if (os_tmr
.tcnt
< delta
) delta
= os_tmr
.tcnt
;
96 /*--------------------------- rt_resume -------------------------------------*/
97 void rt_resume (U32 sleep_time
) {
98 /* Resume OS scheduler after suspend */
102 os_tsk
.run
->state
= READY
;
103 rt_put_rdy_first (os_tsk
.run
);
105 os_robin
.task
= NULL
;
110 if (delta
>= os_dly
.delta_time
) {
111 delta
-= os_dly
.delta_time
;
112 os_time
+= os_dly
.delta_time
;
113 os_dly
.delta_time
= 1;
114 while (os_dly
.p_dlnk
) {
116 if (delta
== 0) break;
122 os_dly
.delta_time
-= delta
;
125 os_time
+= sleep_time
;
129 /* Check the user timers. */
132 if (delta
>= os_tmr
.tcnt
) {
133 delta
-= os_tmr
.tcnt
;
135 while (os_tmr
.next
) {
137 if (delta
== 0) break;
141 os_tmr
.tcnt
-= delta
;
146 /* Switch back to highest ready task */
147 next
= rt_get_first (&os_rdy
);
148 rt_switch_req (next
);
154 /*--------------------------- rt_tsk_lock -----------------------------------*/
156 void rt_tsk_lock (void) {
157 /* Prevent task switching by locking out scheduler */
158 if (os_tick_irqn
< 0) {
161 OS_UNPEND (&pend_flags
);
163 OS_X_LOCK(os_tick_irqn
);
165 OS_X_UNPEND (&pend_flags
);
170 /*--------------------------- rt_tsk_unlock ---------------------------------*/
172 void rt_tsk_unlock (void) {
173 /* Unlock scheduler and re-enable task switching */
174 if (os_tick_irqn
< 0) {
177 OS_PEND (pend_flags
, os_psh_flag
);
178 os_psh_flag
= __FALSE
;
180 OS_X_UNLOCK(os_tick_irqn
);
182 OS_X_PEND (pend_flags
, os_psh_flag
);
183 os_psh_flag
= __FALSE
;
188 /*--------------------------- rt_psh_req ------------------------------------*/
190 void rt_psh_req (void) {
191 /* Initiate a post service handling request if required. */
192 if (os_lock
== __FALSE
) {
196 os_psh_flag
= __TRUE
;
201 /*--------------------------- rt_pop_req ------------------------------------*/
203 void rt_pop_req (void) {
204 /* Process an ISR post service requests. */
209 os_tsk
.run
->state
= READY
;
210 rt_put_rdy_first (os_tsk
.run
);
213 while (os_psq
->count
) {
214 p_CB
= os_psq
->q
[idx
].id
;
215 if (p_CB
->cb_type
== TCB
) {
217 rt_evt_psh ((P_TCB
)p_CB
, (U16
)os_psq
->q
[idx
].arg
);
219 else if (p_CB
->cb_type
== MCB
) {
221 rt_mbx_psh ((P_MCB
)p_CB
, (void *)os_psq
->q
[idx
].arg
);
224 /* Must be of SCB type */
225 rt_sem_psh ((P_SCB
)p_CB
);
227 if (++idx
== os_psq
->size
) idx
= 0;
228 rt_dec (&os_psq
->count
);
232 next
= rt_get_first (&os_rdy
);
233 rt_switch_req (next
);
237 /*--------------------------- os_tick_init ----------------------------------*/
239 __weak
int os_tick_init (void) {
240 /* Initialize SysTick timer as system tick timer. */
242 return (-1); /* Return IRQ number of SysTick timer */
246 /*--------------------------- os_tick_irqack --------------------------------*/
248 __weak
void os_tick_irqack (void) {
249 /* Acknowledge timer interrupt. */
253 /*--------------------------- rt_systick ------------------------------------*/
255 extern void sysTimerTick(void);
257 void rt_systick (void) {
258 /* Check for system clock update, suspend running task. */
261 os_tsk
.run
->state
= READY
;
262 rt_put_rdy_first (os_tsk
.run
);
264 /* Check Round Robin timeout. */
271 /* Check the user timers. */
278 /* Switch back to highest ready task */
279 next
= rt_get_first (&os_rdy
);
280 rt_switch_req (next
);
283 /*--------------------------- rt_stk_check ----------------------------------*/
284 __weak
void rt_stk_check (void) {
285 /* Check for stack overflow. */
286 if (os_tsk
.run
->task_id
== 0x01) {
287 // TODO: For the main thread the check should be done against the main heap pointer
289 if ((os_tsk
.run
->tsk_stack
< (U32
)os_tsk
.run
->stack
) ||
290 (os_tsk
.run
->stack
[0] != MAGIC_WORD
)) {
291 os_error (OS_ERR_STK_OVF
);
296 /*----------------------------------------------------------------------------
298 *---------------------------------------------------------------------------*/