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.
rt_System.c
00001 /** 00002 * @file rt_System.c 00003 * @brief 00004 * 00005 * DAPLink Interface Firmware 00006 * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved 00007 * SPDX-License-Identifier: Apache-2.0 00008 * 00009 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00010 * not use this file except in compliance with the License. 00011 * You may obtain a copy of the License at 00012 * 00013 * http://www.apache.org/licenses/LICENSE-2.0 00014 * 00015 * Unless required by applicable law or agreed to in writing, software 00016 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00017 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00018 * See the License for the specific language governing permissions and 00019 * limitations under the License. 00020 */ 00021 00022 #include "rt_TypeDef.h" 00023 #include "RTX_Config.h" 00024 #include "rt_Task.h" 00025 #include "rt_System.h" 00026 #include "rt_Event.h" 00027 #include "rt_List.h" 00028 #include "rt_Mailbox.h" 00029 #include "rt_Semaphore.h" 00030 #include "rt_Time.h" 00031 #include "rt_Timer.h" 00032 #include "rt_Robin.h" 00033 #include "rt_HAL_CM.h" 00034 00035 /*---------------------------------------------------------------------------- 00036 * Global Variables 00037 *---------------------------------------------------------------------------*/ 00038 00039 int os_tick_irqn; 00040 00041 /*---------------------------------------------------------------------------- 00042 * Local Variables 00043 *---------------------------------------------------------------------------*/ 00044 00045 static volatile BIT os_lock; 00046 static volatile BIT os_psh_flag; 00047 static U8 pend_flags; 00048 00049 /*---------------------------------------------------------------------------- 00050 * Global Functions 00051 *---------------------------------------------------------------------------*/ 00052 00053 __asm void $$RTX$$version (void) { 00054 /* Export a version number symbol for a version control. */ 00055 00056 EXPORT __RL_RTX_VER 00057 00058 __RL_RTX_VER EQU 0x470 00059 } 00060 00061 00062 /*--------------------------- rt_suspend ------------------------------------*/ 00063 00064 U32 rt_suspend (void) { 00065 /* Suspend OS scheduler */ 00066 U32 delta = 0xFFFF; 00067 00068 rt_tsk_lock(); 00069 00070 if (os_dly.p_dlnk) { 00071 delta = os_dly.delta_time; 00072 } 00073 if (os_tmr.next) { 00074 if (os_tmr.tcnt < delta) delta = os_tmr.tcnt; 00075 } 00076 00077 return (delta); 00078 } 00079 00080 00081 /*--------------------------- rt_resume -------------------------------------*/ 00082 00083 void rt_resume (U32 sleep_time) { 00084 /* Resume OS scheduler after suspend */ 00085 P_TCB next; 00086 U32 delta; 00087 00088 os_tsk.run->state = READY; 00089 rt_put_rdy_first (os_tsk.run); 00090 00091 os_robin.task = NULL; 00092 00093 /* Update delays. */ 00094 if (os_dly.p_dlnk) { 00095 delta = sleep_time; 00096 if (delta >= os_dly.delta_time) { 00097 delta -= os_dly.delta_time; 00098 os_time += os_dly.delta_time; 00099 os_dly.delta_time = 1; 00100 while (os_dly.p_dlnk) { 00101 rt_dec_dly(); 00102 if (delta == 0) break; 00103 delta--; 00104 os_time++; 00105 } 00106 } else { 00107 os_time += delta; 00108 os_dly.delta_time -= delta; 00109 } 00110 } else { 00111 os_time += sleep_time; 00112 } 00113 00114 /* Check the user timers. */ 00115 if (os_tmr.next) { 00116 delta = sleep_time; 00117 if (delta >= os_tmr.tcnt) { 00118 delta -= os_tmr.tcnt; 00119 os_tmr.tcnt = 1; 00120 while (os_tmr.next) { 00121 rt_tmr_tick(); 00122 if (delta == 0) break; 00123 delta--; 00124 } 00125 } else { 00126 os_tmr.tcnt -= delta; 00127 } 00128 } 00129 00130 /* Switch back to highest ready task */ 00131 next = rt_get_first (&os_rdy); 00132 rt_switch_req (next); 00133 00134 rt_tsk_unlock(); 00135 } 00136 00137 00138 /*--------------------------- rt_tsk_lock -----------------------------------*/ 00139 00140 void rt_tsk_lock (void) { 00141 /* Prevent task switching by locking out scheduler */ 00142 if (os_tick_irqn < 0) { 00143 OS_LOCK(); 00144 os_lock = __TRUE; 00145 OS_UNPEND (&pend_flags); 00146 } else { 00147 OS_X_LOCK(os_tick_irqn); 00148 os_lock = __TRUE; 00149 OS_X_UNPEND (&pend_flags); 00150 } 00151 } 00152 00153 00154 /*--------------------------- rt_tsk_unlock ---------------------------------*/ 00155 00156 void rt_tsk_unlock (void) { 00157 /* Unlock scheduler and re-enable task switching */ 00158 if (os_tick_irqn < 0) { 00159 OS_UNLOCK(); 00160 os_lock = __FALSE; 00161 OS_PEND (pend_flags, os_psh_flag); 00162 os_psh_flag = __FALSE; 00163 } else { 00164 OS_X_UNLOCK(os_tick_irqn); 00165 os_lock = __FALSE; 00166 OS_X_PEND (pend_flags, os_psh_flag); 00167 os_psh_flag = __FALSE; 00168 } 00169 } 00170 00171 00172 /*--------------------------- rt_psh_req ------------------------------------*/ 00173 00174 void rt_psh_req (void) { 00175 /* Initiate a post service handling request if required. */ 00176 if (os_lock == __FALSE) { 00177 OS_PEND_IRQ (); 00178 } 00179 else { 00180 os_psh_flag = __TRUE; 00181 } 00182 } 00183 00184 00185 /*--------------------------- rt_pop_req ------------------------------------*/ 00186 00187 void rt_pop_req (void) { 00188 /* Process an ISR post service requests. */ 00189 struct OS_XCB *p_CB; 00190 P_TCB next; 00191 U32 idx; 00192 00193 os_tsk.run->state = READY; 00194 rt_put_rdy_first (os_tsk.run); 00195 00196 idx = os_psq->last; 00197 while (os_psq->count) { 00198 p_CB = os_psq->q[idx].id; 00199 if (p_CB->cb_type == TCB) { 00200 /* Is of TCB type */ 00201 rt_evt_psh ((P_TCB)p_CB, (U16)os_psq->q[idx].arg); 00202 } 00203 else if (p_CB->cb_type == MCB) { 00204 /* Is of MCB type */ 00205 rt_mbx_psh ((P_MCB)p_CB, (void *)os_psq->q[idx].arg); 00206 } 00207 else { 00208 /* Must be of SCB type */ 00209 rt_sem_psh ((P_SCB)p_CB); 00210 } 00211 if (++idx == os_psq->size) idx = 0; 00212 rt_dec (&os_psq->count); 00213 } 00214 os_psq->last = idx; 00215 00216 next = rt_get_first (&os_rdy); 00217 rt_switch_req (next); 00218 } 00219 00220 00221 /*--------------------------- os_tick_init ----------------------------------*/ 00222 00223 __weak int os_tick_init (void) { 00224 /* Initialize SysTick timer as system tick timer. */ 00225 rt_systick_init (); 00226 return (-1); /* Return IRQ number of SysTick timer */ 00227 } 00228 00229 00230 /*--------------------------- os_tick_irqack --------------------------------*/ 00231 00232 __weak void os_tick_irqack (void) { 00233 /* Acknowledge timer interrupt. */ 00234 } 00235 00236 00237 /*--------------------------- rt_systick ------------------------------------*/ 00238 00239 void rt_systick (void) { 00240 /* Check for system clock update, suspend running task. */ 00241 P_TCB next; 00242 00243 os_tsk.run->state = READY; 00244 rt_put_rdy_first (os_tsk.run); 00245 00246 /* Check Round Robin timeout. */ 00247 rt_chk_robin (); 00248 00249 /* Update delays. */ 00250 os_time++; 00251 rt_dec_dly (); 00252 00253 /* Check the user timers. */ 00254 rt_tmr_tick (); 00255 00256 /* Switch back to highest ready task */ 00257 next = rt_get_first (&os_rdy); 00258 rt_switch_req (next); 00259 } 00260 00261 /*--------------------------- rt_stk_check ----------------------------------*/ 00262 00263 __weak void rt_stk_check (void) { 00264 /* Check for stack overflow. */ 00265 if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) || 00266 (os_tsk.run->stack[0] != MAGIC_WORD)) { 00267 os_error (OS_ERR_STK_OVF); 00268 } 00269 } 00270 00271 /*---------------------------------------------------------------------------- 00272 * end of file 00273 *---------------------------------------------------------------------------*/ 00274
Generated on Tue Jul 12 2022 15:37:22 by
1.7.2