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 <etl/error_handler.h>
13 :
14 : #include <platform/estdint.h>
15 :
16 : #include <cstring>
17 :
18 : namespace can
19 : {
20 : /**
21 : * Class representing a CANFrame.
22 : *
23 : *
24 : * An 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 extended 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) = default;
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 30 : 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 94 : uint8_t* getPayload() { return _payload; }
96 :
97 : /**
98 : * \return pointer to read only payload of this CANFrame
99 : */
100 51 : 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 31 : uint8_t getPayloadLength() const { return _payloadLength; }
128 :
129 13 : 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 : */
136 : CANFrame& operator=(CANFrame const& canFrame) = default;
137 :
138 : /**
139 : * \return value of timestamp
140 : */
141 4 : uint32_t timestamp() const { return _timestamp; }
142 :
143 : /**
144 : * \return read only access to timestamp
145 : */
146 : void setTimestamp(uint32_t aTimestamp);
147 :
148 : protected:
149 : friend bool operator==(CANFrame const& frame1, CANFrame const& frame2);
150 :
151 : private:
152 : uint32_t _id;
153 : uint32_t _timestamp;
154 : uint8_t _payload[CANFrame::MAX_FRAME_LENGTH];
155 : uint8_t _payloadLength;
156 : };
157 :
158 : /**
159 : * Compares two CANFrames without considering the timestamp
160 : * \param frame1 first frame to compare
161 : * \param frame2 second frame to compare
162 : * \return * - true if frames are equal
163 : * - false if frames are not equal
164 : */
165 : bool operator==(CANFrame const& frame1, CANFrame const& frame2);
166 :
167 : /*
168 : * inline
169 : */
170 :
171 23 : inline void CANFrame::setId(uint32_t const id) { _id = id; }
172 :
173 : inline uint8_t& CANFrame::operator[](uint8_t const pos) { return _payload[pos]; }
174 :
175 : inline uint8_t const& CANFrame::operator[](uint8_t const pos) const { return _payload[pos]; }
176 :
177 31 : inline void CANFrame::setPayload(uint8_t const* const payload, uint8_t const length)
178 : {
179 31 : ETL_ASSERT(
180 : length <= MAX_FRAME_LENGTH,
181 : ETL_ERROR_GENERIC("CAN frame length must be smaller than maximum 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
|