ChibiOS 21.11.5
rt/src/chmsg.c
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006-2026 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 version 3 of the License.
9
10 ChibiOS is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/**
20 * @file rt/src/chmsg.c
21 * @brief Messages code.
22 *
23 * @addtogroup messages
24 * @details Synchronous inter-thread messages APIs and services.
25 * <h2>Operation Mode</h2>
26 * Synchronous messages are an easy to use and fast IPC mechanism,
27 * threads can both act as message servers and/or message clients,
28 * the mechanism allows data to be carried in both directions. Note
29 * that messages are not copied between the client and server threads
30 * but just a pointer passed so the exchange is very time
31 * efficient.<br>
32 * Messages are scalar data types of type @p msg_t that are guaranteed
33 * to be size compatible with data pointers. Note that on some
34 * architectures function pointers can be larger that @p msg_t.<br>
35 * Messages are usually processed in FIFO order but it is possible to
36 * process them in priority order by enabling the
37 * @p CH_CFG_USE_MESSAGES_PRIORITY option in @p chconf.h.<br>
38 * @pre In order to use the message APIs the @p CH_CFG_USE_MESSAGES option
39 * must be enabled in @p chconf.h.
40 * @post Enabling messages requires 6-12 (depending on the architecture)
41 * extra bytes in the @p thread_t structure.
42 * @{
43 */
44
45#include "ch.h"
46
47#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
48
49/*===========================================================================*/
50/* Module exported variables. */
51/*===========================================================================*/
52
53/*===========================================================================*/
54/* Module local types. */
55/*===========================================================================*/
56
57/*===========================================================================*/
58/* Module local variables. */
59/*===========================================================================*/
60
61/*===========================================================================*/
62/* Module local functions. */
63/*===========================================================================*/
64
65/*===========================================================================*/
66/* Module exported functions. */
67/*===========================================================================*/
68
69/**
70 * @brief Sends a message to the specified thread.
71 * @details The sender is stopped until the receiver executes a
72 * @p chMsgRelease()after receiving the message.
73 *
74 * @param[in] tp the pointer to the thread
75 * @param[in] msg the message
76 * @return The answer message from @p chMsgRelease().
77 *
78 * @api
79 */
81 thread_t *currtp = chThdGetSelfX();
82
83 chDbgCheck(tp != NULL);
84
85 chSysLock();
86 currtp->sentmsg = msg;
87 currtp->u.wtobjp = (void *)&tp->msgqueue;
88 __ch_msg_insert(&tp->msgqueue, currtp);
89 if (tp->state == CH_STATE_WTMSG) {
90 tp->u.rdymsg = MSG_OK;
91 (void) chSchReadyI(tp);
92 }
94 msg = currtp->u.rdymsg;
96
97 return msg;
98}
99
100/**
101 * @brief Suspends the thread and waits for an incoming message.
102 * @post After receiving a message the function @p chMsgGet() must be
103 * called in order to retrieve the message and then @p chMsgRelease()
104 * must be invoked in order to acknowledge the reception and send
105 * the answer.
106 * @note If the message is a pointer then you can assume that the data
107 * pointed by the message is stable until you invoke @p chMsgRelease()
108 * because the sending thread is suspended until then.
109 * @note The reference counter of the sender thread is not increased, the
110 * returned pointer is a temporary reference.
111 *
112 * @return A pointer to the thread carrying the message.
113 *
114 * @sclass
115 */
117 thread_t *currtp = chThdGetSelfX();
118 thread_t *tp;
119
121
122 if (!chMsgIsPendingI(currtp)) {
124 }
127
128 return tp;
129}
130
131/**
132 * @brief Suspends the thread and waits for an incoming message or a
133 * timeout to occur.
134 * @post After receiving a message the function @p chMsgGet() must be
135 * called in order to retrieve the message and then @p chMsgRelease()
136 * must be invoked in order to acknowledge the reception and send
137 * the answer.
138 * @note If the message is a pointer then you can assume that the data
139 * pointed by the message is stable until you invoke @p chMsgRelease()
140 * because the sending thread is suspended until then.
141 * @note The reference counter of the sender thread is not increased, the
142 * returned pointer is a temporary reference.
143 *
144 * @param[in] timeout the number of ticks before the operation timeouts,
145 * the following special values are handled:
146 * - @a TIME_INFINITE no timeout.
147 * - @a TIME_IMMEDIATE this value is not allowed.
148 * @return A pointer to the thread carrying the message.
149 * @retval NULL if a timeout occurred.
150 *
151 * @sclass
152 */
154 thread_t *currtp = chThdGetSelfX();
155 thread_t *tp;
156
158 chDbgCheck(timeout != TIME_IMMEDIATE);
159
160 if (!chMsgIsPendingI(currtp)) {
161 if (chSchGoSleepTimeoutS(CH_STATE_WTMSG, timeout) != MSG_OK) {
162 return NULL;
163 }
164 }
167
168 return tp;
169}
170
171/**
172 * @brief Poll to check for an incoming message.
173 * @post If a message is available the function @p chMsgGet() must be
174 * called in order to retrieve the message and then @p chMsgRelease()
175 * must be invoked in order to acknowledge the reception and send
176 * the answer.
177 * @note If the message is a pointer then you can assume that the data
178 * pointed by the message is stable until you invoke @p chMsgRelease()
179 * because the sending thread is suspended until then.
180 * @note The reference counter of the sender thread is not increased, the
181 * returned pointer is a temporary reference.
182 *
183 * @return Result of the poll.
184 * @retval NULL if no incoming message waiting.
185 *
186 * @sclass
187 */
189 thread_t *currtp = chThdGetSelfX();
190 thread_t *tp = NULL;
191
192 if (chMsgIsPendingI(currtp)) {
195 }
196
197 return tp;
198}
199
200/**
201 * @brief Releases a sender thread specifying a response message.
202 * @pre Invoke this function only after a message has been received
203 * using @p chMsgWait().
204 *
205 * @param[in] tp pointer to the thread
206 * @param[in] msg message to be returned to the sender
207 *
208 * @api
209 */
211
212 chSysLock();
213 chDbgAssert(tp->state == CH_STATE_SNDMSG, "invalid state");
214 chMsgReleaseS(tp, msg);
215 chSysUnlock();
216}
217
218#endif /* CH_CFG_USE_MESSAGES == TRUE */
219
220/** @} */
#define chThdGetSelfX()
Returns a pointer to the current thread_t.
#define chSysUnlock()
Leaves the kernel lock state.
#define chSysLock()
Enters the kernel lock state.
#define chSchGoSleepS(newstate)
Puts the current thread to sleep into the specified state.
#define chMsgReleaseS(tp, msg)
Releases the thread waiting on top of the messages queue.
#define chDbgAssert(c, r)
Condition assertion.
Definition chdebug.h:143
#define chDbgCheck(c)
Function parameters check.
Definition chdebug.h:117
#define chDbgCheckClassS()
Definition chdebug.h:99
thread_t * chMsgWaitTimeoutS(sysinterval_t timeout)
Suspends the thread and waits for an incoming message or a timeout to occur.
msg_t chMsgSend(thread_t *tp, msg_t msg)
Sends a message to the specified thread.
thread_t * chMsgWaitS(void)
Suspends the thread and waits for an incoming message.
thread_t * chMsgPollS(void)
Poll to check for an incoming message.
static bool chMsgIsPendingI(thread_t *tp)
Evaluates to true if the thread has pending messages.
void chMsgRelease(thread_t *tp, msg_t msg)
Releases a sender thread specifying a response message.
#define __ch_msg_insert(qp, tp)
static ch_queue_t * ch_queue_fifo_remove(ch_queue_t *qp)
Removes the first-out element from a queue and returns it.
Definition chlists.h:279
#define threadref(p)
Safe cast of a queue pointer to a thread pointer.
Definition chearly.h:205
int32_t msg_t
Definition chearly.h:87
struct ch_thread thread_t
Type of a thread structure.
Definition chearly.h:132
#define CH_STATE_WTMSG
Waiting for a message.
Definition chschd.h:78
#define MSG_OK
Normal wakeup message.
Definition chschd.h:38
thread_t * chSchReadyI(thread_t *tp)
Inserts a thread in the Ready List placing it behind its peers.
Definition chschd.c:279
#define CH_STATE_SNDMSG
Sent a message, waiting answer.
Definition chschd.h:76
#define CH_STATE_SNDMSGQ
Sending a message, in queue.
Definition chschd.h:74
msg_t chSchGoSleepTimeoutS(tstate_t newstate, sysinterval_t timeout)
Puts the current thread to sleep into the specified state with timeout specification.
Definition chschd.c:358
#define TIME_IMMEDIATE
Zero interval specification for some functions with a timeout specification.
Definition chtime.h:46
uint64_t sysinterval_t
Type of time interval.
Definition chtime.h:118
msg_t rdymsg
Thread wakeup code.
Definition chobjects.h:239
void * wtobjp
Pointer to a generic "wait" object.
Definition chobjects.h:253
msg_t sentmsg
Sent message.
Definition chobjects.h:316
tstate_t state
Current thread state.
Definition chobjects.h:203
ch_queue_t msgqueue
Messages queue.
Definition chobjects.h:298
union ch_thread::@250330312022121344252011223135034045240103044261 u
State-specific fields.