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_Mailbox.c
00001 /** 00002 * @file rt_Mailbox.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_Mailbox.h" 00027 #include "rt_Task.h" 00028 #include "rt_HAL_CM.h" 00029 00030 00031 /*---------------------------------------------------------------------------- 00032 * Functions 00033 *---------------------------------------------------------------------------*/ 00034 00035 00036 /*--------------------------- rt_mbx_init -----------------------------------*/ 00037 00038 void rt_mbx_init (OS_ID mailbox, U16 mbx_size) { 00039 /* Initialize a mailbox */ 00040 P_MCB p_MCB = mailbox; 00041 00042 p_MCB->cb_type = MCB; 00043 p_MCB->isr_st = 0; 00044 p_MCB->p_lnk = NULL; 00045 p_MCB->first = 0; 00046 p_MCB->last = 0; 00047 p_MCB->count = 0; 00048 p_MCB->size = (mbx_size + sizeof(void *) - sizeof(struct OS_MCB)) / 00049 (U32)sizeof (void *); 00050 } 00051 00052 00053 /*--------------------------- rt_mbx_send -----------------------------------*/ 00054 00055 OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout) { 00056 /* Send message to a mailbox */ 00057 P_MCB p_MCB = mailbox; 00058 P_TCB p_TCB; 00059 00060 if (p_MCB->p_lnk != NULL && p_MCB->count == 0) { 00061 /* A task is waiting for message */ 00062 p_TCB = rt_get_first ((P_XCB)p_MCB); 00063 *p_TCB->msg = p_msg; 00064 p_TCB->ret_val = OS_R_MBX; 00065 rt_rmv_dly (p_TCB); 00066 rt_dispatch (p_TCB); 00067 os_tsk.run->ret_val = OS_R_OK; 00068 } 00069 else { 00070 /* Store message in mailbox queue */ 00071 if (p_MCB->count == p_MCB->size) { 00072 /* No free message entry, wait for one. If message queue is full, */ 00073 /* then no task is waiting for message. The 'p_MCB->p_lnk' list */ 00074 /* pointer can now be reused for send message waits task list. */ 00075 if (timeout == 0) { 00076 return (OS_R_TMO); 00077 } 00078 if (p_MCB->p_lnk != NULL) { 00079 rt_put_prio ((P_XCB)p_MCB, os_tsk.run); 00080 } 00081 else { 00082 p_MCB->p_lnk = os_tsk.run; 00083 os_tsk.run->p_lnk = NULL; 00084 os_tsk.run->p_rlnk = (P_TCB)p_MCB; 00085 /* Signal the 'isr_mbx_receive ()' that the task is waiting */ 00086 /* to send a message */ 00087 p_MCB->isr_st = 1; 00088 } 00089 os_tsk.run->msg = p_msg; 00090 rt_block (timeout, WAIT_MBX); 00091 return (OS_R_TMO); 00092 } 00093 /* Yes, there is a free entry in a mailbox. */ 00094 p_MCB->msg[p_MCB->first] = p_msg; 00095 rt_inc (&p_MCB->count); 00096 if (++p_MCB->first == p_MCB->size) { 00097 p_MCB->first = 0; 00098 } 00099 } 00100 return (OS_R_OK); 00101 } 00102 00103 00104 /*--------------------------- rt_mbx_wait -----------------------------------*/ 00105 00106 OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout) { 00107 /* Receive a message; possibly wait for it */ 00108 P_MCB p_MCB = mailbox; 00109 P_TCB p_TCB; 00110 00111 /* If a message is available in the fifo buffer */ 00112 /* remove it from the fifo buffer and return. */ 00113 if (p_MCB->count) { 00114 *message = p_MCB->msg[p_MCB->last]; 00115 if (++p_MCB->last == p_MCB->size) { 00116 p_MCB->last = 0; 00117 } 00118 if (p_MCB->p_lnk != NULL) { 00119 /* A task is waiting to send message */ 00120 p_TCB = rt_get_first ((P_XCB)p_MCB); 00121 p_TCB->ret_val = OS_R_OK; 00122 p_MCB->msg[p_MCB->first] = p_TCB->msg; 00123 if (++p_MCB->first == p_MCB->size) { 00124 p_MCB->first = 0; 00125 } 00126 rt_rmv_dly (p_TCB); 00127 rt_dispatch (p_TCB); 00128 os_tsk.run->ret_val = OS_R_OK; 00129 } 00130 else { 00131 rt_dec (&p_MCB->count); 00132 } 00133 return (OS_R_OK); 00134 } 00135 /* No message available: wait for one */ 00136 if (timeout == 0) { 00137 return (OS_R_TMO); 00138 } 00139 if (p_MCB->p_lnk != NULL) { 00140 rt_put_prio ((P_XCB)p_MCB, os_tsk.run); 00141 } 00142 else { 00143 p_MCB->p_lnk = os_tsk.run; 00144 os_tsk.run->p_lnk = NULL; 00145 os_tsk.run->p_rlnk = (P_TCB)p_MCB; 00146 } 00147 rt_block(timeout, WAIT_MBX); 00148 os_tsk.run->msg = message; 00149 return (OS_R_TMO); 00150 } 00151 00152 00153 /*--------------------------- rt_mbx_check ----------------------------------*/ 00154 00155 OS_RESULT rt_mbx_check (OS_ID mailbox) { 00156 /* Check for free space in a mailbox. Returns the number of messages */ 00157 /* that can be stored to a mailbox. It returns 0 when mailbox is full. */ 00158 P_MCB p_MCB = mailbox; 00159 00160 return (p_MCB->size - p_MCB->count); 00161 } 00162 00163 00164 /*--------------------------- isr_mbx_send ----------------------------------*/ 00165 00166 void isr_mbx_send (OS_ID mailbox, void *p_msg) { 00167 /* Same function as "os_mbx_send", but to be called by ISRs. */ 00168 P_MCB p_MCB = mailbox; 00169 00170 rt_psq_enq (p_MCB, (U32)p_msg); 00171 rt_psh_req (); 00172 } 00173 00174 00175 /*--------------------------- isr_mbx_receive -------------------------------*/ 00176 00177 OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message) { 00178 /* Receive a message in the interrupt function. The interrupt function */ 00179 /* should not wait for a message since this would block the rtx os. */ 00180 P_MCB p_MCB = mailbox; 00181 00182 if (p_MCB->count) { 00183 /* A message is available in the fifo buffer. */ 00184 *message = p_MCB->msg[p_MCB->last]; 00185 if (p_MCB->isr_st == 1) { 00186 /* A task is locked waiting to send message */ 00187 p_MCB->isr_st = 2; 00188 rt_psq_enq (p_MCB, 0); 00189 rt_psh_req (); 00190 } 00191 rt_dec (&p_MCB->count); 00192 if (++p_MCB->last == p_MCB->size) { 00193 p_MCB->last = 0; 00194 } 00195 return (OS_R_MBX); 00196 } 00197 return (OS_R_OK); 00198 } 00199 00200 00201 /*--------------------------- rt_mbx_psh ------------------------------------*/ 00202 00203 void rt_mbx_psh (P_MCB p_CB, void *p_msg) { 00204 /* Store the message to the mailbox queue or pass it to task directly. */ 00205 P_TCB p_TCB; 00206 00207 /* Check if this was an 'isr_mbx_receive ()' post service request. */ 00208 if (p_CB->p_lnk != NULL && p_CB->isr_st == 2) { 00209 /* A task is waiting to send message, remove it from the waiting list. */ 00210 p_CB->isr_st = 0; 00211 p_TCB = rt_get_first ((P_XCB)p_CB); 00212 p_TCB->ret_val = OS_R_OK; 00213 /* Store the message to the mailbox queue. */ 00214 p_CB->msg[p_CB->first] = p_TCB->msg; 00215 rt_inc (&p_CB->count); 00216 if (++p_CB->first == p_CB->size) { 00217 p_CB->first = 0; 00218 } 00219 goto rdy; 00220 } 00221 /* A task is waiting for message, pass the message to task directly. */ 00222 if (p_CB->p_lnk != NULL && p_CB->count == 0) { 00223 p_TCB = rt_get_first ((P_XCB)p_CB); 00224 *p_TCB->msg = p_msg; 00225 p_TCB->ret_val = OS_R_MBX; 00226 rdy:p_TCB->state = READY; 00227 rt_rmv_dly (p_TCB); 00228 rt_put_prio (&os_rdy, p_TCB); 00229 } 00230 else { 00231 /* No task is waiting for message, store the message to the mailbox queue.*/ 00232 if (p_CB->count < p_CB->size) { 00233 p_CB->msg[p_CB->first] = p_msg; 00234 rt_inc (&p_CB->count); 00235 if (++p_CB->first == p_CB->size) { 00236 p_CB->first = 0; 00237 } 00238 } 00239 else { 00240 os_error (OS_ERR_MBX_OVF); 00241 } 00242 } 00243 } 00244 00245 /*---------------------------------------------------------------------------- 00246 * end of file 00247 *---------------------------------------------------------------------------*/ 00248
Generated on Tue Jul 12 2022 15:37:22 by
1.7.2