rusEFI console ISO-TP via PCAN #3667
This commit is contained in:
parent
f104e4cc2f
commit
3a33e59b86
|
@ -13,16 +13,15 @@
|
|||
#include "pch.h"
|
||||
#include "os_access.h"
|
||||
#include "crc.h"
|
||||
|
||||
#if HAL_USE_CAN
|
||||
|
||||
#include "serial_can.h"
|
||||
#include "can.h"
|
||||
#include "can_msg_tx.h"
|
||||
|
||||
#if HAL_USE_CAN
|
||||
static CanStreamer streamer;
|
||||
static CanStreamerState state(&streamer);
|
||||
static CanTsListener listener;
|
||||
#endif // HAL_USE_CAN
|
||||
|
||||
int CanStreamerState::sendFrame(const IsoTpFrameHeader & header, const uint8_t *data, int num, can_sysinterval_t timeout) {
|
||||
int dlc = 8; // standard 8 bytes
|
||||
|
@ -320,6 +319,8 @@ void CanTsListener::decodeFrame(const CANRxFrame& frame, efitick_t /*nowNt*/) {
|
|||
}
|
||||
}
|
||||
|
||||
#if HAL_USE_CAN
|
||||
|
||||
void CanStreamer::init() {
|
||||
registerCanListener(listener);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "can_listener.h"
|
||||
#include "can_msg_tx.h"
|
||||
|
||||
#if !EFI_UNIT_TEST
|
||||
#if EFI_PROD_CODE
|
||||
#define can_msg_t msg_t
|
||||
#define can_sysinterval_t sysinterval_t
|
||||
#define CAN_MSG_OK MSG_OK
|
||||
|
|
|
@ -7,9 +7,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#if EFI_UNIT_TEST
|
||||
#if ! EFI_PROD_CODE
|
||||
#include "can_mocks.h"
|
||||
#else
|
||||
#endif // EFI_PROD_CODE
|
||||
|
||||
|
||||
#if !EFI_UNIT_TEST
|
||||
#include "hal.h"
|
||||
#endif // EFI_UNIT_TEST
|
||||
|
||||
|
|
|
@ -78,10 +78,6 @@ void CanTxMessage::setDlc(uint8_t dlc) {
|
|||
m_frame.DLC = dlc;
|
||||
}
|
||||
|
||||
uint8_t& CanTxMessage::operator[](size_t index) {
|
||||
return m_frame.data8[index];
|
||||
}
|
||||
|
||||
void CanTxMessage::setShortValue(uint16_t value, size_t offset) {
|
||||
m_frame.data8[offset] = value & 0xFF;
|
||||
m_frame.data8[offset + 1] = value >> 8;
|
||||
|
@ -101,10 +97,11 @@ CanTxMessage::~CanTxMessage() {
|
|||
|
||||
}
|
||||
|
||||
uint8_t& CanTxMessage::operator[](size_t index) {
|
||||
return m_data8[index];
|
||||
}
|
||||
|
||||
void CanTxMessage::setDlc(uint8_t) { }
|
||||
|
||||
#endif // EFI_CAN_SUPPORT
|
||||
|
||||
uint8_t& CanTxMessage::operator[](size_t index) {
|
||||
return m_frame.data8[index];
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <cstddef>
|
||||
|
||||
#include "os_access.h"
|
||||
#include "can.h"
|
||||
|
||||
/**
|
||||
* Represent a message to be transmitted over CAN.
|
||||
|
@ -58,12 +59,16 @@ public:
|
|||
|
||||
void setDlc(uint8_t dlc);
|
||||
|
||||
//#if ! EFI_SIMULATOR
|
||||
const CANTxFrame *getFrame() const {
|
||||
return &m_frame;
|
||||
}
|
||||
//#endif // EFI_SIMULATOR
|
||||
|
||||
protected:
|
||||
#if EFI_CAN_SUPPORT
|
||||
//#if ! EFI_SIMULATOR
|
||||
CANTxFrame m_frame;
|
||||
#else // not EFI_CAN_SUPPORT
|
||||
uint8_t m_data8[8];
|
||||
#endif // EFI_CAN_SUPPORT
|
||||
//#endif // EFI_SIMULATOR
|
||||
|
||||
private:
|
||||
#if EFI_CAN_SUPPORT
|
||||
|
|
|
@ -1,3 +1,178 @@
|
|||
/*
|
||||
* @file test_can_serial.cpp
|
||||
*
|
||||
* Created on: Nov 26, 2020
|
||||
* @author andreika <prometheus.pcb@gmail.com>
|
||||
* @author Andrey Belomutskiy, (c) 2012-2020
|
||||
*/
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "pch.h"
|
||||
#include "engine_test_helper.h"
|
||||
#include "serial_can.h"
|
||||
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
class TestCanStreamer : public ICanStreamer {
|
||||
public:
|
||||
virtual can_msg_t transmit(canmbx_t mailbox, const CanTxMessage *ctfp, can_sysinterval_t timeout) override {
|
||||
const CANTxFrame * frame = ctfp->getFrame();
|
||||
// invoke copy constructor to clone frame
|
||||
CANTxFrame localCopy = *frame;
|
||||
localCopy.DLC = 8;
|
||||
ctfList.emplace_back(localCopy);
|
||||
return CAN_MSG_OK;
|
||||
}
|
||||
|
||||
virtual can_msg_t receive(canmbx_t mailbox, CANRxFrame *crfp, can_sysinterval_t timeout) override {
|
||||
*crfp = *crfList.begin();
|
||||
crfList.pop_front();
|
||||
return CAN_MSG_OK;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void checkFrame(const T & frame, const std::string & bytes) {
|
||||
EXPECT_EQ(bytes.size(), frame.DLC);
|
||||
for (size_t i = 0; i < bytes.size(); i++) {
|
||||
EXPECT_EQ(bytes[i], frame.data8[i]) << "Frame byte #" << i << " differs!";
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
std::list<CANTxFrame> ctfList;
|
||||
std::list<CANRxFrame> crfList;
|
||||
};
|
||||
|
||||
class TestCanStreamerState : public CanStreamerState {
|
||||
public:
|
||||
TestCanStreamerState() : CanStreamerState(&streamer) {}
|
||||
|
||||
void test(const std::vector<std::string> & dataList, const std::vector<std::string> & frames, int fifoLeftoverSize, const std::vector<size_t> & receiveChunks) {
|
||||
size_t totalSize = 0;
|
||||
std::string totalData;
|
||||
for (auto data : dataList) {
|
||||
size_t np = data.size();
|
||||
|
||||
totalSize += np;
|
||||
totalData += data;
|
||||
|
||||
streamAddToTxTimeout(&np, (uint8_t *)data.c_str(), 0);
|
||||
}
|
||||
|
||||
// check the FIFO buf size
|
||||
EXPECT_EQ(fifoLeftoverSize, txFifoBuf.getCount());
|
||||
|
||||
// send the rest
|
||||
streamFlushTx(0);
|
||||
|
||||
// check if correct the TX frames were sent
|
||||
EXPECT_EQ(frames.size(), streamer.ctfList.size());
|
||||
|
||||
auto it1 = streamer.ctfList.begin();
|
||||
auto it2 = frames.begin();
|
||||
for (; it1 != streamer.ctfList.end() && it2 != frames.end(); it1++, it2++) {
|
||||
streamer.checkFrame(*it1, *it2);
|
||||
}
|
||||
|
||||
// copy transmitted data back into the receive buffer
|
||||
for (auto f : streamer.ctfList) {
|
||||
CANRxFrame rf;
|
||||
rf.DLC = f.DLC;
|
||||
rf.RTR = f.RTR;
|
||||
rf.IDE = f.IDE;
|
||||
rf.EID = f.EID;
|
||||
rf.data64[0] = f.data64[0];
|
||||
streamer.crfList.push_back(rf);
|
||||
}
|
||||
|
||||
size_t totalReceivedSize = 0;
|
||||
std::string totalReceivedData;
|
||||
for (size_t chunkSize : receiveChunks) {
|
||||
size_t nr = chunkSize;
|
||||
uint8_t rxbuf[256];
|
||||
streamReceiveTimeout(&nr, rxbuf, 0);
|
||||
EXPECT_EQ(nr, chunkSize);
|
||||
totalReceivedSize += nr;
|
||||
totalReceivedData += std::string((const char *)rxbuf, nr);
|
||||
}
|
||||
// we should receive the same amount of bytes that we've sent
|
||||
EXPECT_EQ(totalSize, totalReceivedSize);
|
||||
// check the data
|
||||
for (size_t i = 0; i < totalSize; i++) {
|
||||
EXPECT_EQ(totalData[i], totalReceivedData[i]) << "Rcv. byte #" << i << " differs!";
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
TestCanStreamer streamer;
|
||||
};
|
||||
|
||||
TEST(testCanSerial, test1Frame) {
|
||||
/*
|
||||
{
|
||||
TestCanStreamerState state;
|
||||
state.test({ "1" }, { "\x01"s "1\0\0\0\0\0\0"s }, 1, { 1 }); // 1 byte -> 1 frame, 1 byte in FIFO
|
||||
}
|
||||
{
|
||||
TestCanStreamerState state;
|
||||
state.test({ "0123456" }, { "\x07"s "0123456"s }, 0, { 7 }); // 7 bytes -> 1 8-byte frame
|
||||
}
|
||||
{
|
||||
TestCanStreamerState state;
|
||||
state.test({ "0123456" }, { "\x07"s "0123456"s }, 0, { 1, 1, 1, 1, 1, 1, 1 }); // 7 bytes -> 1 8-byte frame, split receive test
|
||||
}
|
||||
{
|
||||
TestCanStreamerState state;
|
||||
state.test({ "0123456" }, { "\x07"s "0123456"s }, 0, { 3, 4 }); // 7 bytes -> 1 8-byte frame, split receive test
|
||||
}
|
||||
{
|
||||
TestCanStreamerState state;
|
||||
state.test({ "0", "1", "2", "3", "4", "5", "6" }, { "\x07"s "0123456"s }, 0, { 7 }); // 7 bytes separately -> 1 8-byte frame
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
TEST(testCanSerial, test2Frames) {
|
||||
{
|
||||
TestCanStreamerState state;
|
||||
state.test({ "01234567" }, { "\x07"s "0123456"s, "\x01"s "7\0\0\0\0\0\0"s }, 1, { 8 }); // 8 bytes -> 2 8-byte frames, 1 byte in FIFO
|
||||
}
|
||||
{
|
||||
TestCanStreamerState state;
|
||||
state.test({ "0123456ABCDEFG" }, { "\x07"s "0123456"s, "\x07"s "ABCDEFG"s }, 0, { 14 }); // 14 bytes -> 2 8-byte frames, empty FIFO
|
||||
}
|
||||
{
|
||||
TestCanStreamerState state;
|
||||
state.test({ "0123456ABCDEFG" }, { "\x07"s "0123456"s, "\x07"s "ABCDEFG"s }, 0, { 6, 1, 1, 6 }); // 14 bytes -> 2 8-byte frames, empty FIFO, split receive test
|
||||
}
|
||||
}
|
||||
|
||||
TEST(testCanSerial, testIrregularSplits) {
|
||||
{
|
||||
TestCanStreamerState state;
|
||||
state.test({ "012", "3456ABCDEFG" }, { "\x07"s "0123456"s, "\x07"s "ABCDEFG"s }, 0, { 7, 7 }); // 14 bytes -> 2 8-byte frames, empty FIFO
|
||||
}
|
||||
{
|
||||
TestCanStreamerState state;
|
||||
state.test({ "0123456ABC", "DEFG" }, { "\x07"s "0123456"s, "\x07"s "ABCDEFG"s }, 0, { 14 }); // 14 bytes -> 2 8-byte frames, empty FIFO
|
||||
}
|
||||
}
|
||||
|
||||
TEST(testCanSerial, testLongMessage) {
|
||||
{
|
||||
TestCanStreamerState state;
|
||||
state.test({ "abcdefghijklmnopqrstuvwxyz" }, {
|
||||
"\x07"s "abcdefg"s,
|
||||
"\x07"s "hijklmn"s,
|
||||
"\x07"s "opqrstu"s,
|
||||
"\x05"s "vwxyz\0\0"s }, 5, { 26 }); // 26 bytes -> 4 8-byte frames, 5 bytes left in FIFO
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue