Developer World
Spresense SDK Library v3.2.0-ebc0364
MsgPacket.h
1/****************************************************************************
2 * modules/include/memutils/message/MsgPacket.h
3 *
4 * Copyright 2018 Sony Semiconductor Solutions Corporation
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 * 3. Neither the name of Sony Semiconductor Solutions Corporation nor
17 * the names of its contributors may be used to endorse or promote
18 * products derived from this software without specific prior written
19 * permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *
34 ****************************************************************************/
35
36#ifndef MSG_PACKET_H_INCLUDED
37#define MSG_PACKET_H_INCLUDED
38
39#include <new> /* placement new */
40#include <stdio.h> /* printf */
41#include "memutils/common_utils/common_types.h" /* MIN, uintN_t */
42#include "memutils/common_utils/common_assert.h" /* D_ASSERT */
43//#include "SpinLock.h" /* MEMORY_BARRIER */
44#include "memutils/message/type_holder.h" /* TypeHolder */
45
46#ifdef USE_MULTI_CORE
47#include "get_cpu_id.h" /* GET_CPU_ID */
48#else
49#define GET_CPU_ID() (0)
50#define MEMORY_BARRIER() {;}
51#endif
52
53/* Various type definition. */
54
55typedef uint16_t MsgType; /* ID of message type. */
56typedef uint16_t MsgQueId; /* ID of message queue. */
57typedef uint8_t MsgCpuId; /* CPU-ID of message. */
58typedef uint8_t MsgFlags; /* Flag of message. */
59
60enum MsgPri
61{
62 /* Priority of message. */
63
64 MsgPriNormal,
65 MsgPriHigh,
66 NumMsgPri /* Number of priority. */
67};
68
69/* Message parameter type match check */
70#define MSG_PARAM_TYPE_MATCH_CHECK false
71
72/*****************************************************************
73 * メッセージパケットヘッダクラス
74 *****************************************************************/
76public:
77 /* Basically, each flag is exclusive to MessageLib internal. */
78
79 /* Flag is empty. */
80
81 static const MsgFlags MsgFlagNull = 0x00; /* Flag is empty. */
82
83 /* Wait for parameter writing. */
84
85 static const MsgFlags MsgFlagWaitParam = 0x80;
86
87 /* Parameter is formatted with type. */
88
89 static const MsgFlags MsgFlagTypedParam = 0x40;
90 MsgPacketHeader(MsgType type, MsgQueId reply, MsgFlags flags, uint16_t size = 0) :
91 m_type(type),
92 m_reply(reply),
93 m_src_cpu(GET_CPU_ID()),
94 m_flags(flags),
95 m_param_size(size) {}
96
97 MsgType getType() const { return m_type; }
98 MsgQueId getReply() const { return m_reply; }
99 MsgCpuId getSrcCpu() const { return m_src_cpu; }
100 MsgFlags getFlags() const { return m_flags; }
101 uint16_t getParamSize() const { return m_param_size; }
102 void popParamNoDestruct() { m_param_size = 0; }
103
104protected:
105 bool isSelfCpu() const { return GET_CPU_ID() == getSrcCpu(); }
106 bool isTypedParam() const { return (m_flags & MsgFlagTypedParam) != 0; }
107
108protected:
109 MsgType m_type;
110 MsgQueId m_reply;
111 MsgCpuId m_src_cpu;
112 MsgFlags m_flags;
113 uint16_t m_param_size;
114}; /* class MsgPacketHeader */
115
116/*****************************************************************
117 * Class indicating that the message parameter does not exist
118 *****************************************************************/
120
121/*****************************************************************
122 * Class indicating that it is an address range parameter
123 *****************************************************************/
125public:
126 MsgRangedParam(const void* param, size_t param_size) :
127 m_param(param),
128 m_param_size(param_size) {}
129 const void* getParam() const { return m_param; }
130 size_t getParamSize() const { return m_param_size; }
131
132private:
133 const void* m_param;
134 size_t m_param_size;
135};
136
137/*****************************************************************
138 * Message Packet Class
139 * In the instance copy of this class,
140 * note that the parameters are not copied
141 *****************************************************************/
143public:
144 template<typename T>
145 T moveParam() {
146 T param = peekParam<T>();
147 popParam<T>();
148 return param;
149 }
150
151 template<typename T>
152 const T& peekParam() const {
153 D_ASSERT2(sizeof(T) == getParamSize(), AssertParamLog(AssertIdSizeError, sizeof(T), getParamSize()));
154 if (isTypeCheckEnable()) {
155 return reinterpret_cast<const TypeHolderBase*>(&m_param[0])->template get<T>();
156 } else {
157 return *reinterpret_cast<const T*>(&m_param[0]);
158 }
159 }
160
161 template<typename T>
162 const T& peekParamOther() const {
163 D_ASSERT2(sizeof(T) <= getParamSize(), AssertParamLog(AssertIdSizeError, sizeof(T), getParamSize()));
164 return peekParamAny<T>();
165 }
166
167 template<typename T>
168 void popParam() {
169 D_ASSERT2(sizeof(T) == getParamSize(), AssertParamLog(AssertIdSizeError, sizeof(T), getParamSize()));
170 if (isTypeCheckEnable()) {
171 TypeHolderBase* p = reinterpret_cast<TypeHolderBase*>(&m_param[0]);
172 D_ASSERT2(p->template is_type<T>(),
173 AssertParamLog(AssertIdTypeUnmatch, (uint32_t)p->id(), (uint32_t)GET_TYPE_ID(T)));
174 p->~TypeHolderBase();
175 } else {
176 reinterpret_cast<T*>(&m_param[0])->~T();
177 }
178 m_param_size = 0;
179 }
180
181 void dump() const {
182 printf("T:%04x, R:%04x, C:%02x, F:%02x, S:%04x, P:",
183 m_type, m_reply, m_src_cpu, m_flags, m_param_size);
184 for (uint16_t i = 0; i < MIN(m_param_size, 16); ++i)
185 printf("%02x ", m_param[i]);
186 printf("\n");
187 }
188
189protected:
190 friend class MsgLib;
191 friend class MsgQueBlock;
192 friend class MsgLog;
193
194 MsgPacket(MsgType type, MsgQueId reply, MsgFlags flags) :
195 MsgPacketHeader(type, reply, flags) {}
196
197 void setParam(const MsgNullParam& /* param */, bool /* type_check */) {}
198
199 template<typename T>
200 void setParam(const T& param, bool type_check) {
201 if (type_check) {
202 m_flags |= MsgFlagTypedParam;
203 new (&m_param[0]) TypeHolder<T>(param);
204 } else {
205 new (&m_param[0]) T(param);
206 }
207 m_param_size = sizeof(T);
208 MEMORY_BARRIER();
209 m_flags &= ~MsgFlagWaitParam; /* Clear the parameter write wait flag. */
210 }
211
212 void setParam(const MsgRangedParam& param, bool /* type_check */) {
213 D_ASSERT((param.getParam() != NULL) && (0 < param.getParamSize()));
214 memcpy(&m_param[0], param.getParam(), param.getParamSize());
215 m_param_size = param.getParamSize();
216 MEMORY_BARRIER();
217 m_flags &= ~MsgFlagWaitParam; /* Clear the parameter write wait flag. */
218 }
219
220 bool isTypeCheckEnable() const { return MSG_PARAM_TYPE_MATCH_CHECK && isTypedParam(); }
221
222 /* Reference parameters with arbitrary types without error checking. */
223
224 template<typename T>
225 const T& peekParamAny() const {
226 if (isTypeCheckEnable()) {
227 return reinterpret_cast<const TypeHolderBase*>(&m_param[0])->template get_any<T>(false);
228 } else {
229 return *reinterpret_cast<const T*>(&m_param[0]);
230 }
231 }
232
233 /* For dump log only.
234 * Since there is no size check,
235 * there is a possibility of returning garbage.
236 */
237
238 uint32_t peekParamHead() const { return peekParamAny<uint32_t>(); }
239
240protected:
241 uint8_t m_param[0];
242}; /* class MsgPacket */
243
244#endif /* MSG_PACKET_H_INCLUDED */
Message Library Class.
Definition: Message.h:88
Definition: MsgPacket.h:119
Definition: MsgPacket.h:75
Definition: MsgPacket.h:142
Message Queue Class.
Definition: MsgQueBlock.h:72
Definition: MsgPacket.h:124
Definition: type_holder.h:53
Definition: type_holder.h:122
Definition: AssertInfo.h:210
Definition: MsgLog.h:42