rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
isotp.h
Go to the documentation of this file.
1#pragma once
2
3#include "fifo_buffer.h"
4#include "can.h"
5#include "can_msg_tx.h"
6#include "can_listener.h"
7
8#if EFI_UNIT_TEST
9#define PRINT printf
10#define PRINT_EOL "\n"
11#else
12#define PRINT efiPrintf
13#define PRINT_EOL ""
14#endif
15
16#if EFI_PROD_CODE | EFI_SIMULATOR
17#define can_msg_t msg_t
18#define can_sysinterval_t sysinterval_t
19#define CAN_MSG_OK MSG_OK
20#define CAN_MSG_TIMEOUT MSG_TIMEOUT
21#else
22#include "can_mocks.h"
23#endif /* EFI_UNIT_TEST */
24
25#define CAN_FLOW_STATUS_OK 0
26#define CAN_FLOW_STATUS_WAIT_MORE 1
27#define CAN_FLOW_STATUS_ABORT 2
28
35
37public:
39
40 // used for 'single' or 'first' frames
42 // used for 'consecutive' frames
43 int index;
44 // used for 'flow control' frames
45 int fcFlag;
48};
49
50// todo: what's the point of this wrapper/holder class anyway?
52public:
54
56 frame = f;
57 }
58
59 CanRxMessage(const CanRxMessage& msg) : frame(msg.frame) {}
60
62 // full content copy
63 frame = msg.frame;
64 return *this;
65 }
66
67public:
69};
70
72public:
73 virtual bool get(CanRxMessage &item, int timeout) = 0;
74};
75
77public:
78 virtual can_msg_t transmit(CanTxMessage &ctfp, can_sysinterval_t timeout) = 0;
79};
80
82public:
83 virtual can_msg_t receive(CANRxFrame *crfp, can_sysinterval_t timeout) = 0;
84 virtual void onTpFirstFrame() = 0;
85};
86
87class IsoTpBase {
88public:
89 IsoTpBase(ICanTransmitter *p_txTransport, size_t p_busIndex, uint32_t p_rxFrameId, uint32_t p_txFrameId)
90 :
91 txTransport(p_txTransport),
92 busIndex(p_busIndex),
93 rxFrameId(p_rxFrameId),
94 txFrameId(p_txFrameId)
95 {}
96
97 int sendFrame(const IsoTpFrameHeader & header, const uint8_t *data, int num, can_sysinterval_t timeout);
98
100
102 if (isoHeaderByteIndex) {
103 // yes that would be truncated to byte, that's expected
104 ctfp[0] = rxFrameId & 0xff;
105 }
106 if (txTransport) {
107 return txTransport->transmit(ctfp, timeout);
108 }
109 return CAN_MSG_OK;
110 }
111
112 // Offset of first ISO-TP byte, usually 0
113 // but some vendors add some specific data in first CAN byte
115
117
118 size_t busIndex;
119 uint32_t rxFrameId;
120 uint32_t txFrameId;
121};
122
123// We need an abstraction layer for unit-testing
124// todo: no reason for composite entity to exist, keep splitting CanStreamerState into RX and TX!
126};
127
128// most efficient sizes are 6 + x * 7 that way whole buffer is transmitted as (x+1) full packets
129#ifndef CAN_FIFO_BUF_SIZE
130#define CAN_FIFO_BUF_SIZE 76
131#endif // CAN_FIFO_BUF_SIZE
132
133#define CAN_FIFO_FRAME_SIZE 8
134
136public:
137 // serial_can uses fifo_buffer_sync, unify?
138 fifo_buffer<uint8_t, CAN_FIFO_BUF_SIZE> rxFifoBuf;
139 fifo_buffer<uint8_t, CAN_FIFO_BUF_SIZE> txFifoBuf;
140
141/*
142#if defined(TS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME)
143 // used to restore the original packet with CRC
144 uint8_t shortCrcPacketStagingArea[13];
145#endif
146*/
147 // used for multi-frame ISO-TP packets
150
152
153public:
154 CanStreamerState(ICanTransmitter *p_txTransport, ICanReceiver *p_rxTransport, size_t p_busIndex, uint32_t p_rxFrameId, uint32_t p_txFrameId)
155 :
156 IsoTpBase(p_txTransport, p_busIndex, p_rxFrameId, p_txFrameId),
157 rxTransport(p_rxTransport)
158 {}
159
161
162 void reset();
163
164 int sendFrame(const IsoTpFrameHeader & header, const uint8_t *data, int num, can_sysinterval_t timeout);
165 int receiveFrame(const CANRxFrame &rxmsg, uint8_t *buf, int num, can_sysinterval_t timeout);
166 int getDataFromFifo(uint8_t *rxbuf, size_t &numBytes);
167 // returns the number of bytes sent
168 int sendDataTimeout(const uint8_t *txbuf, int numBytes, can_sysinterval_t timeout);
169
170 // streaming support for TS I/O (see tunerstudio_io.cpp)
171 can_msg_t streamAddToTxTimeout(size_t *np, const uint8_t *txbuf, can_sysinterval_t timeout);
173 can_msg_t streamReceiveTimeout(size_t *np, uint8_t *rxbuf, can_sysinterval_t timeout);
174};
175
176#define ISOTP_RX_QUEUE_LEN 4
177
178class IsoTpRx : public CanListener, public IsoTpBase {
179public:
180 IsoTpRx(size_t p_busIndex, uint32_t p_rxFrameId, uint32_t p_txFrameId)
181 :
182 CanListener(p_rxFrameId),
183 IsoTpBase(nullptr, p_busIndex, p_rxFrameId, p_txFrameId)
184 {
185 // not cool: this would invoke ChibiOS meaning we have to be careful where instances are declared in order to avoid
186 // initialization too soon
187 // todo: https://github.com/rusefi/rusefi/issues/8938
188 rxFifoBuf.clear();
189 registerCanListener(*this);
190 }
191
194 }
195
196 void reset() {
197 rxFifoBuf.clear();
200 }
201
202 bool isRxEmpty() {
203 return rxFifoBuf.isEmpty();
204 }
205
206 /* CAN messages entry point */
207 virtual void decodeFrame(const CANRxFrame& frame, efitick_t nowNt)
208 {
209 if (frame.DLC < 1 + isoHeaderByteIndex) {
210 // invalid++;
211 return;
212 }
213
214 if (isoHeaderByteIndex) {
215 if (frame.data8[0] != (txFrameId & 0xff)) {
216 return;
217 }
218 }
219
220 if (!rxFifoBuf.put(frame)) {
221 // overruns++;
222 }
223 }
224
225 /* User app entry point */
226 int readTimeout(uint8_t *rxbuf, size_t *size, sysinterval_t timeout);
227
228 void resetRxVerbose();
229private:
230 // used for multi-frame ISO-TP packets
233
234protected:
235 fifo_buffer_sync<CANRxFrame, ISOTP_RX_QUEUE_LEN> rxFifoBuf;
236};
237
238class IsoTpRxTx : public IsoTpRx {
239public:
240 IsoTpRxTx(size_t p_busIndex, uint32_t p_rxFrameId, uint32_t p_txFrameId)
241 :
242 IsoTpRx(p_busIndex, p_rxFrameId, p_txFrameId)
243 {}
244
245 int writeTimeout(const uint8_t *txbuf, size_t size, sysinterval_t timeout);
246};
void registerCanListener(CanListener &listener)
Definition can_rx.cpp:86
void unregisterCanListener(CanListener &listener)
Definition can_rx.cpp:96
int32_t can_msg_t
Definition can_mocks.h:6
int32_t can_sysinterval_t
Definition can_mocks.h:7
CanRxMessage(const CanRxMessage &msg)
Definition isotp.h:59
CANRxFrame frame
Definition isotp.h:68
CanRxMessage()
Definition isotp.h:53
CanRxMessage(const CANRxFrame &f)
Definition isotp.h:55
CanRxMessage & operator=(const CanRxMessage &msg)
Definition isotp.h:61
virtual bool get(CanRxMessage &item, int timeout)=0
fifo_buffer< uint8_t, CAN_FIFO_BUF_SIZE > txFifoBuf
Definition isotp.h:139
fifo_buffer< uint8_t, CAN_FIFO_BUF_SIZE > rxFifoBuf
Definition isotp.h:138
can_msg_t streamFlushTx(can_sysinterval_t timeout)
Definition isotp.cpp:325
int sendDataTimeout(const uint8_t *txbuf, int numBytes, can_sysinterval_t timeout)
Definition isotp.cpp:188
int sendFrame(const IsoTpFrameHeader &header, const uint8_t *data, int num, can_sysinterval_t timeout)
int receiveFrame(const CANRxFrame &rxmsg, uint8_t *buf, int num, can_sysinterval_t timeout)
Definition isotp.cpp:90
ICanReceiver * rxTransport
Definition isotp.h:151
can_msg_t streamReceiveTimeout(size_t *np, uint8_t *rxbuf, can_sysinterval_t timeout)
Definition isotp.cpp:335
int waitingForNumBytes
Definition isotp.h:148
bool isComplete
Definition isotp.h:160
CanStreamerState(ICanTransmitter *p_txTransport, ICanReceiver *p_rxTransport, size_t p_busIndex, uint32_t p_rxFrameId, uint32_t p_txFrameId)
Definition isotp.h:154
int waitingForFrameIndex
Definition isotp.h:149
int getDataFromFifo(uint8_t *rxbuf, size_t &numBytes)
Definition isotp.cpp:272
can_msg_t streamAddToTxTimeout(size_t *np, const uint8_t *txbuf, can_sysinterval_t timeout)
Definition isotp.cpp:285
virtual can_msg_t receive(CANRxFrame *crfp, can_sysinterval_t timeout)=0
virtual void onTpFirstFrame()=0
virtual can_msg_t transmit(CanTxMessage &ctfp, can_sysinterval_t timeout)=0
size_t busIndex
Definition isotp.h:118
can_msg_t transmit(CanTxMessage &ctfp, can_sysinterval_t timeout)
Definition isotp.h:101
uint32_t txFrameId
Definition isotp.h:120
int sendFrame(const IsoTpFrameHeader &header, const uint8_t *data, int num, can_sysinterval_t timeout)
Definition isotp.cpp:14
uint32_t rxFrameId
Definition isotp.h:119
ICanTransmitter * txTransport
Definition isotp.h:116
void sendFlowControl(can_sysinterval_t timeout)
Definition isotp.cpp:80
size_t isoHeaderByteIndex
Definition isotp.h:114
IsoTpBase(ICanTransmitter *p_txTransport, size_t p_busIndex, uint32_t p_rxFrameId, uint32_t p_txFrameId)
Definition isotp.h:89
IsoTpFrameType frameType
Definition isotp.h:38
int separationTime
Definition isotp.h:47
int readTimeout(uint8_t *rxbuf, size_t *size, sysinterval_t timeout)
Definition isotp.cpp:367
int waitingForNumBytes
Definition isotp.h:231
~IsoTpRx()
Definition isotp.h:192
void resetRxVerbose()
Definition isotp.cpp:479
uint8_t waitingForFrameIndex
Definition isotp.h:232
virtual void decodeFrame(const CANRxFrame &frame, efitick_t nowNt)
Definition isotp.h:207
void reset()
Definition isotp.h:196
fifo_buffer_sync< CANRxFrame, ISOTP_RX_QUEUE_LEN > rxFifoBuf
Definition isotp.h:235
IsoTpRx(size_t p_busIndex, uint32_t p_rxFrameId, uint32_t p_txFrameId)
Definition isotp.h:180
bool isRxEmpty()
Definition isotp.h:202
int writeTimeout(const uint8_t *txbuf, size_t size, sysinterval_t timeout)
Definition isotp.cpp:492
IsoTpRxTx(size_t p_busIndex, uint32_t p_rxFrameId, uint32_t p_txFrameId)
Definition isotp.h:240
IsoTpFrameType
Definition isotp.h:29
@ ISO_TP_FRAME_CONSECUTIVE
Definition isotp.h:32
@ ISO_TP_FRAME_FIRST
Definition isotp.h:31
@ ISO_TP_FRAME_FLOW_CONTROL
Definition isotp.h:33
@ ISO_TP_FRAME_SINGLE
Definition isotp.h:30
uint8_t data8[8]
Frame data.
Definition can_mocks.h:55
uint8_t DLC
Data length.
Definition can_mocks.h:42
composite packet size