modes

Dependents:   mbed_USBserial

Fork of mbed-rtos by mbed official

Committer:
emilmont
Date:
Fri Nov 23 09:57:31 2012 +0000
Revision:
6:350b53afb889
Child:
11:db1fc233faa9
Merge RTOS C++ API and RTX under the same library; Update RTX to version 4.60; Add proper Thread destructor;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
emilmont 6:350b53afb889 1 /*----------------------------------------------------------------------------
emilmont 6:350b53afb889 2 * RL-ARM - RTX
emilmont 6:350b53afb889 3 *----------------------------------------------------------------------------
emilmont 6:350b53afb889 4 * Name: RT_SYSTEM.C
emilmont 6:350b53afb889 5 * Purpose: System Task Manager
emilmont 6:350b53afb889 6 * Rev.: V4.60
emilmont 6:350b53afb889 7 *----------------------------------------------------------------------------
emilmont 6:350b53afb889 8 *
emilmont 6:350b53afb889 9 * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH
emilmont 6:350b53afb889 10 * All rights reserved.
emilmont 6:350b53afb889 11 * Redistribution and use in source and binary forms, with or without
emilmont 6:350b53afb889 12 * modification, are permitted provided that the following conditions are met:
emilmont 6:350b53afb889 13 * - Redistributions of source code must retain the above copyright
emilmont 6:350b53afb889 14 * notice, this list of conditions and the following disclaimer.
emilmont 6:350b53afb889 15 * - Redistributions in binary form must reproduce the above copyright
emilmont 6:350b53afb889 16 * notice, this list of conditions and the following disclaimer in the
emilmont 6:350b53afb889 17 * documentation and/or other materials provided with the distribution.
emilmont 6:350b53afb889 18 * - Neither the name of ARM nor the names of its contributors may be used
emilmont 6:350b53afb889 19 * to endorse or promote products derived from this software without
emilmont 6:350b53afb889 20 * specific prior written permission.
emilmont 6:350b53afb889 21 *
emilmont 6:350b53afb889 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
emilmont 6:350b53afb889 23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
emilmont 6:350b53afb889 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
emilmont 6:350b53afb889 25 * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
emilmont 6:350b53afb889 26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
emilmont 6:350b53afb889 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
emilmont 6:350b53afb889 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
emilmont 6:350b53afb889 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
emilmont 6:350b53afb889 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
emilmont 6:350b53afb889 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
emilmont 6:350b53afb889 32 * POSSIBILITY OF SUCH DAMAGE.
emilmont 6:350b53afb889 33 *---------------------------------------------------------------------------*/
emilmont 6:350b53afb889 34
emilmont 6:350b53afb889 35 #include "rt_TypeDef.h"
emilmont 6:350b53afb889 36 #include "RTX_Config.h"
emilmont 6:350b53afb889 37 #include "rt_Task.h"
emilmont 6:350b53afb889 38 #include "rt_System.h"
emilmont 6:350b53afb889 39 #include "rt_Event.h"
emilmont 6:350b53afb889 40 #include "rt_List.h"
emilmont 6:350b53afb889 41 #include "rt_Mailbox.h"
emilmont 6:350b53afb889 42 #include "rt_Semaphore.h"
emilmont 6:350b53afb889 43 #include "rt_Time.h"
emilmont 6:350b53afb889 44 #include "rt_Robin.h"
emilmont 6:350b53afb889 45 #include "rt_HAL_CM.h"
emilmont 6:350b53afb889 46
emilmont 6:350b53afb889 47 /*----------------------------------------------------------------------------
emilmont 6:350b53afb889 48 * Global Variables
emilmont 6:350b53afb889 49 *---------------------------------------------------------------------------*/
emilmont 6:350b53afb889 50
emilmont 6:350b53afb889 51 int os_tick_irqn;
emilmont 6:350b53afb889 52
emilmont 6:350b53afb889 53 /*----------------------------------------------------------------------------
emilmont 6:350b53afb889 54 * Local Variables
emilmont 6:350b53afb889 55 *---------------------------------------------------------------------------*/
emilmont 6:350b53afb889 56
emilmont 6:350b53afb889 57 static volatile BIT os_lock;
emilmont 6:350b53afb889 58 static volatile BIT os_psh_flag;
emilmont 6:350b53afb889 59 static U8 pend_flags;
emilmont 6:350b53afb889 60
emilmont 6:350b53afb889 61 /*----------------------------------------------------------------------------
emilmont 6:350b53afb889 62 * Global Functions
emilmont 6:350b53afb889 63 *---------------------------------------------------------------------------*/
emilmont 6:350b53afb889 64
emilmont 6:350b53afb889 65 #if defined (__CC_ARM)
emilmont 6:350b53afb889 66 __asm void $$RTX$$version (void) {
emilmont 6:350b53afb889 67 /* Export a version number symbol for a version control. */
emilmont 6:350b53afb889 68
emilmont 6:350b53afb889 69 EXPORT __RL_RTX_VER
emilmont 6:350b53afb889 70
emilmont 6:350b53afb889 71 __RL_RTX_VER EQU 0x450
emilmont 6:350b53afb889 72 }
emilmont 6:350b53afb889 73 #endif
emilmont 6:350b53afb889 74
emilmont 6:350b53afb889 75
emilmont 6:350b53afb889 76 /*--------------------------- rt_suspend ------------------------------------*/
emilmont 6:350b53afb889 77 U32 rt_suspend (void) {
emilmont 6:350b53afb889 78 /* Suspend OS scheduler */
emilmont 6:350b53afb889 79 U32 delta = 0xFFFF;
emilmont 6:350b53afb889 80
emilmont 6:350b53afb889 81 rt_tsk_lock();
emilmont 6:350b53afb889 82
emilmont 6:350b53afb889 83 if (os_dly.p_dlnk) {
emilmont 6:350b53afb889 84 delta = os_dly.delta_time;
emilmont 6:350b53afb889 85 }
emilmont 6:350b53afb889 86 #ifndef __CMSIS_RTOS
emilmont 6:350b53afb889 87 if (os_tmr.next) {
emilmont 6:350b53afb889 88 if (os_tmr.tcnt < delta) delta = os_tmr.tcnt;
emilmont 6:350b53afb889 89 }
emilmont 6:350b53afb889 90 #endif
emilmont 6:350b53afb889 91
emilmont 6:350b53afb889 92 return (delta);
emilmont 6:350b53afb889 93 }
emilmont 6:350b53afb889 94
emilmont 6:350b53afb889 95
emilmont 6:350b53afb889 96 /*--------------------------- rt_resume -------------------------------------*/
emilmont 6:350b53afb889 97 void rt_resume (U32 sleep_time) {
emilmont 6:350b53afb889 98 /* Resume OS scheduler after suspend */
emilmont 6:350b53afb889 99 P_TCB next;
emilmont 6:350b53afb889 100 U32 delta;
emilmont 6:350b53afb889 101
emilmont 6:350b53afb889 102 os_tsk.run->state = READY;
emilmont 6:350b53afb889 103 rt_put_rdy_first (os_tsk.run);
emilmont 6:350b53afb889 104
emilmont 6:350b53afb889 105 os_robin.task = NULL;
emilmont 6:350b53afb889 106
emilmont 6:350b53afb889 107 /* Update delays. */
emilmont 6:350b53afb889 108 if (os_dly.p_dlnk) {
emilmont 6:350b53afb889 109 delta = sleep_time;
emilmont 6:350b53afb889 110 if (delta >= os_dly.delta_time) {
emilmont 6:350b53afb889 111 delta -= os_dly.delta_time;
emilmont 6:350b53afb889 112 os_time += os_dly.delta_time;
emilmont 6:350b53afb889 113 os_dly.delta_time = 1;
emilmont 6:350b53afb889 114 while (os_dly.p_dlnk) {
emilmont 6:350b53afb889 115 rt_dec_dly();
emilmont 6:350b53afb889 116 if (delta == 0) break;
emilmont 6:350b53afb889 117 delta--;
emilmont 6:350b53afb889 118 os_time++;
emilmont 6:350b53afb889 119 }
emilmont 6:350b53afb889 120 } else {
emilmont 6:350b53afb889 121 os_time += delta;
emilmont 6:350b53afb889 122 os_dly.delta_time -= delta;
emilmont 6:350b53afb889 123 }
emilmont 6:350b53afb889 124 } else {
emilmont 6:350b53afb889 125 os_time += sleep_time;
emilmont 6:350b53afb889 126 }
emilmont 6:350b53afb889 127
emilmont 6:350b53afb889 128 #ifndef __CMSIS_RTOS
emilmont 6:350b53afb889 129 /* Check the user timers. */
emilmont 6:350b53afb889 130 if (os_tmr.next) {
emilmont 6:350b53afb889 131 delta = sleep_time;
emilmont 6:350b53afb889 132 if (delta >= os_tmr.tcnt) {
emilmont 6:350b53afb889 133 delta -= os_tmr.tcnt;
emilmont 6:350b53afb889 134 os_tmr.tcnt = 1;
emilmont 6:350b53afb889 135 while (os_tmr.next) {
emilmont 6:350b53afb889 136 rt_tmr_tick();
emilmont 6:350b53afb889 137 if (delta == 0) break;
emilmont 6:350b53afb889 138 delta--;
emilmont 6:350b53afb889 139 }
emilmont 6:350b53afb889 140 } else {
emilmont 6:350b53afb889 141 os_tmr.tcnt -= delta;
emilmont 6:350b53afb889 142 }
emilmont 6:350b53afb889 143 }
emilmont 6:350b53afb889 144 #endif
emilmont 6:350b53afb889 145
emilmont 6:350b53afb889 146 /* Switch back to highest ready task */
emilmont 6:350b53afb889 147 next = rt_get_first (&os_rdy);
emilmont 6:350b53afb889 148 rt_switch_req (next);
emilmont 6:350b53afb889 149
emilmont 6:350b53afb889 150 rt_tsk_unlock();
emilmont 6:350b53afb889 151 }
emilmont 6:350b53afb889 152
emilmont 6:350b53afb889 153
emilmont 6:350b53afb889 154 /*--------------------------- rt_tsk_lock -----------------------------------*/
emilmont 6:350b53afb889 155
emilmont 6:350b53afb889 156 void rt_tsk_lock (void) {
emilmont 6:350b53afb889 157 /* Prevent task switching by locking out scheduler */
emilmont 6:350b53afb889 158 if (os_tick_irqn < 0) {
emilmont 6:350b53afb889 159 OS_LOCK();
emilmont 6:350b53afb889 160 os_lock = __TRUE;
emilmont 6:350b53afb889 161 OS_UNPEND (&pend_flags);
emilmont 6:350b53afb889 162 } else {
emilmont 6:350b53afb889 163 OS_X_LOCK(os_tick_irqn);
emilmont 6:350b53afb889 164 os_lock = __TRUE;
emilmont 6:350b53afb889 165 OS_X_UNPEND (&pend_flags);
emilmont 6:350b53afb889 166 }
emilmont 6:350b53afb889 167 }
emilmont 6:350b53afb889 168
emilmont 6:350b53afb889 169
emilmont 6:350b53afb889 170 /*--------------------------- rt_tsk_unlock ---------------------------------*/
emilmont 6:350b53afb889 171
emilmont 6:350b53afb889 172 void rt_tsk_unlock (void) {
emilmont 6:350b53afb889 173 /* Unlock scheduler and re-enable task switching */
emilmont 6:350b53afb889 174 if (os_tick_irqn < 0) {
emilmont 6:350b53afb889 175 OS_UNLOCK();
emilmont 6:350b53afb889 176 os_lock = __FALSE;
emilmont 6:350b53afb889 177 OS_PEND (pend_flags, os_psh_flag);
emilmont 6:350b53afb889 178 os_psh_flag = __FALSE;
emilmont 6:350b53afb889 179 } else {
emilmont 6:350b53afb889 180 OS_X_UNLOCK(os_tick_irqn);
emilmont 6:350b53afb889 181 os_lock = __FALSE;
emilmont 6:350b53afb889 182 OS_X_PEND (pend_flags, os_psh_flag);
emilmont 6:350b53afb889 183 os_psh_flag = __FALSE;
emilmont 6:350b53afb889 184 }
emilmont 6:350b53afb889 185 }
emilmont 6:350b53afb889 186
emilmont 6:350b53afb889 187
emilmont 6:350b53afb889 188 /*--------------------------- rt_psh_req ------------------------------------*/
emilmont 6:350b53afb889 189
emilmont 6:350b53afb889 190 void rt_psh_req (void) {
emilmont 6:350b53afb889 191 /* Initiate a post service handling request if required. */
emilmont 6:350b53afb889 192 if (os_lock == __FALSE) {
emilmont 6:350b53afb889 193 OS_PEND_IRQ ();
emilmont 6:350b53afb889 194 }
emilmont 6:350b53afb889 195 else {
emilmont 6:350b53afb889 196 os_psh_flag = __TRUE;
emilmont 6:350b53afb889 197 }
emilmont 6:350b53afb889 198 }
emilmont 6:350b53afb889 199
emilmont 6:350b53afb889 200
emilmont 6:350b53afb889 201 /*--------------------------- rt_pop_req ------------------------------------*/
emilmont 6:350b53afb889 202
emilmont 6:350b53afb889 203 void rt_pop_req (void) {
emilmont 6:350b53afb889 204 /* Process an ISR post service requests. */
emilmont 6:350b53afb889 205 struct OS_XCB *p_CB;
emilmont 6:350b53afb889 206 P_TCB next;
emilmont 6:350b53afb889 207 U32 idx;
emilmont 6:350b53afb889 208
emilmont 6:350b53afb889 209 os_tsk.run->state = READY;
emilmont 6:350b53afb889 210 rt_put_rdy_first (os_tsk.run);
emilmont 6:350b53afb889 211
emilmont 6:350b53afb889 212 idx = os_psq->last;
emilmont 6:350b53afb889 213 while (os_psq->count) {
emilmont 6:350b53afb889 214 p_CB = os_psq->q[idx].id;
emilmont 6:350b53afb889 215 if (p_CB->cb_type == TCB) {
emilmont 6:350b53afb889 216 /* Is of TCB type */
emilmont 6:350b53afb889 217 rt_evt_psh ((P_TCB)p_CB, (U16)os_psq->q[idx].arg);
emilmont 6:350b53afb889 218 }
emilmont 6:350b53afb889 219 else if (p_CB->cb_type == MCB) {
emilmont 6:350b53afb889 220 /* Is of MCB type */
emilmont 6:350b53afb889 221 rt_mbx_psh ((P_MCB)p_CB, (void *)os_psq->q[idx].arg);
emilmont 6:350b53afb889 222 }
emilmont 6:350b53afb889 223 else {
emilmont 6:350b53afb889 224 /* Must be of SCB type */
emilmont 6:350b53afb889 225 rt_sem_psh ((P_SCB)p_CB);
emilmont 6:350b53afb889 226 }
emilmont 6:350b53afb889 227 if (++idx == os_psq->size) idx = 0;
emilmont 6:350b53afb889 228 rt_dec (&os_psq->count);
emilmont 6:350b53afb889 229 }
emilmont 6:350b53afb889 230 os_psq->last = idx;
emilmont 6:350b53afb889 231
emilmont 6:350b53afb889 232 next = rt_get_first (&os_rdy);
emilmont 6:350b53afb889 233 rt_switch_req (next);
emilmont 6:350b53afb889 234 }
emilmont 6:350b53afb889 235
emilmont 6:350b53afb889 236
emilmont 6:350b53afb889 237 /*--------------------------- os_tick_init ----------------------------------*/
emilmont 6:350b53afb889 238
emilmont 6:350b53afb889 239 __weak int os_tick_init (void) {
emilmont 6:350b53afb889 240 /* Initialize SysTick timer as system tick timer. */
emilmont 6:350b53afb889 241 rt_systick_init ();
emilmont 6:350b53afb889 242 return (-1); /* Return IRQ number of SysTick timer */
emilmont 6:350b53afb889 243 }
emilmont 6:350b53afb889 244
emilmont 6:350b53afb889 245
emilmont 6:350b53afb889 246 /*--------------------------- os_tick_irqack --------------------------------*/
emilmont 6:350b53afb889 247
emilmont 6:350b53afb889 248 __weak void os_tick_irqack (void) {
emilmont 6:350b53afb889 249 /* Acknowledge timer interrupt. */
emilmont 6:350b53afb889 250 }
emilmont 6:350b53afb889 251
emilmont 6:350b53afb889 252
emilmont 6:350b53afb889 253 /*--------------------------- rt_systick ------------------------------------*/
emilmont 6:350b53afb889 254
emilmont 6:350b53afb889 255 extern void sysTimerTick(void);
emilmont 6:350b53afb889 256
emilmont 6:350b53afb889 257 void rt_systick (void) {
emilmont 6:350b53afb889 258 /* Check for system clock update, suspend running task. */
emilmont 6:350b53afb889 259 P_TCB next;
emilmont 6:350b53afb889 260
emilmont 6:350b53afb889 261 os_tsk.run->state = READY;
emilmont 6:350b53afb889 262 rt_put_rdy_first (os_tsk.run);
emilmont 6:350b53afb889 263
emilmont 6:350b53afb889 264 /* Check Round Robin timeout. */
emilmont 6:350b53afb889 265 rt_chk_robin ();
emilmont 6:350b53afb889 266
emilmont 6:350b53afb889 267 /* Update delays. */
emilmont 6:350b53afb889 268 os_time++;
emilmont 6:350b53afb889 269 rt_dec_dly ();
emilmont 6:350b53afb889 270
emilmont 6:350b53afb889 271 /* Check the user timers. */
emilmont 6:350b53afb889 272 #ifdef __CMSIS_RTOS
emilmont 6:350b53afb889 273 sysTimerTick();
emilmont 6:350b53afb889 274 #else
emilmont 6:350b53afb889 275 rt_tmr_tick ();
emilmont 6:350b53afb889 276 #endif
emilmont 6:350b53afb889 277
emilmont 6:350b53afb889 278 /* Switch back to highest ready task */
emilmont 6:350b53afb889 279 next = rt_get_first (&os_rdy);
emilmont 6:350b53afb889 280 rt_switch_req (next);
emilmont 6:350b53afb889 281 }
emilmont 6:350b53afb889 282
emilmont 6:350b53afb889 283 /*--------------------------- rt_stk_check ----------------------------------*/
emilmont 6:350b53afb889 284 __weak void rt_stk_check (void) {
emilmont 6:350b53afb889 285 /* Check for stack overflow. */
emilmont 6:350b53afb889 286 if (os_tsk.run->task_id == 0x01) {
emilmont 6:350b53afb889 287 // TODO: For the main thread the check should be done against the main heap pointer
emilmont 6:350b53afb889 288 } else {
emilmont 6:350b53afb889 289 if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) ||
emilmont 6:350b53afb889 290 (os_tsk.run->stack[0] != MAGIC_WORD)) {
emilmont 6:350b53afb889 291 os_error (OS_ERR_STK_OVF);
emilmont 6:350b53afb889 292 }
emilmont 6:350b53afb889 293 }
emilmont 6:350b53afb889 294 }
emilmont 6:350b53afb889 295
emilmont 6:350b53afb889 296 /*----------------------------------------------------------------------------
emilmont 6:350b53afb889 297 * end of file
emilmont 6:350b53afb889 298 *---------------------------------------------------------------------------*/
emilmont 6:350b53afb889 299