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.
Fork of mbed-rtos by
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.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_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->p_lnk != NULL) && (p_MCB->state == 1)) { 00076 /* A task is waiting for message */ 00077 p_TCB = rt_get_first ((P_XCB)p_MCB); 00078 #ifdef __CMSIS_RTOS 00079 rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); 00080 #else 00081 *p_TCB->msg = p_msg; 00082 rt_ret_val (p_TCB, OS_R_MBX); 00083 #endif 00084 rt_rmv_dly (p_TCB); 00085 rt_dispatch (p_TCB); 00086 } 00087 else { 00088 /* Store message in mailbox queue */ 00089 if (p_MCB->count == p_MCB->size) { 00090 /* No free message entry, wait for one. If message queue is full, */ 00091 /* then no task is waiting for message. The 'p_MCB->p_lnk' list */ 00092 /* pointer can now be reused for send message waits task list. */ 00093 if (timeout == 0) { 00094 return (OS_R_TMO); 00095 } 00096 if (p_MCB->p_lnk != NULL) { 00097 rt_put_prio ((P_XCB)p_MCB, os_tsk.run); 00098 } 00099 else { 00100 p_MCB->p_lnk = os_tsk.run; 00101 os_tsk.run->p_lnk = NULL; 00102 os_tsk.run->p_rlnk = (P_TCB)p_MCB; 00103 /* Task is waiting to send a message */ 00104 p_MCB->state = 2; 00105 } 00106 os_tsk.run->msg = p_msg; 00107 rt_block (timeout, WAIT_MBX); 00108 return (OS_R_TMO); 00109 } 00110 /* Yes, there is a free entry in a mailbox. */ 00111 p_MCB->msg[p_MCB->first] = p_msg; 00112 rt_inc (&p_MCB->count); 00113 if (++p_MCB->first == p_MCB->size) { 00114 p_MCB->first = 0; 00115 } 00116 } 00117 return (OS_R_OK); 00118 } 00119 00120 00121 /*--------------------------- rt_mbx_wait -----------------------------------*/ 00122 00123 OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout) { 00124 /* Receive a message; possibly wait for it */ 00125 P_MCB p_MCB = mailbox; 00126 P_TCB p_TCB; 00127 00128 /* If a message is available in the fifo buffer */ 00129 /* remove it from the fifo buffer and return. */ 00130 if (p_MCB->count) { 00131 *message = p_MCB->msg[p_MCB->last]; 00132 if (++p_MCB->last == p_MCB->size) { 00133 p_MCB->last = 0; 00134 } 00135 if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 2)) { 00136 /* A task is waiting to send message */ 00137 p_TCB = rt_get_first ((P_XCB)p_MCB); 00138 #ifdef __CMSIS_RTOS 00139 rt_ret_val(p_TCB, 0/*osOK*/); 00140 #else 00141 rt_ret_val(p_TCB, OS_R_OK); 00142 #endif 00143 p_MCB->msg[p_MCB->first] = p_TCB->msg; 00144 if (++p_MCB->first == p_MCB->size) { 00145 p_MCB->first = 0; 00146 } 00147 rt_rmv_dly (p_TCB); 00148 rt_dispatch (p_TCB); 00149 } 00150 else { 00151 rt_dec (&p_MCB->count); 00152 } 00153 return (OS_R_OK); 00154 } 00155 /* No message available: wait for one */ 00156 if (timeout == 0) { 00157 return (OS_R_TMO); 00158 } 00159 if (p_MCB->p_lnk != NULL) { 00160 rt_put_prio ((P_XCB)p_MCB, os_tsk.run); 00161 } 00162 else { 00163 p_MCB->p_lnk = os_tsk.run; 00164 os_tsk.run->p_lnk = NULL; 00165 os_tsk.run->p_rlnk = (P_TCB)p_MCB; 00166 /* Task is waiting to receive a message */ 00167 p_MCB->state = 1; 00168 } 00169 rt_block(timeout, WAIT_MBX); 00170 #ifndef __CMSIS_RTOS 00171 os_tsk.run->msg = message; 00172 #endif 00173 return (OS_R_TMO); 00174 } 00175 00176 00177 /*--------------------------- rt_mbx_check ----------------------------------*/ 00178 00179 OS_RESULT rt_mbx_check (OS_ID mailbox) { 00180 /* Check for free space in a mailbox. Returns the number of messages */ 00181 /* that can be stored to a mailbox. It returns 0 when mailbox is full. */ 00182 P_MCB p_MCB = mailbox; 00183 00184 return (p_MCB->size - p_MCB->count); 00185 } 00186 00187 00188 /*--------------------------- isr_mbx_send ----------------------------------*/ 00189 00190 void isr_mbx_send (OS_ID mailbox, void *p_msg) { 00191 /* Same function as "os_mbx_send", but to be called by ISRs. */ 00192 P_MCB p_MCB = mailbox; 00193 00194 rt_psq_enq (p_MCB, (U32)p_msg); 00195 rt_psh_req (); 00196 } 00197 00198 00199 /*--------------------------- isr_mbx_receive -------------------------------*/ 00200 00201 OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message) { 00202 /* Receive a message in the interrupt function. The interrupt function */ 00203 /* should not wait for a message since this would block the rtx os. */ 00204 P_MCB p_MCB = mailbox; 00205 00206 if (p_MCB->count) { 00207 /* A message is available in the fifo buffer. */ 00208 *message = p_MCB->msg[p_MCB->last]; 00209 if (p_MCB->state == 2) { 00210 /* A task is locked waiting to send message */ 00211 rt_psq_enq (p_MCB, 0); 00212 rt_psh_req (); 00213 } 00214 rt_dec (&p_MCB->count); 00215 if (++p_MCB->last == p_MCB->size) { 00216 p_MCB->last = 0; 00217 } 00218 return (OS_R_MBX); 00219 } 00220 return (OS_R_OK); 00221 } 00222 00223 00224 /*--------------------------- rt_mbx_psh ------------------------------------*/ 00225 00226 void rt_mbx_psh (P_MCB p_CB, void *p_msg) { 00227 /* Store the message to the mailbox queue or pass it to task directly. */ 00228 P_TCB p_TCB; 00229 void *mem; 00230 00231 if (p_CB->p_lnk != NULL) switch (p_CB->state) { 00232 #ifdef __CMSIS_RTOS 00233 case 3: 00234 /* Task is waiting to allocate memory, remove it from the waiting list */ 00235 mem = rt_alloc_box(p_msg); 00236 if (mem == NULL) break; 00237 p_TCB = rt_get_first ((P_XCB)p_CB); 00238 rt_ret_val(p_TCB, (U32)mem); 00239 p_TCB->state = READY; 00240 rt_rmv_dly (p_TCB); 00241 rt_put_prio (&os_rdy, p_TCB); 00242 break; 00243 #endif 00244 case 2: 00245 /* Task is waiting to send a message, remove it from the waiting list */ 00246 p_TCB = rt_get_first ((P_XCB)p_CB); 00247 #ifdef __CMSIS_RTOS 00248 rt_ret_val(p_TCB, 0/*osOK*/); 00249 #else 00250 rt_ret_val(p_TCB, OS_R_OK); 00251 #endif 00252 p_CB->msg[p_CB->first] = p_TCB->msg; 00253 rt_inc (&p_CB->count); 00254 if (++p_CB->first == p_CB->size) { 00255 p_CB->first = 0; 00256 } 00257 p_TCB->state = READY; 00258 rt_rmv_dly (p_TCB); 00259 rt_put_prio (&os_rdy, p_TCB); 00260 break; 00261 case 1: 00262 /* Task is waiting for a message, pass the message to the task directly */ 00263 p_TCB = rt_get_first ((P_XCB)p_CB); 00264 #ifdef __CMSIS_RTOS 00265 rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); 00266 #else 00267 *p_TCB->msg = p_msg; 00268 rt_ret_val (p_TCB, OS_R_MBX); 00269 #endif 00270 p_TCB->state = READY; 00271 rt_rmv_dly (p_TCB); 00272 rt_put_prio (&os_rdy, p_TCB); 00273 break; 00274 } else { 00275 /* No task is waiting for a message, store it to the mailbox queue */ 00276 if (p_CB->count < p_CB->size) { 00277 p_CB->msg[p_CB->first] = p_msg; 00278 rt_inc (&p_CB->count); 00279 if (++p_CB->first == p_CB->size) { 00280 p_CB->first = 0; 00281 } 00282 } 00283 else { 00284 os_error (OS_ERR_MBX_OVF); 00285 } 00286 } 00287 } 00288 00289 /*---------------------------------------------------------------------------- 00290 * end of file 00291 *---------------------------------------------------------------------------*/ 00292
Generated on Wed Jul 13 2022 18:32:39 by
