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