ChibiOS  21.6.0
rt/include/chmsg.h
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/include/chmsg.h
22  * @brief Messages macros and structures.
23  *
24  * @addtogroup messages
25  * @{
26  */
27 
28 #ifndef CHMSG_H
29 #define CHMSG_H
30 
31 #if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
32 
33 /*===========================================================================*/
34 /* Module constants. */
35 /*===========================================================================*/
36 
37 /*===========================================================================*/
38 /* Module pre-compile time settings. */
39 /*===========================================================================*/
40 
41 /*===========================================================================*/
42 /* Derived constants and error checks. */
43 /*===========================================================================*/
44 
45 /*===========================================================================*/
46 /* Module data structures and types. */
47 /*===========================================================================*/
48 
49 /*===========================================================================*/
50 /* Module macros. */
51 /*===========================================================================*/
52 
53 #if CH_CFG_USE_MESSAGES_PRIORITY == TRUE
54 #define __ch_msg_insert(qp, tp) ch_sch_prio_insert(qp, &tp->hdr.queue)
55 #else
56 #define __ch_msg_insert(qp, tp) ch_queue_insert(qp, &tp->hdr.queue)
57 #endif
58 
59 /*===========================================================================*/
60 /* External declarations. */
61 /*===========================================================================*/
62 
63 #ifdef __cplusplus
64 extern "C" {
65 #endif
66  msg_t chMsgSend(thread_t *tp, msg_t msg);
67  thread_t *chMsgWaitS(void);
69  thread_t *chMsgPollS(void);
70  void chMsgRelease(thread_t *tp, msg_t msg);
71 #ifdef __cplusplus
72 }
73 #endif
74 
75 /*===========================================================================*/
76 /* External declarations. */
77 /*===========================================================================*/
78 
79 /**
80  * @brief Suspends the thread and waits for an incoming message.
81  * @post After receiving a message the function @p chMsgGet() must be
82  * called in order to retrieve the message and then @p chMsgRelease()
83  * must be invoked in order to acknowledge the reception and send
84  * the answer.
85  * @note If the message is a pointer then you can assume that the data
86  * pointed by the message is stable until you invoke @p chMsgRelease()
87  * because the sending thread is suspended until then.
88  * @note The reference counter of the sender thread is not increased, the
89  * returned pointer is a temporary reference.
90  *
91  * @return A pointer to the thread carrying the message.
92  *
93  * @api
94  */
95 static inline thread_t *chMsgWait(void) {
96  thread_t *tp;
97 
98  chSysLock();
99  tp = chMsgWaitS();
100  chSysUnlock();
101 
102  return tp;
103 }
104 
105 /**
106  * @brief Suspends the thread and waits for an incoming message or a
107  * timeout to occur.
108  * @post After receiving a message the function @p chMsgGet() must be
109  * called in order to retrieve the message and then @p chMsgRelease()
110  * must be invoked in order to acknowledge the reception and send
111  * the answer.
112  * @note If the message is a pointer then you can assume that the data
113  * pointed by the message is stable until you invoke @p chMsgRelease()
114  * because the sending thread is suspended until then.
115  * @note The reference counter of the sender thread is not increased, the
116  * returned pointer is a temporary reference.
117  *
118  * @param[in] timeout the number of ticks before the operation timeouts,
119  * the following special values are allowed:
120  * - @a TIME_IMMEDIATE immediate timeout.
121  * - @a TIME_INFINITE no timeout.
122  * .
123  * @return A pointer to the thread carrying the message.
124  * @retval NULL if a timeout occurred.
125  *
126  * @api
127  */
128 static inline thread_t *chMsgWaitTimeout(sysinterval_t timeout) {
129  thread_t *tp;
130 
131  chSysLock();
132  tp = chMsgWaitTimeoutS(timeout);
133  chSysUnlock();
134 
135  return tp;
136 }
137 
138 /**
139  * @brief Poll to check for an incoming message.
140  * @post If a message is available the function @p chMsgGet() must be
141  * called in order to retrieve the message and then @p chMsgRelease()
142  * must be invoked in order to acknowledge the reception and send
143  * the answer.
144  * @note If the message is a pointer then you can assume that the data
145  * pointed by the message is stable until you invoke @p chMsgRelease()
146  * because the sending thread is suspended until then.
147  * @note The reference counter of the sender thread is not increased, the
148  * returned pointer is a temporary reference.
149  *
150  * @return A pointer to the thread carrying the message.
151  * @retval NULL if no incoming message waiting.
152  *
153  * @api
154  */
155 static inline thread_t *chMsgPoll(void) {
156  thread_t *tp;
157 
158  chSysLock();
159  tp = chMsgPollS();
160  chSysUnlock();
161 
162  return tp;
163 }
164 
165 /**
166  * @brief Evaluates to @p true if the thread has pending messages.
167  *
168  * @param[in] tp pointer to the thread
169  * @return The pending messages status.
170  *
171  * @iclass
172  */
173 static inline bool chMsgIsPendingI(thread_t *tp) {
174 
175  chDbgCheckClassI();
176 
177  return (bool)(tp->msgqueue.next != &tp->msgqueue);
178 }
179 
180 /**
181  * @brief Returns the message carried by the specified thread.
182  * @pre This function must be invoked immediately after exiting a call
183  * to @p chMsgWait().
184  *
185  * @param[in] tp pointer to the thread
186  * @return The message carried by the sender.
187  *
188  * @api
189  */
190 static inline msg_t chMsgGet(thread_t *tp) {
191 
192  chDbgAssert(tp->state == CH_STATE_SNDMSG, "invalid state");
193 
194  return tp->u.sentmsg;
195 }
196 
197 /**
198  * @brief Releases the thread waiting on top of the messages queue.
199  * @pre Invoke this function only after a message has been received
200  * using @p chMsgWait().
201  *
202  * @param[in] tp pointer to the thread
203  * @param[in] msg message to be returned to the sender
204  *
205  * @sclass
206  */
207 static inline void chMsgReleaseS(thread_t *tp, msg_t msg) {
208 
209  chDbgCheckClassS();
210 
211  chSchWakeupS(tp, msg);
212 }
213 
214 #endif /* CH_CFG_USE_MESSAGES == TRUE */
215 
216 #endif /* CHMSG_H */
217 
218 /** @} */
ch_queue::next
ch_queue_t * next
Next in the list/queue.
Definition: chlists.h:70
chMsgWaitS
thread_t * chMsgWaitS(void)
Suspends the thread and waits for an incoming message.
Definition: rt/src/chmsg.c:115
chMsgPollS
thread_t * chMsgPollS(void)
Poll to check for an incoming message.
Definition: rt/src/chmsg.c:186
chDbgAssert
#define chDbgAssert(c, r)
Condition assertion.
Definition: chdebug.h:144
chMsgReleaseS
static void chMsgReleaseS(thread_t *tp, msg_t msg)
Releases the thread waiting on top of the messages queue.
Definition: rt/include/chmsg.h:207
msg_t
int32_t msg_t
Definition: chearly.h:88
chMsgGet
static msg_t chMsgGet(thread_t *tp)
Returns the message carried by the specified thread.
Definition: rt/include/chmsg.h:190
ch_thread::sentmsg
msg_t sentmsg
Thread sent message.
Definition: chobjects.h:268
ch_thread
Structure representing a thread.
Definition: chobjects.h:156
chMsgSend
msg_t chMsgSend(thread_t *tp, msg_t msg)
Sends a message to the specified thread.
Definition: rt/src/chmsg.c:81
chMsgWait
static thread_t * chMsgWait(void)
Suspends the thread and waits for an incoming message.
Definition: rt/include/chmsg.h:95
ch_thread::msgqueue
ch_queue_t msgqueue
Messages queue.
Definition: chobjects.h:307
ch_thread::u
union ch_thread::@1 u
State-specific fields.
CH_STATE_SNDMSG
#define CH_STATE_SNDMSG
Sent a message, waiting answer.
Definition: chschd.h:77
chMsgIsPendingI
static bool chMsgIsPendingI(thread_t *tp)
Evaluates to true if the thread has pending messages.
Definition: rt/include/chmsg.h:173
chMsgPoll
static thread_t * chMsgPoll(void)
Poll to check for an incoming message.
Definition: rt/include/chmsg.h:155
chMsgRelease
void chMsgRelease(thread_t *tp, msg_t msg)
Releases a sender thread specifying a response message.
Definition: rt/src/chmsg.c:208
sysinterval_t
uint64_t sysinterval_t
Type of time interval.
Definition: chtime.h:119
ch_thread::state
tstate_t state
Current thread state.
Definition: chobjects.h:206
chMsgWaitTimeout
static thread_t * chMsgWaitTimeout(sysinterval_t timeout)
Suspends the thread and waits for an incoming message or a timeout to occur.
Definition: rt/include/chmsg.h:128
chMsgWaitTimeoutS
thread_t * chMsgWaitTimeoutS(sysinterval_t timeout)
Suspends the thread and waits for an incoming message or a timeout to occur.
Definition: rt/src/chmsg.c:152
chSysUnlock
#define chSysUnlock()
Leaves the kernel lock state.
Definition: nil/include/ch.h:1053
chSchWakeupS
void chSchWakeupS(thread_t *ntp, msg_t msg)
Wakes up a thread.
Definition: chschd.c:393
chSysLock
#define chSysLock()
Enters the kernel lock state.
Definition: nil/include/ch.h:1043