ChibiOS/RT  5.1.0
chmsg.c
Go to the documentation of this file.
1 /*
2  ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio.
3 
4  This file is part of ChibiOS.
5 
6  ChibiOS is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 3 of the License, or
9  (at your option) any later version.
10 
11  ChibiOS is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 /**
21  * @file chmsg.c
22  * @brief Messages code.
23  *
24  * @addtogroup messages
25  * @details Synchronous inter-thread messages APIs and services.
26  * <h2>Operation Mode</h2>
27  * Synchronous messages are an easy to use and fast IPC mechanism,
28  * threads can both act as message servers and/or message clients,
29  * the mechanism allows data to be carried in both directions. Note
30  * that messages are not copied between the client and server threads
31  * but just a pointer passed so the exchange is very time
32  * efficient.<br>
33  * Messages are scalar data types of type @p msg_t that are guaranteed
34  * to be size compatible with data pointers. Note that on some
35  * architectures function pointers can be larger that @p msg_t.<br>
36  * Messages are usually processed in FIFO order but it is possible to
37  * process them in priority order by enabling the
38  * @p CH_CFG_USE_MESSAGES_PRIORITY option in @p chconf.h.<br>
39  * @pre In order to use the message APIs the @p CH_CFG_USE_MESSAGES option
40  * must be enabled in @p chconf.h.
41  * @post Enabling messages requires 6-12 (depending on the architecture)
42  * extra bytes in the @p thread_t structure.
43  * @{
44  */
45 
46 #include "ch.h"
47 
48 #if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
49 
50 /*===========================================================================*/
51 /* Module exported variables. */
52 /*===========================================================================*/
53 
54 /*===========================================================================*/
55 /* Module local types. */
56 /*===========================================================================*/
57 
58 /*===========================================================================*/
59 /* Module local variables. */
60 /*===========================================================================*/
61 
62 /*===========================================================================*/
63 /* Module local functions. */
64 /*===========================================================================*/
65 
66 #if CH_CFG_USE_MESSAGES_PRIORITY == TRUE
67 #define msg_insert(tp, qp) queue_prio_insert(tp, qp)
68 #else
69 #define msg_insert(tp, qp) queue_insert(tp, qp)
70 #endif
71 
72 /*===========================================================================*/
73 /* Module exported functions. */
74 /*===========================================================================*/
75 
76 /**
77  * @brief Sends a message to the specified thread.
78  * @details The sender is stopped until the receiver executes a
79  * @p chMsgRelease()after receiving the message.
80  *
81  * @param[in] tp the pointer to the thread
82  * @param[in] msg the message
83  * @return The answer message from @p chMsgRelease().
84  *
85  * @api
86  */
87 msg_t chMsgSend(thread_t *tp, msg_t msg) {
88  thread_t *ctp = currp;
89 
90  chDbgCheck(tp != NULL);
91 
92  chSysLock();
93  ctp->u.sentmsg = msg;
94  msg_insert(ctp, &tp->msgqueue);
95  if (tp->state == CH_STATE_WTMSG) {
96  (void) chSchReadyI(tp);
97  }
99  msg = ctp->u.rdymsg;
100  chSysUnlock();
101 
102  return msg;
103 }
104 
105 /**
106  * @brief Suspends the thread and waits for an incoming message.
107  * @post After receiving a message the function @p chMsgGet() must be
108  * called in order to retrieve the message and then @p chMsgRelease()
109  * must be invoked in order to acknowledge the reception and send
110  * the answer.
111  * @note If the message is a pointer then you can assume that the data
112  * pointed by the message is stable until you invoke @p chMsgRelease()
113  * because the sending thread is suspended until then.
114  *
115  * @return A reference to the thread carrying the message.
116  *
117  * @api
118  */
120  thread_t *tp;
121 
122  chSysLock();
123  if (!chMsgIsPendingI(currp)) {
125  }
126  tp = queue_fifo_remove(&currp->msgqueue);
127  tp->state = CH_STATE_SNDMSG;
128  chSysUnlock();
129 
130  return tp;
131 }
132 
133 /**
134  * @brief Releases a sender thread specifying a response message.
135  * @pre Invoke this function only after a message has been received
136  * using @p chMsgWait().
137  *
138  * @param[in] tp pointer to the thread
139  * @param[in] msg message to be returned to the sender
140  *
141  * @api
142  */
143 void chMsgRelease(thread_t *tp, msg_t msg) {
144 
145  chSysLock();
146  chDbgAssert(tp->state == CH_STATE_SNDMSG, "invalid state");
147  chMsgReleaseS(tp, msg);
148  chSysUnlock();
149 }
150 
151 #endif /* CH_CFG_USE_MESSAGES == TRUE */
152 
153 /** @} */
#define CH_STATE_WTMSG
Waiting for a message.
Definition: chschd.h:85
static void chSysLock(void)
Enters the kernel lock state.
Definition: chsys.h:353
thread_t * chSchReadyI(thread_t *tp)
Inserts a thread in the Ready List placing it behind its peers.
Definition: chschd.c:218
#define CH_STATE_SNDMSG
Sent a message, waiting answer.
Definition: chschd.h:82
static void chMsgReleaseS(thread_t *tp, msg_t msg)
Releases the thread waiting on top of the messages queue.
Definition: chmsg.h:113
#define currp
Current thread pointer access macro.
Definition: chschd.h:459
msg_t rdymsg
Thread wakeup code.
Definition: chschd.h:216
static void chSysUnlock(void)
Leaves the kernel lock state.
Definition: chsys.h:365
threads_queue_t msgqueue
Messages queue.
Definition: chschd.h:281
#define CH_STATE_SNDMSGQ
Sending a message, in queue.
Definition: chschd.h:79
msg_t chMsgSend(thread_t *tp, msg_t msg)
Sends a message to the specified thread.
Definition: chmsg.c:87
void chSchGoSleepS(tstate_t newstate)
Puts the current thread to sleep into the specified state.
Definition: chschd.c:289
msg_t sentmsg
Thread sent message.
Definition: chschd.h:242
#define chDbgCheck(c)
Function parameters check.
Definition: chdebug.h:101
static bool chMsgIsPendingI(thread_t *tp)
Evaluates to true if the thread has pending messages.
Definition: chmsg.h:79
#define chDbgAssert(c, r)
Condition assertion.
Definition: chdebug.h:127
thread_t * chMsgWait(void)
Suspends the thread and waits for an incoming message.
Definition: chmsg.c:119
void chMsgRelease(thread_t *tp, msg_t msg)
Releases a sender thread specifying a response message.
Definition: chmsg.c:143
tstate_t state
Current thread state.
Definition: chschd.h:180
union ch_thread::@0 u
State-specific fields.
ChibiOS/RT main include file.
thread_t * queue_fifo_remove(threads_queue_t *tqp)
Removes the first-out thread from a queue and returns it.
Definition: chschd.c:124
Structure representing a thread.
Definition: chschd.h:153