ソースの整理中ですが、利用はできます。
Dependencies: EthernetInterface HttpServer TextLCD mbed-rpc mbed-rtos 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.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 Tue Jul 12 2022 13:42:57 by 1.7.2