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.
Dependencies: mbed Socket lwip-eth lwip-sys lwip
rt_Mailbox.c
00001 /*---------------------------------------------------------------------------- 00002 * RL-ARM - RTX 00003 *---------------------------------------------------------------------------- 00004 * Name: RT_MAILBOX.C 00005 * Purpose: Implements waits and wake-ups for mailbox messages 00006 * Rev.: V4.50 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_Config.h" 00037 #include "rt_System.h" 00038 #include "rt_List.h" 00039 #include "rt_Mailbox.h" 00040 #include "rt_MemBox.h" 00041 #include "rt_Task.h" 00042 #include "rt_HAL_CM.h" 00043 00044 00045 /*---------------------------------------------------------------------------- 00046 * Functions 00047 *---------------------------------------------------------------------------*/ 00048 00049 00050 /*--------------------------- rt_mbx_init -----------------------------------*/ 00051 00052 void rt_mbx_init (OS_ID mailbox, U16 mbx_size) { 00053 /* Initialize a mailbox */ 00054 P_MCB p_MCB = mailbox; 00055 00056 p_MCB->cb_type = MCB; 00057 p_MCB->state = 0; 00058 p_MCB->isr_st = 0; 00059 p_MCB->p_lnk = NULL; 00060 p_MCB->first = 0; 00061 p_MCB->last = 0; 00062 p_MCB->count = 0; 00063 p_MCB->size = (mbx_size + sizeof(void *) - sizeof(struct OS_MCB)) / 00064 (U32)sizeof (void *); 00065 } 00066 00067 00068 /*--------------------------- rt_mbx_send -----------------------------------*/ 00069 00070 OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout) { 00071 /* Send message to a mailbox */ 00072 P_MCB p_MCB = mailbox; 00073 P_TCB p_TCB; 00074 00075 if (p_MCB->state == 1) { 00076 /* A task is waiting for message */ 00077 p_TCB = rt_get_first ((P_XCB)p_MCB); 00078 if (p_MCB->p_lnk == NULL) { 00079 p_MCB->state = 0; 00080 } 00081 rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); 00082 rt_rmv_dly (p_TCB); 00083 rt_dispatch (p_TCB); 00084 } 00085 else { 00086 /* Store message in mailbox queue */ 00087 if (p_MCB->count == p_MCB->size) { 00088 /* No free message entry, wait for one. If message queue is full, */ 00089 /* then no task is waiting for message. The 'p_MCB->p_lnk' list */ 00090 /* pointer can now be reused for send message waits task list. */ 00091 if (timeout == 0) { 00092 return (OS_R_TMO); 00093 } 00094 if (p_MCB->p_lnk != NULL) { 00095 rt_put_prio ((P_XCB)p_MCB, os_tsk.run); 00096 } 00097 else { 00098 p_MCB->p_lnk = os_tsk.run; 00099 os_tsk.run->p_lnk = NULL; 00100 os_tsk.run->p_rlnk = (P_TCB)p_MCB; 00101 /* Task is waiting to send a message */ 00102 p_MCB->state = 2; 00103 } 00104 os_tsk.run->msg = p_msg; 00105 rt_block (timeout, WAIT_MBX); 00106 return (OS_R_TMO); 00107 } 00108 /* Yes, there is a free entry in a mailbox. */ 00109 p_MCB->msg[p_MCB->first] = p_msg; 00110 rt_inc (&p_MCB->count); 00111 if (++p_MCB->first == p_MCB->size) { 00112 p_MCB->first = 0; 00113 } 00114 } 00115 return (OS_R_OK); 00116 } 00117 00118 00119 /*--------------------------- rt_mbx_wait -----------------------------------*/ 00120 00121 OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout) { 00122 /* Receive a message; possibly wait for it */ 00123 P_MCB p_MCB = mailbox; 00124 P_TCB p_TCB; 00125 00126 /* If a message is available in the fifo buffer */ 00127 /* remove it from the fifo buffer and return. */ 00128 if (p_MCB->count) { 00129 *message = p_MCB->msg[p_MCB->last]; 00130 if (++p_MCB->last == p_MCB->size) { 00131 p_MCB->last = 0; 00132 } 00133 if (p_MCB->state == 2) { 00134 /* A task is waiting to send message */ 00135 p_TCB = rt_get_first ((P_XCB)p_MCB); 00136 if (p_MCB->p_lnk == NULL) { 00137 p_MCB->state = 0; 00138 } 00139 rt_ret_val(p_TCB, 0/*osOK*/); 00140 p_MCB->msg[p_MCB->first] = p_TCB->msg; 00141 if (++p_MCB->first == p_MCB->size) { 00142 p_MCB->first = 0; 00143 } 00144 rt_rmv_dly (p_TCB); 00145 rt_dispatch (p_TCB); 00146 } 00147 else { 00148 rt_dec (&p_MCB->count); 00149 } 00150 return (OS_R_OK); 00151 } 00152 /* No message available: wait for one */ 00153 if (timeout == 0) { 00154 return (OS_R_TMO); 00155 } 00156 if (p_MCB->p_lnk != NULL) { 00157 rt_put_prio ((P_XCB)p_MCB, os_tsk.run); 00158 } 00159 else { 00160 p_MCB->p_lnk = os_tsk.run; 00161 os_tsk.run->p_lnk = NULL; 00162 os_tsk.run->p_rlnk = (P_TCB)p_MCB; 00163 /* Task is waiting to receive a message */ 00164 p_MCB->state = 1; 00165 } 00166 rt_block(timeout, WAIT_MBX); 00167 return (OS_R_TMO); 00168 } 00169 00170 00171 /*--------------------------- rt_mbx_check ----------------------------------*/ 00172 00173 OS_RESULT rt_mbx_check (OS_ID mailbox) { 00174 /* Check for free space in a mailbox. Returns the number of messages */ 00175 /* that can be stored to a mailbox. It returns 0 when mailbox is full. */ 00176 P_MCB p_MCB = mailbox; 00177 00178 return (p_MCB->size - p_MCB->count); 00179 } 00180 00181 00182 /*--------------------------- isr_mbx_send ----------------------------------*/ 00183 00184 void isr_mbx_send (OS_ID mailbox, void *p_msg) { 00185 /* Same function as "os_mbx_send", but to be called by ISRs. */ 00186 P_MCB p_MCB = mailbox; 00187 00188 rt_psq_enq (p_MCB, (U32)p_msg); 00189 rt_psh_req (); 00190 } 00191 00192 00193 /*--------------------------- isr_mbx_receive -------------------------------*/ 00194 00195 OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message) { 00196 /* Receive a message in the interrupt function. The interrupt function */ 00197 /* should not wait for a message since this would block the rtx os. */ 00198 P_MCB p_MCB = mailbox; 00199 00200 if (p_MCB->count) { 00201 /* A message is available in the fifo buffer. */ 00202 *message = p_MCB->msg[p_MCB->last]; 00203 if (p_MCB->state == 2) { 00204 /* A task is locked waiting to send message */ 00205 rt_psq_enq (p_MCB, 0); 00206 rt_psh_req (); 00207 } 00208 rt_dec (&p_MCB->count); 00209 if (++p_MCB->last == p_MCB->size) { 00210 p_MCB->last = 0; 00211 } 00212 return (OS_R_MBX); 00213 } 00214 return (OS_R_OK); 00215 } 00216 00217 00218 /*--------------------------- rt_mbx_psh ------------------------------------*/ 00219 00220 void rt_mbx_psh (P_MCB p_CB, void *p_msg) { 00221 /* Store the message to the mailbox queue or pass it to task directly. */ 00222 P_TCB p_TCB; 00223 void *mem; 00224 00225 switch (p_CB->state) { 00226 case 3: 00227 /* Task is waiting to allocate memory, remove it from the waiting list */ 00228 mem = rt_alloc_box(p_msg); 00229 if (mem == NULL) break; 00230 p_TCB = rt_get_first ((P_XCB)p_CB); 00231 if (p_CB->p_lnk == NULL) { 00232 p_CB->state = 0; 00233 } 00234 rt_ret_val(p_TCB, (U32)mem); 00235 p_TCB->state = READY; 00236 rt_rmv_dly (p_TCB); 00237 rt_put_prio (&os_rdy, p_TCB); 00238 break; 00239 case 2: 00240 /* Task is waiting to send a message, remove it from the waiting list */ 00241 p_TCB = rt_get_first ((P_XCB)p_CB); 00242 if (p_CB->p_lnk == NULL) { 00243 p_CB->state = 0; 00244 } 00245 rt_ret_val(p_TCB, 0/*osOK*/); 00246 p_CB->msg[p_CB->first] = p_TCB->msg; 00247 rt_inc (&p_CB->count); 00248 if (++p_CB->first == p_CB->size) { 00249 p_CB->first = 0; 00250 } 00251 p_TCB->state = READY; 00252 rt_rmv_dly (p_TCB); 00253 rt_put_prio (&os_rdy, p_TCB); 00254 break; 00255 case 1: 00256 /* Task is waiting for a message, pass the message to the task directly */ 00257 p_TCB = rt_get_first ((P_XCB)p_CB); 00258 if (p_CB->p_lnk == NULL) { 00259 p_CB->state = 0; 00260 } 00261 rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); 00262 p_TCB->state = READY; 00263 rt_rmv_dly (p_TCB); 00264 rt_put_prio (&os_rdy, p_TCB); 00265 break; 00266 default: 00267 /* No task is waiting for a message, store it to the mailbox queue */ 00268 if (p_CB->count < p_CB->size) { 00269 p_CB->msg[p_CB->first] = p_msg; 00270 rt_inc (&p_CB->count); 00271 if (++p_CB->first == p_CB->size) { 00272 p_CB->first = 0; 00273 } 00274 } 00275 else { 00276 os_error (OS_ERR_MBX_OVF); 00277 } 00278 break; 00279 } 00280 } 00281 00282 /*---------------------------------------------------------------------------- 00283 * end of file 00284 *---------------------------------------------------------------------------*/ 00285
Generated on Tue Jul 12 2022 19:57:00 by
1.7.2