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