ChibiOS/RT 7.0.5
chmsg.c
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
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 rt/src/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/*===========================================================================*/
67/* Module exported functions. */
68/*===========================================================================*/
69
70/**
71 * @brief Sends a message to the specified thread.
72 * @details The sender is stopped until the receiver executes a
73 * @p chMsgRelease()after receiving the message.
74 *
75 * @param[in] tp the pointer to the thread
76 * @param[in] msg the message
77 * @return The answer message from @p chMsgRelease().
78 *
79 * @api
80 */
82 thread_t *currtp = chThdGetSelfX();
83
84 chDbgCheck(tp != NULL);
85
86 chSysLock();
87 currtp->u.sentmsg = msg;
88 __ch_msg_insert(&tp->msgqueue, currtp);
89 if (tp->state == CH_STATE_WTMSG) {
90 (void) chSchReadyI(tp);
91 }
93 msg = currtp->u.rdymsg;
95
96 return msg;
97}
98
99/**
100 * @brief Suspends the thread and waits for an incoming message.
101 * @post After receiving a message the function @p chMsgGet() must be
102 * called in order to retrieve the message and then @p chMsgRelease()
103 * must be invoked in order to acknowledge the reception and send
104 * the answer.
105 * @note If the message is a pointer then you can assume that the data
106 * pointed by the message is stable until you invoke @p chMsgRelease()
107 * because the sending thread is suspended until then.
108 * @note The reference counter of the sender thread is not increased, the
109 * returned pointer is a temporary reference.
110 *
111 * @return A pointer to the thread carrying the message.
112 *
113 * @sclass
114 */
116 thread_t *currtp = chThdGetSelfX();
117 thread_t *tp;
118
120
121 if (!chMsgIsPendingI(currtp)) {
123 }
126
127 return tp;
128}
129
130/**
131 * @brief Suspends the thread and waits for an incoming message or a
132 * timeout to occur.
133 * @post After receiving a message the function @p chMsgGet() must be
134 * called in order to retrieve the message and then @p chMsgRelease()
135 * must be invoked in order to acknowledge the reception and send
136 * the answer.
137 * @note If the message is a pointer then you can assume that the data
138 * pointed by the message is stable until you invoke @p chMsgRelease()
139 * because the sending thread is suspended until then.
140 * @note The reference counter of the sender thread is not increased, the
141 * returned pointer is a temporary reference.
142 *
143 * @param[in] timeout the number of ticks before the operation timeouts,
144 * the following special values are allowed:
145 * - @a TIME_INFINITE no timeout.
146 * .
147 * @return A pointer to the thread carrying the message.
148 * @retval NULL if a timeout occurred.
149 *
150 * @sclass
151 */
153 thread_t *currtp = chThdGetSelfX();
154 thread_t *tp;
155
157
158 if (!chMsgIsPendingI(currtp)) {
159 if (chSchGoSleepTimeoutS(CH_STATE_WTMSG, timeout) != MSG_OK) {
160 return NULL;
161 }
162 }
165
166 return tp;
167}
168
169/**
170 * @brief Poll to check for an incoming message.
171 * @post If a message is available the function @p chMsgGet() must be
172 * called in order to retrieve the message and then @p chMsgRelease()
173 * must be invoked in order to acknowledge the reception and send
174 * the answer.
175 * @note If the message is a pointer then you can assume that the data
176 * pointed by the message is stable until you invoke @p chMsgRelease()
177 * because the sending thread is suspended until then.
178 * @note The reference counter of the sender thread is not increased, the
179 * returned pointer is a temporary reference.
180 *
181 * @return Result of the poll.
182 * @retval NULL if no incoming message waiting.
183 *
184 * @sclass
185 */
187 thread_t *currtp = chThdGetSelfX();
188 thread_t *tp = NULL;
189
190 if (chMsgIsPendingI(currtp)) {
193 }
194
195 return tp;
196}
197
198/**
199 * @brief Releases a sender thread specifying a response message.
200 * @pre Invoke this function only after a message has been received
201 * using @p chMsgWait().
202 *
203 * @param[in] tp pointer to the thread
204 * @param[in] msg message to be returned to the sender
205 *
206 * @api
207 */
209
210 chSysLock();
211 chDbgAssert(tp->state == CH_STATE_SNDMSG, "invalid state");
212 chMsgReleaseS(tp, msg);
213 chSysUnlock();
214}
215
216#endif /* CH_CFG_USE_MESSAGES == TRUE */
217
218/** @} */
ChibiOS/RT main include file.
#define chDbgAssert(c, r)
Condition assertion.
Definition chdebug.h:144
#define chDbgCheck(c)
Function parameters check.
Definition chdebug.h:118
#define chDbgCheckClassS()
Definition chdebug.h:100
thread_t * chMsgWaitTimeoutS(sysinterval_t timeout)
Suspends the thread and waits for an incoming message or a timeout to occur.
Definition chmsg.c:152
static void chMsgReleaseS(thread_t *tp, msg_t msg)
Releases the thread waiting on top of the messages queue.
Definition chmsg.h:207
msg_t chMsgSend(thread_t *tp, msg_t msg)
Sends a message to the specified thread.
Definition chmsg.c:81
thread_t * chMsgWaitS(void)
Suspends the thread and waits for an incoming message.
Definition chmsg.c:115
thread_t * chMsgPollS(void)
Poll to check for an incoming message.
Definition chmsg.c:186
static bool chMsgIsPendingI(thread_t *tp)
Evaluates to true if the thread has pending messages.
Definition chmsg.h:173
void chMsgRelease(thread_t *tp, msg_t msg)
Releases a sender thread specifying a response message.
Definition chmsg.c:208
#define __ch_msg_insert(qp, tp)
Definition chmsg.h:54
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:280
#define threadref(p)
Safe cast of a queue pointer to a thread pointer.
Definition chearly.h:206
int32_t msg_t
Definition chearly.h:88
struct ch_thread thread_t
Type of a thread structure.
Definition chearly.h:133
#define CH_STATE_WTMSG
Waiting for a message.
Definition chschd.h:79
#define MSG_OK
Normal wakeup message.
Definition chschd.h:39
thread_t * chSchReadyI(thread_t *tp)
Inserts a thread in the Ready List placing it behind its peers.
Definition chschd.c:280
void chSchGoSleepS(tstate_t newstate)
Puts the current thread to sleep into the specified state.
Definition chschd.c:305
#define CH_STATE_SNDMSG
Sent a message, waiting answer.
Definition chschd.h:77
#define CH_STATE_SNDMSGQ
Sending a message, in queue.
Definition chschd.h:75
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:359
static void chSysLock(void)
Enters the kernel lock state.
Definition chsys.h:407
static void chSysUnlock(void)
Leaves the kernel lock state.
Definition chsys.h:421
static thread_t * chThdGetSelfX(void)
Returns a pointer to the current thread_t.
Definition chthreads.h:341
uint64_t sysinterval_t
Type of time interval.
Definition chtime.h:119
msg_t rdymsg
Thread wakeup code.
Definition chobjects.h:242
msg_t sentmsg
Thread sent message.
Definition chobjects.h:268
tstate_t state
Current thread state.
Definition chobjects.h:206
ch_queue_t msgqueue
Messages queue.
Definition chobjects.h:307
union ch_thread::@250330312022121344252011223135034045240103044261 u
State-specific fields.