|
ChibiOS/RT
2.5.1 |
00001 /* 00002 ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, 00003 2011,2012 Giovanni Di Sirio. 00004 00005 This file is part of ChibiOS/RT. 00006 00007 ChibiOS/RT is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 ChibiOS/RT is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 /** 00022 * @file chmsg.c 00023 * @brief Messages code. 00024 * 00025 * @addtogroup messages 00026 * @details Synchronous inter-thread messages APIs and services. 00027 * <h2>Operation Mode</h2> 00028 * Synchronous messages are an easy to use and fast IPC mechanism, 00029 * threads can both act as message servers and/or message clients, 00030 * the mechanism allows data to be carried in both directions. Note 00031 * that messages are not copied between the client and server threads 00032 * but just a pointer passed so the exchange is very time 00033 * efficient.<br> 00034 * Messages are scalar data types of type @p msg_t that are guaranteed 00035 * to be size compatible with data pointers. Note that on some 00036 * architectures function pointers can be larger that @p msg_t.<br> 00037 * Messages are usually processed in FIFO order but it is possible to 00038 * process them in priority order by enabling the 00039 * @p CH_USE_MESSAGES_PRIORITY option in @p chconf.h.<br> 00040 * @pre In order to use the message APIs the @p CH_USE_MESSAGES option 00041 * must be enabled in @p chconf.h. 00042 * @post Enabling messages requires 6-12 (depending on the architecture) 00043 * extra bytes in the @p Thread structure. 00044 * @{ 00045 */ 00046 00047 #include "ch.h" 00048 00049 #if CH_USE_MESSAGES || defined(__DOXYGEN__) 00050 00051 #if CH_USE_MESSAGES_PRIORITY 00052 #define msg_insert(tp, qp) prio_insert(tp, qp) 00053 #else 00054 #define msg_insert(tp, qp) queue_insert(tp, qp) 00055 #endif 00056 00057 /** 00058 * @brief Sends a message to the specified thread. 00059 * @details The sender is stopped until the receiver executes a 00060 * @p chMsgRelease()after receiving the message. 00061 * 00062 * @param[in] tp the pointer to the thread 00063 * @param[in] msg the message 00064 * @return The answer message from @p chMsgRelease(). 00065 * 00066 * @api 00067 */ 00068 msg_t chMsgSend(Thread *tp, msg_t msg) { 00069 Thread *ctp = currp; 00070 00071 chDbgCheck(tp != NULL, "chMsgSend"); 00072 00073 chSysLock(); 00074 ctp->p_msg = msg; 00075 ctp->p_u.wtobjp = &tp->p_msgqueue; 00076 msg_insert(ctp, &tp->p_msgqueue); 00077 if (tp->p_state == THD_STATE_WTMSG) 00078 chSchReadyI(tp); 00079 chSchGoSleepS(THD_STATE_SNDMSGQ); 00080 msg = ctp->p_u.rdymsg; 00081 chSysUnlock(); 00082 return msg; 00083 } 00084 00085 /** 00086 * @brief Suspends the thread and waits for an incoming message. 00087 * @post After receiving a message the function @p chMsgGet() must be 00088 * called in order to retrieve the message and then @p chMsgRelease() 00089 * must be invoked in order to acknowledge the reception and send 00090 * the answer. 00091 * @note If the message is a pointer then you can assume that the data 00092 * pointed by the message is stable until you invoke @p chMsgRelease() 00093 * because the sending thread is suspended until then. 00094 * 00095 * @return A reference to the thread carrying the message. 00096 * 00097 * @api 00098 */ 00099 Thread *chMsgWait(void) { 00100 Thread *tp; 00101 00102 chSysLock(); 00103 if (!chMsgIsPendingI(currp)) 00104 chSchGoSleepS(THD_STATE_WTMSG); 00105 tp = fifo_remove(&currp->p_msgqueue); 00106 tp->p_state = THD_STATE_SNDMSG; 00107 chSysUnlock(); 00108 return tp; 00109 } 00110 00111 /** 00112 * @brief Releases a sender thread specifying a response message. 00113 * @pre Invoke this function only after a message has been received 00114 * using @p chMsgWait(). 00115 * 00116 * @param[in] tp pointer to the thread 00117 * @param[in] msg message to be returned to the sender 00118 * 00119 * @api 00120 */ 00121 void chMsgRelease(Thread *tp, msg_t msg) { 00122 00123 chSysLock(); 00124 chDbgAssert(tp->p_state == THD_STATE_SNDMSG, 00125 "chMsgRelease(), #1", "invalid state"); 00126 chMsgReleaseS(tp, msg); 00127 chSysUnlock(); 00128 } 00129 00130 #endif /* CH_USE_MESSAGES */ 00131 00132 /** @} */