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_List.c
00001 /** 00002 * @file rt_List.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_System.h" 00025 #include "rt_List.h" 00026 #include "rt_Task.h" 00027 #include "rt_Time.h" 00028 #include "rt_HAL_CM.h" 00029 00030 /*---------------------------------------------------------------------------- 00031 * Global Variables 00032 *---------------------------------------------------------------------------*/ 00033 00034 /* List head of chained ready tasks */ 00035 struct OS_XCB os_rdy; 00036 /* List head of chained delay tasks */ 00037 struct OS_XCB os_dly; 00038 00039 00040 /*---------------------------------------------------------------------------- 00041 * Functions 00042 *---------------------------------------------------------------------------*/ 00043 00044 00045 /*--------------------------- rt_put_prio -----------------------------------*/ 00046 00047 void rt_put_prio (P_XCB p_CB, P_TCB p_task) { 00048 /* Put task identified with "p_task" into list ordered by priority. */ 00049 /* "p_CB" points to head of list; list has always an element at end with */ 00050 /* a priority less than "p_task->prio". */ 00051 P_TCB p_CB2; 00052 U32 prio; 00053 BOOL sem_mbx = __FALSE; 00054 00055 if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { 00056 sem_mbx = __TRUE; 00057 } 00058 prio = p_task->prio; 00059 p_CB2 = p_CB->p_lnk; 00060 /* Search for an entry in the list */ 00061 while (p_CB2 != NULL && prio <= p_CB2->prio) { 00062 p_CB = (P_XCB)p_CB2; 00063 p_CB2 = p_CB2->p_lnk; 00064 } 00065 /* Entry found, insert the task into the list */ 00066 p_task->p_lnk = p_CB2; 00067 p_CB->p_lnk = p_task; 00068 if (sem_mbx) { 00069 if (p_CB2 != NULL) { 00070 p_CB2->p_rlnk = p_task; 00071 } 00072 p_task->p_rlnk = (P_TCB)p_CB; 00073 } 00074 else { 00075 p_task->p_rlnk = NULL; 00076 } 00077 } 00078 00079 00080 /*--------------------------- rt_get_first ----------------------------------*/ 00081 00082 P_TCB rt_get_first (P_XCB p_CB) { 00083 /* Get task at head of list: it is the task with highest priority. */ 00084 /* "p_CB" points to head of list. */ 00085 P_TCB p_first; 00086 00087 p_first = p_CB->p_lnk; 00088 p_CB->p_lnk = p_first->p_lnk; 00089 if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { 00090 if (p_first->p_lnk != NULL) { 00091 p_first->p_lnk->p_rlnk = (P_TCB)p_CB; 00092 p_first->p_lnk = NULL; 00093 } 00094 p_first->p_rlnk = NULL; 00095 } 00096 else { 00097 p_first->p_lnk = NULL; 00098 } 00099 return (p_first); 00100 } 00101 00102 00103 /*--------------------------- rt_put_rdy_first ------------------------------*/ 00104 00105 void rt_put_rdy_first (P_TCB p_task) { 00106 /* Put task identified with "p_task" at the head of the ready list. The */ 00107 /* task must have at least a priority equal to highest priority in list. */ 00108 p_task->p_lnk = os_rdy.p_lnk; 00109 p_task->p_rlnk = NULL; 00110 os_rdy.p_lnk = p_task; 00111 } 00112 00113 00114 /*--------------------------- rt_get_same_rdy_prio --------------------------*/ 00115 00116 P_TCB rt_get_same_rdy_prio (void) { 00117 /* Remove a task of same priority from ready list if any exists. Other- */ 00118 /* wise return NULL. */ 00119 P_TCB p_first; 00120 00121 p_first = os_rdy.p_lnk; 00122 if (p_first->prio == os_tsk.run->prio) { 00123 os_rdy.p_lnk = os_rdy.p_lnk->p_lnk; 00124 return (p_first); 00125 } 00126 return (NULL); 00127 } 00128 00129 00130 /*--------------------------- rt_resort_prio --------------------------------*/ 00131 00132 void rt_resort_prio (P_TCB p_task) { 00133 /* Re-sort ordered lists after the priority of 'p_task' has changed. */ 00134 P_TCB p_CB; 00135 00136 if (p_task->p_rlnk == NULL) { 00137 if (p_task->state == READY) { 00138 /* Task is chained into READY list. */ 00139 p_CB = (P_TCB)&os_rdy; 00140 goto res; 00141 } 00142 } 00143 else { 00144 p_CB = p_task->p_rlnk; 00145 while (p_CB->cb_type == TCB) { 00146 /* Find a header of this task chain list. */ 00147 p_CB = p_CB->p_rlnk; 00148 } 00149 res:rt_rmv_list (p_task); 00150 rt_put_prio ((P_XCB)p_CB, p_task); 00151 } 00152 } 00153 00154 00155 /*--------------------------- rt_put_dly ------------------------------------*/ 00156 00157 void rt_put_dly (P_TCB p_task, U16 delay) { 00158 /* Put a task identified with "p_task" into chained delay wait list using */ 00159 /* a delay value of "delay". */ 00160 P_TCB p; 00161 U32 delta,idelay = delay; 00162 00163 p = (P_TCB)&os_dly; 00164 if (p->p_dlnk == NULL) { 00165 /* Delay list empty */ 00166 delta = 0; 00167 goto last; 00168 } 00169 delta = os_dly.delta_time; 00170 while (delta < idelay) { 00171 if (p->p_dlnk == NULL) { 00172 /* End of list found */ 00173 last: p_task->p_dlnk = NULL; 00174 p->p_dlnk = p_task; 00175 p_task->p_blnk = p; 00176 p->delta_time = (U16)(idelay - delta); 00177 p_task->delta_time = 0; 00178 return; 00179 } 00180 p = p->p_dlnk; 00181 delta += p->delta_time; 00182 } 00183 /* Right place found */ 00184 p_task->p_dlnk = p->p_dlnk; 00185 p->p_dlnk = p_task; 00186 p_task->p_blnk = p; 00187 if (p_task->p_dlnk != NULL) { 00188 p_task->p_dlnk->p_blnk = p_task; 00189 } 00190 p_task->delta_time = (U16)(delta - idelay); 00191 p->delta_time -= p_task->delta_time; 00192 } 00193 00194 00195 /*--------------------------- rt_dec_dly ------------------------------------*/ 00196 00197 void rt_dec_dly (void) { 00198 /* Decrement delta time of list head: remove tasks having a value of zero.*/ 00199 P_TCB p_rdy; 00200 00201 if (os_dly.p_dlnk == NULL) { 00202 return; 00203 } 00204 os_dly.delta_time--; 00205 while ((os_dly.delta_time == 0) && (os_dly.p_dlnk != NULL)) { 00206 p_rdy = os_dly.p_dlnk; 00207 if (p_rdy->p_rlnk != NULL) { 00208 /* Task is really enqueued, remove task from semaphore/mailbox */ 00209 /* timeout waiting list. */ 00210 p_rdy->p_rlnk->p_lnk = p_rdy->p_lnk; 00211 if (p_rdy->p_lnk != NULL) { 00212 p_rdy->p_lnk->p_rlnk = p_rdy->p_rlnk; 00213 p_rdy->p_lnk = NULL; 00214 } 00215 p_rdy->p_rlnk = NULL; 00216 } 00217 rt_put_prio (&os_rdy, p_rdy); 00218 os_dly.delta_time = p_rdy->delta_time; 00219 if (p_rdy->state == WAIT_ITV) { 00220 /* Calculate the next time for interval wait. */ 00221 p_rdy->delta_time = p_rdy->interval_time + (U16)os_time; 00222 } 00223 p_rdy->state = READY; 00224 p_rdy->ret_val = OS_R_TMO; 00225 os_dly.p_dlnk = p_rdy->p_dlnk; 00226 if (p_rdy->p_dlnk != NULL) { 00227 p_rdy->p_dlnk->p_blnk = (P_TCB)&os_dly; 00228 p_rdy->p_dlnk = NULL; 00229 } 00230 p_rdy->p_blnk = NULL; 00231 } 00232 } 00233 00234 00235 /*--------------------------- rt_rmv_list -----------------------------------*/ 00236 00237 void rt_rmv_list (P_TCB p_task) { 00238 /* Remove task identified with "p_task" from ready, semaphore or mailbox */ 00239 /* waiting list if enqueued. */ 00240 P_TCB p_b; 00241 00242 if (p_task->p_rlnk != NULL) { 00243 /* A task is enqueued in semaphore / mailbox waiting list. */ 00244 p_task->p_rlnk->p_lnk = p_task->p_lnk; 00245 if (p_task->p_lnk != NULL) { 00246 p_task->p_lnk->p_rlnk = p_task->p_rlnk; 00247 } 00248 return; 00249 } 00250 00251 p_b = (P_TCB)&os_rdy; 00252 while (p_b != NULL) { 00253 /* Search the ready list for task "p_task" */ 00254 if (p_b->p_lnk == p_task) { 00255 p_b->p_lnk = p_task->p_lnk; 00256 return; 00257 } 00258 p_b = p_b->p_lnk; 00259 } 00260 } 00261 00262 00263 /*--------------------------- rt_rmv_dly ------------------------------------*/ 00264 00265 void rt_rmv_dly (P_TCB p_task) { 00266 /* Remove task identified with "p_task" from delay list if enqueued. */ 00267 P_TCB p_b; 00268 00269 p_b = p_task->p_blnk; 00270 if (p_b != NULL) { 00271 /* Task is really enqueued */ 00272 p_b->p_dlnk = p_task->p_dlnk; 00273 if (p_task->p_dlnk != NULL) { 00274 /* 'p_task' is in the middle of list */ 00275 p_b->delta_time += p_task->delta_time; 00276 p_task->p_dlnk->p_blnk = p_b; 00277 p_task->p_dlnk = NULL; 00278 } 00279 else { 00280 /* 'p_task' is at the end of list */ 00281 p_b->delta_time = 0; 00282 } 00283 p_task->p_blnk = NULL; 00284 } 00285 } 00286 00287 00288 /*--------------------------- rt_psq_enq ------------------------------------*/ 00289 00290 void rt_psq_enq (OS_ID entry, U32 arg) { 00291 /* Insert post service request "entry" into ps-queue. */ 00292 U32 idx; 00293 00294 idx = rt_inc_qi (os_psq->size, &os_psq->count, &os_psq->first); 00295 if (idx < os_psq->size) { 00296 os_psq->q[idx].id = entry; 00297 os_psq->q[idx].arg = arg; 00298 } 00299 else { 00300 os_error (OS_ERR_FIFO_OVF); 00301 } 00302 } 00303 00304 00305 /*---------------------------------------------------------------------------- 00306 * end of file 00307 *---------------------------------------------------------------------------*/ 00308
Generated on Tue Jul 12 2022 15:37:22 by
1.7.2