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