Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-rtos by
rt_System.c
00001 /*---------------------------------------------------------------------------- 00002 * RL-ARM - RTX 00003 *---------------------------------------------------------------------------- 00004 * Name: RT_SYSTEM.C 00005 * Purpose: System Task Manager 00006 * Rev.: V4.60 00007 *---------------------------------------------------------------------------- 00008 * 00009 * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH 00010 * All rights reserved. 00011 * Redistribution and use in source and binary forms, with or without 00012 * modification, are permitted provided that the following conditions are met: 00013 * - Redistributions of source code must retain the above copyright 00014 * notice, this list of conditions and the following disclaimer. 00015 * - Redistributions in binary form must reproduce the above copyright 00016 * notice, this list of conditions and the following disclaimer in the 00017 * documentation and/or other materials provided with the distribution. 00018 * - Neither the name of ARM nor the names of its contributors may be used 00019 * to endorse or promote products derived from this software without 00020 * specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00023 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00024 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00025 * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE 00026 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00027 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00028 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00029 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00030 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00031 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 * POSSIBILITY OF SUCH DAMAGE. 00033 *---------------------------------------------------------------------------*/ 00034 00035 #include "rt_TypeDef.h" 00036 #include "RTX_Conf.h" 00037 #include "rt_Task.h" 00038 #include "rt_System.h" 00039 #include "rt_Event.h" 00040 #include "rt_List.h" 00041 #include "rt_Mailbox.h" 00042 #include "rt_Semaphore.h" 00043 #include "rt_Time.h" 00044 #include "rt_Robin.h" 00045 #include "rt_HAL_CM.h" 00046 00047 /*---------------------------------------------------------------------------- 00048 * Global Variables 00049 *---------------------------------------------------------------------------*/ 00050 00051 int os_tick_irqn; 00052 00053 /*---------------------------------------------------------------------------- 00054 * Local Variables 00055 *---------------------------------------------------------------------------*/ 00056 00057 static volatile BIT os_lock; 00058 static volatile BIT os_psh_flag; 00059 static U8 pend_flags; 00060 00061 /*---------------------------------------------------------------------------- 00062 * Global Functions 00063 *---------------------------------------------------------------------------*/ 00064 00065 #if defined (__CC_ARM) 00066 __asm void $$RTX$$version (void) { 00067 /* Export a version number symbol for a version control. */ 00068 00069 EXPORT __RL_RTX_VER 00070 00071 __RL_RTX_VER EQU 0x450 00072 } 00073 #endif 00074 00075 00076 /*--------------------------- rt_suspend ------------------------------------*/ 00077 U32 rt_suspend (void) { 00078 /* Suspend OS scheduler */ 00079 U32 delta = 0xFFFF; 00080 00081 rt_tsk_lock(); 00082 00083 if (os_dly.p_dlnk) { 00084 delta = os_dly.delta_time; 00085 } 00086 #ifndef __CMSIS_RTOS 00087 if (os_tmr.next) { 00088 if (os_tmr.tcnt < delta) delta = os_tmr.tcnt; 00089 } 00090 #endif 00091 00092 return (delta); 00093 } 00094 00095 00096 /*--------------------------- rt_resume -------------------------------------*/ 00097 void rt_resume (U32 sleep_time) { 00098 /* Resume OS scheduler after suspend */ 00099 P_TCB next; 00100 U32 delta; 00101 00102 os_tsk.run->state = READY; 00103 rt_put_rdy_first (os_tsk.run); 00104 00105 os_robin.task = NULL; 00106 00107 /* Update delays. */ 00108 if (os_dly.p_dlnk) { 00109 delta = sleep_time; 00110 if (delta >= os_dly.delta_time) { 00111 delta -= os_dly.delta_time; 00112 os_time += os_dly.delta_time; 00113 os_dly.delta_time = 1; 00114 while (os_dly.p_dlnk) { 00115 rt_dec_dly(); 00116 if (delta == 0) break; 00117 delta--; 00118 os_time++; 00119 } 00120 } else { 00121 os_time += delta; 00122 os_dly.delta_time -= delta; 00123 } 00124 } else { 00125 os_time += sleep_time; 00126 } 00127 00128 #ifndef __CMSIS_RTOS 00129 /* Check the user timers. */ 00130 if (os_tmr.next) { 00131 delta = sleep_time; 00132 if (delta >= os_tmr.tcnt) { 00133 delta -= os_tmr.tcnt; 00134 os_tmr.tcnt = 1; 00135 while (os_tmr.next) { 00136 rt_tmr_tick(); 00137 if (delta == 0) break; 00138 delta--; 00139 } 00140 } else { 00141 os_tmr.tcnt -= delta; 00142 } 00143 } 00144 #endif 00145 00146 /* Switch back to highest ready task */ 00147 next = rt_get_first (&os_rdy); 00148 rt_switch_req (next); 00149 00150 rt_tsk_unlock(); 00151 } 00152 00153 00154 /*--------------------------- rt_tsk_lock -----------------------------------*/ 00155 00156 void rt_tsk_lock (void) { 00157 /* Prevent task switching by locking out scheduler */ 00158 if (os_tick_irqn < 0) { 00159 OS_LOCK(); 00160 os_lock = __TRUE; 00161 OS_UNPEND (&pend_flags); 00162 } else { 00163 OS_X_LOCK(os_tick_irqn); 00164 os_lock = __TRUE; 00165 OS_X_UNPEND (&pend_flags); 00166 } 00167 } 00168 00169 00170 /*--------------------------- rt_tsk_unlock ---------------------------------*/ 00171 00172 void rt_tsk_unlock (void) { 00173 /* Unlock scheduler and re-enable task switching */ 00174 if (os_tick_irqn < 0) { 00175 OS_UNLOCK(); 00176 os_lock = __FALSE; 00177 OS_PEND (pend_flags, os_psh_flag); 00178 os_psh_flag = __FALSE; 00179 } else { 00180 OS_X_UNLOCK(os_tick_irqn); 00181 os_lock = __FALSE; 00182 OS_X_PEND (pend_flags, os_psh_flag); 00183 os_psh_flag = __FALSE; 00184 } 00185 } 00186 00187 00188 /*--------------------------- rt_psh_req ------------------------------------*/ 00189 00190 void rt_psh_req (void) { 00191 /* Initiate a post service handling request if required. */ 00192 if (os_lock == __FALSE) { 00193 OS_PEND_IRQ (); 00194 } 00195 else { 00196 os_psh_flag = __TRUE; 00197 } 00198 } 00199 00200 00201 /*--------------------------- rt_pop_req ------------------------------------*/ 00202 00203 void rt_pop_req (void) { 00204 /* Process an ISR post service requests. */ 00205 struct OS_XCB *p_CB; 00206 P_TCB next; 00207 U32 idx; 00208 00209 os_tsk.run->state = READY; 00210 rt_put_rdy_first (os_tsk.run); 00211 00212 idx = os_psq->last; 00213 while (os_psq->count) { 00214 p_CB = os_psq->q[idx].id; 00215 if (p_CB->cb_type == TCB) { 00216 /* Is of TCB type */ 00217 rt_evt_psh ((P_TCB)p_CB, (U16)os_psq->q[idx].arg); 00218 } 00219 else if (p_CB->cb_type == MCB) { 00220 /* Is of MCB type */ 00221 rt_mbx_psh ((P_MCB)p_CB, (void *)os_psq->q[idx].arg); 00222 } 00223 else { 00224 /* Must be of SCB type */ 00225 rt_sem_psh ((P_SCB)p_CB); 00226 } 00227 if (++idx == os_psq->size) idx = 0; 00228 rt_dec (&os_psq->count); 00229 } 00230 os_psq->last = idx; 00231 00232 next = rt_get_first (&os_rdy); 00233 rt_switch_req (next); 00234 } 00235 00236 00237 /*--------------------------- os_tick_init ----------------------------------*/ 00238 00239 __weak int os_tick_init (void) { 00240 /* Initialize SysTick timer as system tick timer. */ 00241 rt_systick_init (); 00242 return (-1); /* Return IRQ number of SysTick timer */ 00243 } 00244 00245 00246 /*--------------------------- os_tick_irqack --------------------------------*/ 00247 00248 __weak void os_tick_irqack (void) { 00249 /* Acknowledge timer interrupt. */ 00250 } 00251 00252 00253 /*--------------------------- rt_systick ------------------------------------*/ 00254 00255 extern void sysTimerTick(void); 00256 00257 void rt_systick (void) { 00258 /* Check for system clock update, suspend running task. */ 00259 P_TCB next; 00260 00261 os_tsk.run->state = READY; 00262 rt_put_rdy_first (os_tsk.run); 00263 00264 /* Check Round Robin timeout. */ 00265 rt_chk_robin (); 00266 00267 /* Update delays. */ 00268 os_time++; 00269 rt_dec_dly (); 00270 00271 /* Check the user timers. */ 00272 #ifdef __CMSIS_RTOS 00273 sysTimerTick(); 00274 #else 00275 rt_tmr_tick (); 00276 #endif 00277 00278 /* Switch back to highest ready task */ 00279 next = rt_get_first (&os_rdy); 00280 rt_switch_req (next); 00281 } 00282 00283 /*--------------------------- rt_stk_check ----------------------------------*/ 00284 __weak void rt_stk_check (void) { 00285 /* Check for stack overflow. */ 00286 if (os_tsk.run->task_id == 0x01) { 00287 // TODO: For the main thread the check should be done against the main heap pointer 00288 } else { 00289 if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) || 00290 (os_tsk.run->stack[0] != MAGIC_WORD)) { 00291 os_error (OS_ERR_STK_OVF); 00292 } 00293 } 00294 } 00295 00296 /*---------------------------------------------------------------------------- 00297 * end of file 00298 *---------------------------------------------------------------------------*/ 00299
Generated on Wed Jul 13 2022 18:32:39 by
