Official mbed Real Time Operating System based on the RTX implementation of the CMSIS-RTOS API open standard. Patched to work with NUCLEO L152 board
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 Thu Jul 14 2022 02:41:33 by 1.7.2