ts refactoring (#439)

* replace large buffer instances

* handlePageReadCommand uses locked

* cleanup

* explicitly call big vs. small packet implementation

* correctness

* unused UNUSED

* cleaner TS logging & cleanup

* about time we bumped this
This commit is contained in:
Matthew Kennedy 2024-06-09 20:26:27 -07:00 committed by GitHub
parent 6cc65b4c70
commit 2eb6c25313
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 65 additions and 165 deletions

View File

@ -34,7 +34,7 @@ public:
void stop() override; void stop() override;
// Special override for writeCrcPacket for small packets // Special override for writeCrcPacket for small packets
void writeCrcPacket(const uint8_t* buf, size_t size, bool allowLongPackets = false) override; void copyAndWriteSmallCrcPacket(const uint8_t* buf, size_t size) override;
}; };
@ -52,7 +52,7 @@ void CanTsChannel::start() {
void CanTsChannel::stop() { void CanTsChannel::stop() {
} }
void CanTsChannel::writeCrcPacket(const uint8_t* buf, size_t size, bool allowLongPackets) { void CanTsChannel::copyAndWriteSmallCrcPacket(const uint8_t* buf, size_t size) {
#ifdef TS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME #ifdef TS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME
// a special case for short packets: we can send them in 1 frame, without CRC & size, // a special case for short packets: we can send them in 1 frame, without CRC & size,
// because the CAN protocol is already protected by its own checksum. // because the CAN protocol is already protected by its own checksum.
@ -68,7 +68,7 @@ void CanTsChannel::writeCrcPacket(const uint8_t* buf, size_t size, bool allowLon
#endif /* TS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME */ #endif /* TS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME */
// Packet too large, use default implementation // Packet too large, use default implementation
TsChannelBase::writeCrcPacket(buf, size, allowLongPackets); TsChannelBase::copyAndWriteSmallCrcPacket(buf, size);
} }
void CanTsChannel::write(const uint8_t* buffer, size_t size, bool) { void CanTsChannel::write(const uint8_t* buffer, size_t size, bool) {

View File

@ -125,6 +125,8 @@ static void sendOkResponse(TsChannelBase *tsChannel) {
} }
void sendErrorCode(TsChannelBase *tsChannel, uint8_t code) { void sendErrorCode(TsChannelBase *tsChannel, uint8_t code) {
efiPrintf("TS <- Err: %d", code);
tsChannel->writeCrcResponse(code); tsChannel->writeCrcResponse(code);
} }
@ -135,6 +137,8 @@ void TunerStudio::sendErrorCode(TsChannelBase* tsChannel, uint8_t code) {
void TunerStudio::handlePageSelectCommand(TsChannelBase *tsChannel) { void TunerStudio::handlePageSelectCommand(TsChannelBase *tsChannel) {
tsState.pageCommandCounter++; tsState.pageCommandCounter++;
efiPrintf("TS -> Set page (no-op)");
sendOkResponse(tsChannel); sendOkResponse(tsChannel);
} }
@ -154,7 +158,7 @@ void TunerStudio::handleWriteChunkCommand(TsChannelBase* tsChannel, uint16_t off
return; return;
} }
efiPrintf("WRITE CHUNK o=%d s=%d", offset, count); efiPrintf("TS -> Write chunk offset %d count %d", offset, count);
if (validateOffsetCount(offset, count, tsChannel)) { if (validateOffsetCount(offset, count, tsChannel)) {
return; return;
@ -183,8 +187,11 @@ void TunerStudio::handleCrc32Check(TsChannelBase *tsChannel, uint16_t offset, ui
const uint8_t* start = getWorkingPageAddr() + offset; const uint8_t* start = getWorkingPageAddr() + offset;
uint32_t crc = SWAP_UINT32(crc32(start, count)); uint32_t crc = crc32(start, count);
tsChannel->writeCrcPacket((const uint8_t *) &crc, 4); efiPrintf("TS <- Get CRC offset %d count %d result %08x", offset, count, crc);
crc = SWAP_UINT32(crc);
tsChannel->copyAndWriteSmallCrcPacket((const uint8_t *) &crc, sizeof(crc));
} }
/** /**
@ -192,15 +199,13 @@ void TunerStudio::handleCrc32Check(TsChannelBase *tsChannel, uint16_t offset, ui
* @note Writing values one by one is pretty slow * @note Writing values one by one is pretty slow
*/ */
void TunerStudio::handleWriteValueCommand(TsChannelBase* tsChannel, uint16_t offset, uint8_t value) { void TunerStudio::handleWriteValueCommand(TsChannelBase* tsChannel, uint16_t offset, uint8_t value) {
UNUSED(tsChannel);
tsState.writeValueCommandCounter++; tsState.writeValueCommandCounter++;
if (isLockedFromUser()) { if (isLockedFromUser()) {
sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND); sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND);
return; return;
} }
tunerStudioDebug(tsChannel, "got W (Write)"); // we can get a lot of these efiPrintf("TS -> Write value offset %d value %d", offset, value);
if (validateOffsetCount(offset, 1, tsChannel)) { if (validateOffsetCount(offset, 1, tsChannel)) {
return; return;
@ -222,9 +227,7 @@ void TunerStudio::handlePageReadCommand(TsChannelBase* tsChannel, uint16_t offse
return; return;
} }
#if EFI_TUNER_STUDIO_VERBOSE efiPrintf("TS <- Read chunk offset %d count %d", offset, count);
efiPrintf("READ offset=%d size=%d", offset, count);
#endif
if (validateOffsetCount(offset, count, tsChannel)) { if (validateOffsetCount(offset, count, tsChannel)) {
return; return;
@ -233,15 +236,12 @@ void TunerStudio::handlePageReadCommand(TsChannelBase* tsChannel, uint16_t offse
uint8_t* addr; uint8_t* addr;
if (isLockedFromUser()) { if (isLockedFromUser()) {
// to have rusEFI console happy just send all zeros within a valid packet // to have rusEFI console happy just send all zeros within a valid packet
addr = (uint8_t*)&tsChannel->scratchBuffer + SCRATCH_BUFFER_PREFIX_SIZE; addr = (uint8_t*)&tsChannel->scratchBuffer;
memset(addr, 0, count); memset(addr, 0, count);
} else { } else {
addr = getWorkingPageAddr() + offset; addr = getWorkingPageAddr() + offset;
} }
tsChannel->writeCrcPacket(addr, count); tsChannel->writeCrcPacketLocked(addr, count);
#if EFI_TUNER_STUDIO_VERBOSE
// efiPrintf("Sending %d done", count);
#endif
} }
#endif // EFI_TUNER_STUDIO #endif // EFI_TUNER_STUDIO
@ -265,7 +265,7 @@ static void handleBurnCommand(TsChannelBase* tsChannel) {
tsState.burnCommandCounter++; tsState.burnCommandCounter++;
efiPrintf("got B (Burn)"); efiPrintf("TS -> Burn");
// Skip the burn if a preset was just loaded - we don't want to overwrite it // Skip the burn if a preset was just loaded - we don't want to overwrite it
if (!rebootForPresetPending) { if (!rebootForPresetPending) {
@ -273,7 +273,7 @@ static void handleBurnCommand(TsChannelBase* tsChannel) {
} }
tsChannel->writeCrcResponse(TS_RESPONSE_BURN_OK); tsChannel->writeCrcResponse(TS_RESPONSE_BURN_OK);
efiPrintf("BURN in %dms", (int)(t.getElapsedSeconds() * 1e3)); efiPrintf("Burned in %.1fms", t.getElapsedSeconds() * 1e3);
} }
#if EFI_TUNER_STUDIO && (EFI_PROD_CODE || EFI_SIMULATOR) #if EFI_TUNER_STUDIO && (EFI_PROD_CODE || EFI_SIMULATOR)
@ -293,36 +293,6 @@ static bool isKnownCommand(char command) {
|| command == TS_QUERY_BOOTLOADER; || command == TS_QUERY_BOOTLOADER;
} }
/**
* rusEfi own test command
*/
static void handleTestCommand(TsChannelBase* tsChannel) {
tsState.testCommandCounter++;
char testOutputBuffer[64];
/**
* this is NOT a standard TunerStudio command, this is my own
* extension of the protocol to simplify troubleshooting
*/
tunerStudioDebug(tsChannel, "got T (Test)");
tsChannel->write((const uint8_t*)GIT_HASH_SHORT, sizeof(GIT_HASH_SHORT));
chsnprintf(testOutputBuffer, sizeof(testOutputBuffer), " %d %d", engine->engineState.warnings.lastErrorCode, tsState.testCommandCounter);
tsChannel->write((const uint8_t*)testOutputBuffer, strlen(testOutputBuffer));
chsnprintf(testOutputBuffer, sizeof(testOutputBuffer), " uptime=%ds ", (int)getTimeNowS());
tsChannel->write((const uint8_t*)testOutputBuffer, strlen(testOutputBuffer));
chsnprintf(testOutputBuffer, sizeof(testOutputBuffer), __DATE__ " %s\r\n", PROTOCOL_TEST_RESPONSE_TAG);
tsChannel->write((const uint8_t*)testOutputBuffer, strlen(testOutputBuffer));
if (hasFirmwareError()) {
const char* error = getCriticalErrorMessage();
chsnprintf(testOutputBuffer, sizeof(testOutputBuffer), "error=%s\r\n", error);
tsChannel->write((const uint8_t*)testOutputBuffer, strlen(testOutputBuffer));
}
tsChannel->flush();
}
/** /**
* this command is part of protocol initialization * this command is part of protocol initialization
* *
@ -331,17 +301,17 @@ static void handleTestCommand(TsChannelBase* tsChannel) {
*/ */
void TunerStudio::handleQueryCommand(TsChannelBase* tsChannel, ts_response_format_e mode) { void TunerStudio::handleQueryCommand(TsChannelBase* tsChannel, ts_response_format_e mode) {
tsState.queryCommandCounter++; tsState.queryCommandCounter++;
#if EFI_TUNER_STUDIO_VERBOSE
efiPrintf("got S/H (queryCommand) mode=%d", mode);
printErrorCounters();
#endif
const char *signature = getTsSignature(); const char *signature = getTsSignature();
efiPrintf("TS <- Query signature: %s", signature);
printErrorCounters();
auto buffer = (const uint8_t *)signature; auto buffer = (const uint8_t *)signature;
size_t size = strlen(signature) + 1; size_t size = strlen(signature) + 1;
if (mode == TS_CRC) { if (mode == TS_CRC) {
tsChannel->writeCrcPacket(buffer, size); tsChannel->copyAndWriteSmallCrcPacket(buffer, size);
} else { } else {
tsChannel->write(buffer, size, true); tsChannel->write(buffer, size, true);
tsChannel->flush(); tsChannel->flush();
@ -359,12 +329,8 @@ bool TunerStudio::handlePlainCommand(TsChannelBase* tsChannel, uint8_t command)
return false; return false;
} else if (command == TS_HELLO_COMMAND || command == TS_QUERY_COMMAND) { } else if (command == TS_HELLO_COMMAND || command == TS_QUERY_COMMAND) {
// We interpret 'Q' as TS_HELLO_COMMAND, since TS uses hardcoded 'Q' during ECU detection (scan all serial ports) // We interpret 'Q' as TS_HELLO_COMMAND, since TS uses hardcoded 'Q' during ECU detection (scan all serial ports)
efiPrintf("Got naked Query command");
handleQueryCommand(tsChannel, TS_PLAIN); handleQueryCommand(tsChannel, TS_PLAIN);
return true; return true;
} else if (command == TS_TEST_COMMAND || command == 'T') {
handleTestCommand(tsChannel);
return true;
} else if (command == TS_COMMAND_F) { } else if (command == TS_COMMAND_F) {
/** /**
* http://www.msextra.com/forums/viewtopic.php?f=122&t=48327 * http://www.msextra.com/forums/viewtopic.php?f=122&t=48327
@ -554,7 +520,7 @@ extern CommandHandler console_line_callback;
static void handleGetVersion(TsChannelBase* tsChannel) { static void handleGetVersion(TsChannelBase* tsChannel) {
char versionBuffer[32]; char versionBuffer[32];
chsnprintf(versionBuffer, sizeof(versionBuffer), "FOME " QUOTE(SHORT_BOARD_NAME) " %d@" GIT_HASH_SHORT, getRusEfiVersion()); chsnprintf(versionBuffer, sizeof(versionBuffer), "FOME " QUOTE(SHORT_BOARD_NAME) " %d@" GIT_HASH_SHORT, getRusEfiVersion());
tsChannel->writeCrcPacket((const uint8_t *) versionBuffer, strlen(versionBuffer) + 1); tsChannel->copyAndWriteSmallCrcPacket((const uint8_t *) versionBuffer, strlen(versionBuffer) + 1);
} }
#if EFI_TEXT_LOGGING #if EFI_TEXT_LOGGING
@ -569,7 +535,7 @@ static void handleGetText(TsChannelBase* tsChannel) {
logMsg("get test sending [%d]\r\n", outputSize); logMsg("get test sending [%d]\r\n", outputSize);
#endif #endif
tsChannel->writeCrcPacket(reinterpret_cast<const uint8_t*>(output), outputSize, true); tsChannel->writeCrcPacketLocked(reinterpret_cast<const uint8_t*>(output), outputSize);
#if EFI_SIMULATOR #if EFI_SIMULATOR
logMsg("sent [%d]\r\n", outputSize); logMsg("sent [%d]\r\n", outputSize);
#endif #endif
@ -610,7 +576,6 @@ int TunerStudio::handleCrcCommand(TsChannelBase* tsChannel, uint8_t* data, int i
cmdOutputChannels(tsChannel, offset, count); cmdOutputChannels(tsChannel, offset, count);
break; break;
case TS_HELLO_COMMAND: case TS_HELLO_COMMAND:
tunerStudioDebug(tsChannel, "got Query command");
handleQueryCommand(tsChannel, TS_CRC); handleQueryCommand(tsChannel, TS_CRC);
break; break;
case TS_GET_FIRMWARE_VERSION: case TS_GET_FIRMWARE_VERSION:
@ -645,11 +610,6 @@ int TunerStudio::handleCrcCommand(TsChannelBase* tsChannel, uint8_t* data, int i
case TS_READ_COMMAND: case TS_READ_COMMAND:
handlePageReadCommand(tsChannel, offset, count); handlePageReadCommand(tsChannel, offset, count);
break; break;
case TS_TEST_COMMAND:
[[fallthrough]];
case 'T':
handleTestCommand(tsChannel);
break;
case TS_IO_TEST_COMMAND: case TS_IO_TEST_COMMAND:
{ {
uint16_t subsystem = SWAP_UINT16(data16[0]); uint16_t subsystem = SWAP_UINT16(data16[0]);
@ -675,7 +635,7 @@ int TunerStudio::handleCrcCommand(TsChannelBase* tsChannel, uint8_t* data, int i
auto toothBuffer = GetToothLoggerBufferNonblocking(); auto toothBuffer = GetToothLoggerBufferNonblocking();
if (toothBuffer) { if (toothBuffer) {
tsChannel->writeCrcPacket(reinterpret_cast<const uint8_t*>(toothBuffer->buffer), toothBuffer->nextIdx * sizeof(composite_logger_s), true); tsChannel->writeCrcPacketLocked(reinterpret_cast<const uint8_t*>(toothBuffer->buffer), toothBuffer->nextIdx * sizeof(composite_logger_s));
ReturnToothLoggerBuffer(toothBuffer); ReturnToothLoggerBuffer(toothBuffer);
} else { } else {
@ -696,7 +656,7 @@ int TunerStudio::handleCrcCommand(TsChannelBase* tsChannel, uint8_t* data, int i
const auto& buffer = triggerScopeGetBuffer(); const auto& buffer = triggerScopeGetBuffer();
if (buffer) { if (buffer) {
tsChannel->writeCrcPacket(buffer.get<uint8_t>(), buffer.size(), true); tsChannel->writeCrcPacketLocked(buffer.get<uint8_t>(), buffer.size());
} else { } else {
// TS asked for a tooth logger buffer, but we don't have one to give it. // TS asked for a tooth logger buffer, but we don't have one to give it.
sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE); sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE);
@ -721,14 +681,14 @@ int TunerStudio::handleCrcCommand(TsChannelBase* tsChannel, uint8_t* data, int i
case TS_PERF_TRACE_GET_BUFFER: case TS_PERF_TRACE_GET_BUFFER:
{ {
auto trace = perfTraceGetBuffer(); auto trace = perfTraceGetBuffer();
tsChannel->writeCrcPacket(trace.get<uint8_t>(), trace.size(), true); tsChannel->writeCrcPacketLocked(trace.get<uint8_t>(), trace.size());
} }
break; break;
#endif /* ENABLE_PERF_TRACE */ #endif /* ENABLE_PERF_TRACE */
case TS_GET_CONFIG_ERROR: { case TS_GET_CONFIG_ERROR: {
const char* configError = getCriticalErrorMessage(); const char* configError = getCriticalErrorMessage();
tsChannel->writeCrcPacket(reinterpret_cast<const uint8_t*>(configError), strlen(configError), true); tsChannel->writeCrcPacketLocked(reinterpret_cast<const uint8_t*>(configError), strlen(configError));
break; break;
} }
case TS_QUERY_BOOTLOADER: { case TS_QUERY_BOOTLOADER: {
@ -737,7 +697,7 @@ int TunerStudio::handleCrcCommand(TsChannelBase* tsChannel, uint8_t* data, int i
bldata = TS_QUERY_BOOTLOADER_OPENBLT; bldata = TS_QUERY_BOOTLOADER_OPENBLT;
#endif #endif
tsChannel->writeCrcPacket(&bldata, 1, false); tsChannel->copyAndWriteSmallCrcPacket(&bldata, 1);
break; break;
} }
default: default:

View File

@ -56,15 +56,15 @@ void TunerStudio::cmdOutputChannels(TsChannelBase* tsChannel, uint16_t offset, u
tsState.outputChannelsCommandCounter++; tsState.outputChannelsCommandCounter++;
updateTunerStudioState(); updateTunerStudioState();
tsChannel->assertPacketSize(count, false);
// this method is invoked too often to print any debug information // this method is invoked too often to print any debug information
uint8_t * scratchBuffer = (uint8_t *)tsChannel->scratchBuffer; uint8_t * scratchBuffer = (uint8_t *)tsChannel->scratchBuffer;
/** /**
* collect data from all models * collect data from all models
*/ */
copyRange(scratchBuffer + 3, getLiveDataFragments(), offset, count); copyRange(scratchBuffer, getLiveDataFragments(), offset, count);
tsChannel->crcAndWriteBuffer(TS_RESPONSE_OK, count); tsChannel->writeCrcPacketLocked(TS_RESPONSE_OK, scratchBuffer, count);
} }
#endif // EFI_TUNER_STUDIO #endif // EFI_TUNER_STUDIO

View File

@ -21,7 +21,7 @@ size_t TsChannelBase::read(uint8_t* buffer, size_t size) {
#define isBigPacket(size) ((size) > BLOCKING_FACTOR + 7) #define isBigPacket(size) ((size) > BLOCKING_FACTOR + 7)
void TsChannelBase::copyAndWriteSmallCrcPacket(uint8_t responseCode, const uint8_t* buf, size_t size) { void TsChannelBase::copyAndWriteSmallCrcPacket(const uint8_t* buf, size_t size) {
// don't transmit too large a buffer // don't transmit too large a buffer
efiAssertVoid(ObdCode::OBD_PCM_Processor_Fault, !isBigPacket(size), "copyAndWriteSmallCrcPacket tried to transmit too large a packet") efiAssertVoid(ObdCode::OBD_PCM_Processor_Fault, !isBigPacket(size), "copyAndWriteSmallCrcPacket tried to transmit too large a packet")
@ -30,57 +30,33 @@ void TsChannelBase::copyAndWriteSmallCrcPacket(uint8_t responseCode, const uint8
// tsOutputChannels) during the CRC computation. Instead compute the CRC on our // tsOutputChannels) during the CRC computation. Instead compute the CRC on our
// local buffer that nobody else will write. // local buffer that nobody else will write.
if (size) { if (size) {
memcpy(scratchBuffer + SCRATCH_BUFFER_PREFIX_SIZE, buf, size); memcpy(scratchBuffer, buf, size);
} }
crcAndWriteBuffer(responseCode, size); writeCrcPacketLocked(TS_RESPONSE_OK, &scratchBuffer[0], size);
} }
void TsChannelBase::crcAndWriteBuffer(uint8_t responseCode, size_t size) { void TsChannelBase::writeCrcPacketLocked(const uint8_t responseCode, const uint8_t* buf, const size_t size) {
efiAssertVoid(ObdCode::OBD_PCM_Processor_Fault, !isBigPacket(size), "crcAndWriteBuffer tried to transmit too large a packet")
// Index 0/1 = packet size (big endian)
*(uint16_t*)scratchBuffer = SWAP_UINT16(size + 1);
// Index 2 = response code
scratchBuffer[2] = responseCode;
// CRC is computed on the responseCode and payload but not length
uint32_t crc = crc32(&scratchBuffer[2], size + 1); // command part of CRC
// Place the CRC at the end
crc = SWAP_UINT32(crc);
memcpy(scratchBuffer + size + SCRATCH_BUFFER_PREFIX_SIZE, &crc, sizeof(crc));
// Write to the underlying stream
write(reinterpret_cast<uint8_t*>(scratchBuffer), size + 7, true);
flush();
}
uint32_t TsChannelBase::writePacketHeader(const uint8_t responseCode, const size_t size) {
uint8_t headerBuffer[3]; uint8_t headerBuffer[3];
*(uint16_t*)headerBuffer = SWAP_UINT16(size + 1); *(uint16_t*)headerBuffer = SWAP_UINT16(size + 1);
*(uint8_t*)(headerBuffer + 2) = responseCode; *(uint8_t*)(headerBuffer + 2) = responseCode;
// Write header // Write header
write(headerBuffer, sizeof(headerBuffer), /*isEndOfPacket*/false); write(headerBuffer, sizeof(headerBuffer), /*isEndOfPacket*/false);
// Command part of CRC
return crc32((void*)(headerBuffer + 2), 1);
}
void TsChannelBase::writeCrcPacketLarge(const uint8_t responseCode, const uint8_t* buf, const size_t size) {
uint8_t crcBuffer[4];
// Command part of CRC
uint32_t crc = writePacketHeader(responseCode, size);
// Data part of CRC
crc = crc32inc((void*)buf, crc, size);
*(uint32_t*)crcBuffer = SWAP_UINT32(crc);
// If data, write that // If data, write that
if (size) { if (size) {
write(buf, size, /*isEndOfPacket*/false); write(buf, size, /*isEndOfPacket*/false);
} }
// Command part of CRC
uint32_t crc = crc32((void*)(headerBuffer + 2), 1);
// Data part of CRC
crc = crc32inc((void*)buf, crc, size);
uint8_t crcBuffer[4];
*(uint32_t*)crcBuffer = SWAP_UINT32(crc);
// Lastly the CRC footer // Lastly the CRC footer
write(crcBuffer, sizeof(crcBuffer), /*isEndOfPacket*/true); write(crcBuffer, sizeof(crcBuffer), /*isEndOfPacket*/true);
flush(); flush();
@ -90,29 +66,3 @@ TsChannelBase::TsChannelBase(const char *name)
: m_name(name) : m_name(name)
{ {
} }
void TsChannelBase::assertPacketSize(size_t size, bool allowLongPackets) {
if (isBigPacket(size) && !allowLongPackets) {
firmwareError(ObdCode::OBD_PCM_Processor_Fault, "[USE PROPER CONSOLE VERSION ] disallowed long packet of size %d", size);
}
}
/**
* Adds size to the beginning of a packet and a crc32 at the end. Then send the packet.
*/
void TsChannelBase::writeCrcPacket(const uint8_t* buf, size_t size, bool allowLongPackets) {
// don't transmit a null buffer...
if (!buf) {
size = 0;
}
assertPacketSize(size, allowLongPackets);
if (isBigPacket(size)) {
// for larger packets we do not use a buffer for CRC calculation meaning data is now allowed to modify while pending
writeCrcPacketLarge(TS_RESPONSE_OK, buf, size);
} else {
// for small packets we use a buffer for CRC calculation
copyAndWriteSmallCrcPacket(TS_RESPONSE_OK, buf, size);
}
}

View File

@ -36,11 +36,6 @@ public:
// Base functions that use the above virtual implementation // Base functions that use the above virtual implementation
size_t read(uint8_t* buffer, size_t size); size_t read(uint8_t* buffer, size_t size);
#ifdef EFI_CAN_SERIAL
virtual // CAN device needs this function to be virtual for small-packet optimization
#endif
void writeCrcPacket(const uint8_t* buf, size_t size, bool allowLongPackets = false);
/** /**
* See 'blockingFactor' in rusefi.ini * See 'blockingFactor' in rusefi.ini
*/ */
@ -50,14 +45,21 @@ public:
return m_name; return m_name;
} }
void assertPacketSize(size_t size, bool allowLongPackets); #ifdef EFI_CAN_SERIAL
uint32_t writePacketHeader(const uint8_t responseCode, const size_t size); virtual // CAN device needs this function to be virtual for small-packet optimization
void crcAndWriteBuffer(const uint8_t responseCode, const size_t size); #endif
void copyAndWriteSmallCrcPacket(uint8_t responseCode, const uint8_t* buf, size_t size); // Use when buf could change during execution. Makes a copy before computing checksum.
void copyAndWriteSmallCrcPacket(const uint8_t* buf, size_t size);
// Use when buf cannot change during execution. Computes checksum without an extra copy.
void writeCrcPacketLocked(uint8_t responseCode, const uint8_t* buf, size_t size);
inline void writeCrcPacketLocked(const uint8_t* buf, size_t size) {
writeCrcPacketLocked(TS_RESPONSE_OK, buf, size);
}
// Write a response code with no data // Write a response code with no data
void writeCrcResponse(uint8_t responseCode) { inline void writeCrcResponse(uint8_t responseCode) {
writeCrcPacketLarge(responseCode, nullptr, 0); writeCrcPacketLocked(responseCode, nullptr, 0);
} }
/* When TsChannel is in "not in sync" state tsProcessOne will silently try to find /* When TsChannel is in "not in sync" state tsProcessOne will silently try to find
@ -74,9 +76,6 @@ public:
protected: protected:
const char * const m_name; const char * const m_name;
private:
void writeCrcPacketLarge(uint8_t responseCode, const uint8_t* buf, size_t size);
}; };
// This class represents a channel for a physical async serial poart // This class represents a channel for a physical async serial poart

View File

@ -86,7 +86,7 @@
! so not forget to change fileVersion in rusefi.ini ! so not forget to change fileVersion in rusefi.ini
! todo: this not needed in light of TS_SIGNATURE but rusEFI console still uses it. Need to migrate ! todo: this not needed in light of TS_SIGNATURE but rusEFI console still uses it. Need to migrate
! rusEFI console from TS_FILE_VERSION to TS_SIGNATURE :( ! rusEFI console from TS_FILE_VERSION to TS_SIGNATURE :(
#define TS_FILE_VERSION 20210312 #define TS_FILE_VERSION 20240610
! This is the version of the data stored in flash configuration ! This is the version of the data stored in flash configuration
! Any time an incompatible change is made to the configuration format stored in flash, ! Any time an incompatible change is made to the configuration format stored in flash,
@ -1893,10 +1893,6 @@ end_struct
! Engine Sniffer time stamp unit, in microseconds ! Engine Sniffer time stamp unit, in microseconds
#define ENGINE_SNIFFER_UNIT_US 10 #define ENGINE_SNIFFER_UNIT_US 10
! These commands are used exclusively by the FOME console
! 0x74
#define TS_TEST_COMMAND 't'
! High speed logger commands ! High speed logger commands
#define TS_SET_LOGGER_SWITCH 'l' #define TS_SET_LOGGER_SWITCH 'l'

View File

@ -50,19 +50,14 @@ static void assertCrcPacket(BufferTsChannel& dut) {
TEST(binary, testWriteCrc) { TEST(binary, testWriteCrc) {
BufferTsChannel test; BufferTsChannel test;
// Let it pick which impl (small vs large) to use // Small impl
test.reset(); test.reset();
test.writeCrcPacket((const uint8_t*)PAYLOAD, SIZE); test.copyAndWriteSmallCrcPacket((const uint8_t*)PAYLOAD, SIZE);
assertCrcPacket(test); assertCrcPacket(test);
// Force the large impl // Large impl
test.reset(); test.reset();
test.writeCrcPacket((const uint8_t*)PAYLOAD, SIZE); test.writeCrcPacketLocked((const uint8_t*)PAYLOAD, SIZE);
assertCrcPacket(test);
// Force the small impl
test.reset();
test.writeCrcPacket((const uint8_t*)PAYLOAD, SIZE);
assertCrcPacket(test); assertCrcPacket(test);
} }