GCC Code Coverage Report


Directory: ./
File: firmware/console/binary/serial_can.h
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 12.5% 1 0 8
Functions: 25.0% 1 0 4
Branches: -% 0 0 0
Decisions: -% 0 - 0

Line Branch Decision Exec Source
1 /**
2 * @file serial_can.h
3 *
4 * @date Aug 1, 2020
5 * @author andreika <prometheus.pcb@gmail.com>
6 * @author Andrey Belomutskiy, (c) 2012-2020
7 */
8
9 #pragma once
10
11 #include "fifo_buffer.h"
12 #include "can_listener.h"
13 #include "can_msg_tx.h"
14
15 #if EFI_PROD_CODE | EFI_SIMULATOR
16 #define can_msg_t msg_t
17 #define can_sysinterval_t sysinterval_t
18 #define CAN_MSG_OK MSG_OK
19 #define CAN_MSG_TIMEOUT MSG_TIMEOUT
20 #else
21 #include "can_mocks.h"
22 #endif /* EFI_UNIT_TEST */
23
24
25 #define CAN_TIME_IMMEDIATE ((can_sysinterval_t)0)
26
27 // most efficient sizes are 6 + x * 7 that way whole buffer is transmitted as (x+1) full packets
28 #define CAN_FIFO_BUF_SIZE 76
29 #define CAN_FIFO_FRAME_SIZE 8
30
31 #define CAN_FLOW_STATUS_OK 0
32 #define CAN_FLOW_STATUS_WAIT_MORE 1
33 #define CAN_FLOW_STATUS_ABORT 2
34
35
36 enum IsoTpFrameType {
37 ISO_TP_FRAME_SINGLE = 0,
38 ISO_TP_FRAME_FIRST = 1,
39 ISO_TP_FRAME_CONSECUTIVE = 2,
40 ISO_TP_FRAME_FLOW_CONTROL = 3,
41 };
42
43 class IsoTpFrameHeader {
44 public:
45 IsoTpFrameType frameType;
46
47 // used for 'single' or 'first' frames
48 int numBytes;
49 // used for 'consecutive' frames
50 int index;
51 // used for 'flow control' frames
52 int fcFlag;
53 int blockSize;
54 int separationTime;
55 };
56
57 // We need an abstraction layer for unit-testing
58 class ICanStreamer {
59 public:
60 virtual can_msg_t transmit(canmbx_t mailbox, const CanTxMessage *ctfp, can_sysinterval_t timeout) = 0;
61 virtual can_msg_t receive(canmbx_t mailbox, CANRxFrame *crfp, can_sysinterval_t timeout) = 0;
62 };
63
64 class CanStreamerState {
65 public:
66 fifo_buffer<uint8_t, CAN_FIFO_BUF_SIZE> rxFifoBuf;
67 fifo_buffer<uint8_t, CAN_FIFO_BUF_SIZE> txFifoBuf;
68
69 #if defined(TS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME)
70 // used to restore the original packet with CRC
71 uint8_t tmpRxBuf[13];
72 #endif
73
74 // used for multi-frame ISO-TP packets
75 int waitingForNumBytes = 0;
76 int waitingForFrameIndex = 0;
77
78 ICanStreamer *streamer;
79
80 public:
81 13 CanStreamerState(ICanStreamer *s) : streamer(s) {}
82
83 int sendFrame(const IsoTpFrameHeader & header, const uint8_t *data, int num, can_sysinterval_t timeout);
84 int receiveFrame(CANRxFrame *rxmsg, uint8_t *buf, int num, can_sysinterval_t timeout);
85 int getDataFromFifo(uint8_t *rxbuf, size_t &numBytes);
86 // returns the number of bytes sent
87 int sendDataTimeout(const uint8_t *txbuf, int numBytes, can_sysinterval_t timeout);
88
89 // streaming support for TS I/O (see tunerstudio_io.cpp)
90 can_msg_t streamAddToTxTimeout(size_t *np, const uint8_t *txbuf, can_sysinterval_t timeout);
91 can_msg_t streamFlushTx(can_sysinterval_t timeout);
92 can_msg_t streamReceiveTimeout(size_t *np, uint8_t *rxbuf, can_sysinterval_t timeout);
93 };
94
95 class CanRxMessage {
96 public:
97 CanRxMessage() {}
98 CanRxMessage(const CANRxFrame &f) {
99 frame = f;
100 }
101 CanRxMessage(const CanRxMessage& msg) : frame(msg.frame) {}
102 CanRxMessage& operator=(const CanRxMessage& msg) {
103 frame = msg.frame;
104 return *this;
105 }
106
107 public:
108 CANRxFrame frame;
109 };
110
111 class CanTsListener : public CanListener {
112 public:
113 CanTsListener()
114 : CanListener(CAN_ECU_SERIAL_RX_ID)
115 {
116 }
117
118 virtual void decodeFrame(const CANRxFrame& frame, efitick_t nowNt);
119
120 bool get(CanRxMessage &item, int timeout) {
121 return rxFifo.get(item, timeout);
122 }
123
124 protected:
125 fifo_buffer_sync<CanRxMessage, CAN_FIFO_FRAME_SIZE> rxFifo;
126 };
127
128 #if HAL_USE_CAN
129 class CanStreamer : public ICanStreamer {
130 public:
131 void init();
132
133 virtual can_msg_t transmit(canmbx_t mailbox, const CanTxMessage *ctfp, can_sysinterval_t timeout) override;
134 virtual can_msg_t receive(canmbx_t mailbox, CANRxFrame *crfp, can_sysinterval_t timeout) override;
135 };
136
137 void canStreamInit(void);
138
139 // we don't have canStreamSendTimeout() because we need to "bufferize" the stream and send it in fixed-length packets
140 msg_t canStreamAddToTxTimeout(size_t *np, const uint8_t *txbuf, sysinterval_t timeout);
141 msg_t canStreamFlushTx(sysinterval_t timeout);
142
143 msg_t canStreamReceiveTimeout(size_t *np, uint8_t *rxbuf, sysinterval_t timeout);
144 #endif /* HAL_USE_CAN */
145