Line data Source code
1 : // Copyright 2024 Accenture. 2 : 3 : /** 4 : * Contains Cpp2CAN CANFrame. 5 : * \file CANFrame.h 6 : * \ingroup cpp2can 7 : */ 8 : #pragma once 9 : 10 : #include "can/canframes/CanId.h" 11 : 12 : #include <estd/assert.h> 13 : #include <platform/estdint.h> 14 : 15 : #include <cstring> 16 : 17 : namespace can 18 : { 19 : /** 20 : * Class representing a CANFrame. 21 : * 22 : * 23 : * A object of type CANFrame does not provide any payload-buffer by default. 24 : * It has to be provided with buffers by using a certain constructor or the 25 : * setPayload() method. 26 : * 27 : * \note * CANFrame may be used as base class for special frame classes providing 28 : * the programmer with explicit methods to access the signals that are 29 : * encoded in the CANFrames payload. 30 : */ 31 : class CANFrame 32 : { 33 : public: 34 : /** bitmask to extract sender */ 35 : static uint8_t const SENDER_MASK = 0xFFU; 36 : /** overhead of a CANFrame (in bit) */ 37 : static uint8_t const CAN_OVERHEAD_BITS = 47U; 38 : /** maximum payload length of a CANFrame */ 39 : #ifdef CPP2CAN_USE_64_BYTE_FRAMES 40 : static uint8_t const MAX_FRAME_LENGTH = 64U; 41 : #else 42 : static uint8_t const MAX_FRAME_LENGTH = 8U; 43 : #endif 44 : /** maximum value of a CANFrame id */ 45 : static uint32_t const MAX_FRAME_ID = 0x7FFU; 46 : /** maximum value of a CANFrame id */ 47 : static uint32_t const MAX_FRAME_ID_EXTENDED = 0x1FFFFFFFU; 48 : 49 : /** 50 : * \post getId() == 0x00 51 : * \post isExtendedId() == false 52 : * \post getPayload() == pointer to buffer 53 : * \post getPayloadLength() == 0 54 : * \post getTimestamp() == 0 55 : */ 56 : CANFrame(); 57 : 58 : explicit CANFrame(uint32_t id); 59 : 60 : /** 61 : * Copy constructor 62 : * \param frame CANFrame to copy content from 63 : */ 64 : CANFrame(CANFrame const& frame); 65 : 66 : /** 67 : * Constructor initializing id, payload and length 68 : * 69 : * \param id frame id \see ::can::CanId 70 : * \pre length <= MAX_FRAME_LENGTH 71 : * @throws assertion 72 : */ 73 : CANFrame(uint32_t id, uint8_t const payload[], uint8_t length); 74 : 75 : /** 76 : * Constructor initializing raw id with extended flag, payload and length. 77 : * 78 : * \pre rawId <= MAX_FRAME_ID_EXTENDED 79 : * \pre length <= MAX_FRAME_LENGTH 80 : * @throws assertion 81 : */ 82 : CANFrame(uint32_t rawId, uint8_t const payload[], uint8_t length, bool isExtendedId); 83 : 84 : /** 85 : * \return the identifier of this CANFrame. Use the CanId class to check for normal/extended id. 86 : */ 87 26 : uint32_t getId() const { return _id; } 88 : 89 : void setId(uint32_t id); 90 : 91 : /** 92 : * \return pointer to modifiable payload of this CANFrame 93 : */ 94 52 : uint8_t* getPayload() { return _payload; } 95 : 96 : /** 97 : * \return pointer to read only payload of this CANFrame 98 : */ 99 3 : uint8_t const* getPayload() const { return _payload; } 100 : 101 : uint8_t& operator[](uint8_t pos); 102 : 103 : // this const uint8_t& is important because in some bits 104 : // of the code we take the address of this! Ideally we would 105 : // just return the uint8_t by value. 106 : uint8_t const& operator[](uint8_t pos) const; 107 : 108 : /** 109 : * Sets the CANFrames payload and length 110 : * 111 : * \note * This method just sets a pointer to the payload and does not copy it! 112 : * 113 : * \post getPayload() == payload 114 : * \post getPayloadLength() == length 115 : * \post getMaxPayloadLength() == length 116 : */ 117 : void setPayload(uint8_t const payload[], uint8_t length); 118 : 119 : /** 120 : * \pre getPayload() != NULL 121 : * \pre length <= getMaxPayloadLength() 122 : * @throws assertion 123 : */ 124 : void setPayloadLength(uint8_t length); 125 : 126 30 : uint8_t getPayloadLength() const { return _payloadLength; } 127 : 128 : static uint8_t getMaxPayloadLength() { return CANFrame::MAX_FRAME_LENGTH; } 129 : 130 : /** 131 : * Assigns content of a CANFrame to another. 132 : * \param canFrame frame to copy from 133 : * \return reference to frame with new content 134 : * \pre getMaxPayloadLength() >= canFrame.getPayloadLength() 135 : * @throws assertion 136 : */ 137 : CANFrame& operator=(CANFrame const& canFrame); 138 : 139 : /** 140 : * \return value of timestamp 141 : */ 142 3 : uint32_t timestamp() const { return _timestamp; } 143 : 144 : /** 145 : * \return read only access to timestamp 146 : */ 147 : void setTimestamp(uint32_t aTimestamp); 148 : 149 : protected: 150 : friend bool operator==(CANFrame const& frame1, CANFrame const& frame2); 151 : 152 : private: 153 : uint32_t _id; 154 : uint32_t _timestamp; 155 : uint8_t _payload[CANFrame::MAX_FRAME_LENGTH]; 156 : uint8_t _payloadLength; 157 : }; 158 : 159 : /** 160 : * Compares two CANFrames without considering the timestamp 161 : * \param frame1 first frame to compare 162 : * \param frame2 second frame to compare 163 : * \return * - true if frames are equal 164 : * - false if frames are not equal 165 : */ 166 : bool operator==(CANFrame const& frame1, CANFrame const& frame2); 167 : 168 : /* 169 : * inline 170 : */ 171 : 172 20 : inline void CANFrame::setId(uint32_t const id) { _id = id; } 173 : 174 : inline uint8_t& CANFrame::operator[](uint8_t const pos) { return _payload[pos]; } 175 : 176 : inline uint8_t const& CANFrame::operator[](uint8_t const pos) const { return _payload[pos]; } 177 : 178 31 : inline void CANFrame::setPayload(uint8_t const* const payload, uint8_t const length) 179 : { 180 31 : estd_assert(length <= MAX_FRAME_LENGTH); 181 : 182 30 : (void)memcpy(_payload, payload, static_cast<size_t>(length)); 183 30 : _payloadLength = length; 184 30 : } 185 : 186 6 : inline void CANFrame::setTimestamp(uint32_t const aTimestamp) { _timestamp = aTimestamp; } 187 : 188 : } // namespace can