|
25 | 25 | /// @li @b "comms/" - replace with "comms2/" |
26 | 26 | /// |
27 | 27 | /// @section page_use_prot_error_handling Error Handling |
28 | | -/// The COMMS library is intended to be used in embedded systems (including |
| 28 | +/// The @b COMMS library is intended to be used in embedded systems (including |
29 | 29 | /// bare metal), which means the library does not use exceptions to report errors. |
30 | 30 | /// The runtime errors are reported via @ref comms::ErrorStatus return values. All |
31 | 31 | /// pre- and post-conditions are checked using COMMS_ASSERT() macro. |
|
220 | 220 | /// std::size_t readMessage(MyMessage& msg, const std::uint8_t* buf, std::size_t len) |
221 | 221 | /// { |
222 | 222 | /// MyMessage::ReadIterator readIter = buf; |
223 | | -/// auto es = msg->read(readIter, len); // readIter is advanced in the read operation |
| 223 | +/// auto es = msg.read(readIter, len); // readIter is advanced in the read operation |
224 | 224 | /// if (es != comms::ErrorStatus::Success) { |
225 | 225 | /// ... // Report and handle error |
226 | 226 | /// return 0U; |
|
279 | 279 | /// iterator for write operation. In the example above the output buffer |
280 | 280 | /// is chosen to be @b std::vector<std::uint8_t> and the write operation will |
281 | 281 | /// be performed using @b push_back() calls on this vector (due to @b std::back_insert_iterator |
282 | | -/// being chosen as @b WriteIterator). @n |
| 282 | +/// being chosen as @b WriteIterator). |
| 283 | +/// |
283 | 284 | /// Also @b note, that iterator is passed by reference, which allows advancing |
284 | | -/// operator when write operation is performed. |
| 285 | +/// operator when write operation is performed. In case the iterator is |
| 286 | +/// random-access one, the difference between the initial and its value |
| 287 | +/// after the write has been performed can be used to determine amount of |
| 288 | +/// bytes that have been written to the buffer. |
285 | 289 | /// |
286 | 290 | /// The @ref comms::Message interface class defines @ref comms::Message::hasWrite() |
287 | 291 | /// static constexpr member function, which may be used at compile time to |
|
292 | 296 | /// @subsection page_use_prot_interface_length Polymorphic Serialisation Length Retrieval |
293 | 297 | /// Sometimes it may be needed to polymorphically retrieve the serialisation length of the message |
294 | 298 | /// in order to be able to reserve or allocate enough space for output buffer. |
295 | | -/// The COMMS library provides @ref comms::option::app::LengthInfoInterface option that |
| 299 | +/// The @b COMMS library provides @ref comms::option::app::LengthInfoInterface option that |
296 | 300 | /// adds @b length() member function to the interface. |
297 | 301 | /// @code |
298 | 302 | /// using MyMessage = |
|
314 | 318 | /// } |
315 | 319 | /// |
316 | 320 | /// protected: |
317 | | -/// virtual std::size_t lengthImpl() const = 0; // Implemented in the derived class |
| 321 | +/// virtual std::size_t lengthImpl() const {...}; // Must be overridden in the derived class |
318 | 322 | /// }; |
319 | 323 | /// @endcode |
320 | 324 | /// The @ref comms::Message interface class defines @ref comms::Message::hasLength() |
|
325 | 329 | /// |
326 | 330 | /// @subsection page_use_prot_interface_valid Polymorphic Validity Check |
327 | 331 | /// Sometimes it may be needed to be able to check whether the message contents |
328 | | -/// (fields) have valid values. The COMMS library provides comms::option::app::ValidCheckInterface |
| 332 | +/// (fields) have valid values. The @b COMMS library provides comms::option::app::ValidCheckInterface |
329 | 333 | /// option that adds @b valid() member function to the interface: |
330 | 334 | /// @code |
331 | 335 | /// using MyMessage = |
|
405 | 409 | /// } |
406 | 410 | /// |
407 | 411 | /// protected: |
408 | | -/// virtual DispatchRetType dispatchImpl(Handler& handler) = 0; // Must be implemented in the derived class |
| 412 | +/// virtual DispatchRetType dispatchImpl(Handler& handler) {...} // Must be overridden in the derived class |
409 | 413 | /// }; |
410 | 414 | /// @endcode |
411 | 415 | /// More details about polymorphic dispatching and handling will be provided |
|
425 | 429 | /// After updating such fields directly, using the interface of the message object, |
426 | 430 | /// the message contents may end up being in an inconsistent (or invalid) state. |
427 | 431 | /// There may be a need to polymorphically normalise the state of the message object. The |
428 | | -/// COMMS library provides @ref comms::option::app::RefreshInterface option, that adds |
| 432 | +/// @b COMMS library provides @ref comms::option::app::RefreshInterface option, that adds |
429 | 433 | /// @b refresh() member function to the message interface. |
430 | 434 | /// @code |
431 | 435 | /// using MyMessage = |
|
453 | 457 | /// } |
454 | 458 | /// }; |
455 | 459 | /// @endcode |
456 | | -/// Note, that the @b refresh() member function returns boolean value, which |
| 460 | +/// Note, that the @ref comms::Message::refresh() "refresh()" member function returns boolean value, which |
457 | 461 | /// is expected to be @b true in case at least one of the internal fields has |
458 | 462 | /// been updated, and @b false if message state remains unchanged. @n |
459 | 463 | /// Also note, that interface provide default implementation of @b refreshImpl() |
|
491 | 495 | /// } |
492 | 496 | /// |
493 | 497 | /// protected: |
494 | | -/// virtual const char* nameImpl() const = 0; |
| 498 | +/// virtual const char* nameImpl() const = 0; // Must be overridden in the derived class |
495 | 499 | /// }; |
496 | 500 | /// @endcode |
497 | 501 | /// The @ref comms::Message interface class defines @ref comms::Message::hasName() |
|
562 | 566 | /// comms::option::app::NameInterface // Add an ability to retrieve message name |
563 | 567 | /// >; |
564 | 568 | /// @endcode |
| 569 | +/// In case no polymorphic interface extension option has been chosen, every |
| 570 | +/// message object becomes a simple "data structure" without any v-table "penalty". |
| 571 | +/// @code |
| 572 | +/// using MyInterface = my_protocol::Message<>; |
| 573 | +/// @endcode |
565 | 574 | /// |
566 | 575 | /// @section page_use_prot_messages Protocol Messages |
567 | 576 | /// The protocol messages are expected to be defined as template classes, receiving |
|
591 | 600 | /// The interface class that was defined for the application (@b MyMessage) needs |
592 | 601 | /// to be passed as @b TBase template parameter. The defined message class |
593 | 602 | /// extends @ref comms::MessageBase, which in turn extends provided interface |
594 | | -/// class @b TBase, which in turn extends @ref comms::Message. The inheritence |
| 603 | +/// class @b TBase, which in turn extends (or typedef-s) @ref comms::Message. The inheritance |
595 | 604 | /// hierarchy may look like this: |
596 | 605 | /// @diafile message_class_hierarchy.dia |
597 | 606 | /// |
|
1233 | 1242 | /// calculating length, checking field's contents validity, and bringing field's |
1234 | 1243 | /// value into a consistent state. It may be required |
1235 | 1244 | /// when a message contains sequence (see @ref page_use_prot_fields_array_list) |
1236 | | -/// of such bundles/structs. The COMMS library provides @ref comms::field::Bundle |
| 1245 | +/// of such bundles/structs. The @b COMMS library provides @ref comms::field::Bundle |
1237 | 1246 | /// field for this purpose. It is quite similar to @ref comms::field::Bitfield described |
1238 | 1247 | /// earlier. The difference is that every member field |
1239 | 1248 | /// doesn't specify any length in bits, just bytes. For example: |
|
1307 | 1316 | /// @subsection page_use_prot_fields_array_list Array List Fields |
1308 | 1317 | /// Some communication protocols may define messages that transmit sequence |
1309 | 1318 | /// of similar fields and/or raw data buffers. To make it easier to handle, the |
1310 | | -/// COMMS library provides comms::field::ArrayList field which provide a required |
| 1319 | +/// @b COMMS library provides comms::field::ArrayList field which provide a required |
1311 | 1320 | /// interface to properly handle such sequences of data. It supports a |
1312 | 1321 | /// sequence of raw bytes |
1313 | 1322 | /// @code |
|
1356 | 1365 | /// >; |
1357 | 1366 | /// @endcode |
1358 | 1367 | /// Usage of this option just ensures right amount of elements "on the wire" after |
1359 | | -/// the field is serialised, but it doesn't automatically resize inner |
| 1368 | +/// the field is serialised, but it does @b NOT automatically resize inner |
1360 | 1369 | /// storage vector. |
1361 | 1370 | /// @code |
1362 | 1371 | /// MyList field; |
|
1384 | 1393 | /// |
1385 | 1394 | /// Also similar to @ref page_use_prot_fields_array_list, fixed length strings |
1386 | 1395 | /// are defined using @ref comms::option::def::SequenceFixedSize option, and just |
1387 | | -/// like with lists it doesn't automatically resize inner string, just ensures |
| 1396 | +/// like with lists it does @b NOT automatically resize inner string, just ensures |
1388 | 1397 | /// right amount of characters "on the wire" when field is serialised. |
1389 | 1398 | /// @code |
1390 | 1399 | /// using MyFixedString = |
|
1411 | 1420 | /// based on information recorded in other fields. For example there is a |
1412 | 1421 | /// "flags" bitmask field which specifies whether the following field exists or |
1413 | 1422 | /// missing. The optional field may also be tentative, i.e. if there is enough |
1414 | | -/// data in the input buffer it exists, and missing otherwise. The COMMS |
| 1423 | +/// data in the input buffer it exists, and missing otherwise. The @b COMMS |
1415 | 1424 | /// library provides @ref comms::field::Optional which is a mere wrapper around |
1416 | 1425 | /// other fields and provides an ability to set the optional state of the field. |
1417 | 1426 | /// @code |
|
1420 | 1429 | /// comms::field::IntValue<MyFieldBase, std::int32_t> |
1421 | 1430 | /// >; |
1422 | 1431 | /// @endcode |
1423 | | -/// The default mode of such field is "tentative". |
| 1432 | +/// The default mode of such field is "tentative", which means read if there |
| 1433 | +/// is data available in the input buffer, and write if there is enough space |
| 1434 | +/// in the output buffer. |
1424 | 1435 | /// @code |
1425 | 1436 | /// OptField field; |
1426 | 1437 | /// assert(field.isTentative()); |
|
2121 | 2132 | /// please open reference page of a required @b field class for the list of |
2122 | 2133 | /// supported options and read their documentation for more details. |
2123 | 2134 | /// |
| 2135 | +/// @subsection page_use_prot_fields_value_assign Field Value Assignment |
| 2136 | +/// As was mentioned earlier, every field class has @b value() member function, |
| 2137 | +/// which provides an access to internal value storage. Quite often there |
| 2138 | +/// may be case when explicit cast is required. |
| 2139 | +/// @code |
| 2140 | +/// using MyField = comms::field::IntValue<FieldBase, std::uint8_t>; // One byte int |
| 2141 | +/// int someValue = ...; |
| 2142 | +/// MyField field; |
| 2143 | +/// field.value() = static_cast<std::uint8_t>(someValue); |
| 2144 | +/// @endcode |
| 2145 | +/// The code above is boilerplate one, which in general should be avoided, because in |
| 2146 | +/// case of the field definition being changed, the cast below must also be changed. |
| 2147 | +/// Such boilerplate code can be avoided by using extra compile time type manipulations: |
| 2148 | +/// @code |
| 2149 | +/// field.value() = static_cast<typename std::decay<decltype(field.value())>::type>(someValue); |
| 2150 | +/// @endcode |
| 2151 | +/// However, it's too much typing to do and quite inconvenient for the developer. |
| 2152 | +/// The @b COMMS library provides @ref comms::cast_assign() stand alone |
| 2153 | +/// function which can be used for easy assignments with implicit @b static_cast to |
| 2154 | +/// appropriate type. It should be used for any arithmetic and/or enum storage |
| 2155 | +/// values. |
| 2156 | +/// @code |
| 2157 | +/// comms::cast_assign(field.value()) = someValue; // static_cast is automatic |
| 2158 | +/// @endcode |
| 2159 | +/// |
| 2160 | +/// @subsection page_use_prot_fields_cast Cast Between Fields |
| 2161 | +/// There may also be cases when value of one field needs to be assigned to |
| 2162 | +/// value of another type. If @b static_cast between the values works, then |
| 2163 | +/// it is possible to use @ref comms::cast_assign() function described in |
| 2164 | +/// @ref page_use_prot_fields_value_assign section above. |
| 2165 | +/// @code |
| 2166 | +/// comms::assign(field1.value()) = field2.value(); |
| 2167 | +/// @endcode |
| 2168 | +/// However, there may be cases when such cast is not possible. For example |
| 2169 | +/// value of 1 byte @ref comms::field::IntValue needs to be assigned to |
| 2170 | +/// a @ref comms::field::Bitfield length of which is also 1 byte, but it |
| 2171 | +/// splits the value into a couple of inner members. In this case |
| 2172 | +/// the @ref comms::field_cast() function should be used. |
| 2173 | +/// @code |
| 2174 | +/// using MyInt = comms::field::IntValue<FieldBase, std::uint8_t>; |
| 2175 | +/// using MyBitfield = comms::field::Bitfield<...>; |
| 2176 | +/// MyInt field1; |
| 2177 | +/// MyBitfield field2; |
| 2178 | +/// ... // Set values of field1 and field2 |
| 2179 | +/// field2 = comms::field_cast<MyBitfield>(field1); |
| 2180 | +/// @endcode |
| 2181 | +/// @b NOTE, that casting and assignment is performed on the field objects |
| 2182 | +/// themselves, not their stored values. |
| 2183 | +/// |
2124 | 2184 | /// @section page_use_prot_transport Transport Framing |
2125 | 2185 | /// In addition to definition of the messages and their contents, every |
2126 | 2186 | /// communication protocol must ensure that the message is successfully delivered |
|
2708 | 2768 | /// @endcode |
2709 | 2769 | /// |
2710 | 2770 | /// @subsection page_use_prot_handling_generic Generic Handler |
2711 | | -/// The COMMS library provides some help in defining custom message handlers. |
| 2771 | +/// The @b COMMS library provides some help in defining custom message handlers. |
2712 | 2772 | /// There is @ref comms::GenericHandler class that receives at least two template |
2713 | 2773 | /// parameters. The first one is a common interface class for all the handled messages |
2714 | 2774 | /// (@b MyMessage). The second template parameter is |
|
2972 | 3032 | /// using VersionType = ...; // Equals to ValueType of the relevant field. |
2973 | 3033 | /// |
2974 | 3034 | /// // Accessors for the version info |
2975 | | -/// VersionType version(); |
2976 | | -/// const VersionType& version(); |
| 3035 | +/// VersionType& version(); |
| 3036 | +/// const VersionType& version() const; |
2977 | 3037 | /// }; |
2978 | 3038 | /// |
2979 | 3039 | /// } // namespace my_protocol |
|
3096 | 3156 | /// @li @ref comms::option::app::NoWriteImpl |
3097 | 3157 | /// @li @ref comms::option::app::NoValidImpl |
3098 | 3158 | /// @li @ref comms::option::app::NoLengthImpl |
| 3159 | +/// @li @ref comms::option::app::NoDispatchImpl |
3099 | 3160 | /// |
3100 | 3161 | /// In order to be able to pass these extra options to message definition classes, |
3101 | 3162 | /// the support from the latter is required. If the protocol definition |
|
0 commit comments