From 6d8cfb8f30a273cda93ba150407e364839b3fa34 Mon Sep 17 00:00:00 2001 From: "David J. Fiddes" Date: Thu, 2 Oct 2025 19:06:19 +0100 Subject: [PATCH] Fix CAN SDO print timeout The class needs to be properly initialised as the TriggerTimeout() method will likely be called before any incoming SDO frames. On the VCU I observed unitialised member variables being filled with garbage from the stack painting. The previous TriggerTimeout() logic causes timeouts even when no timeout period has elapsed. This corrupts the parameter database download. Overshooting and setting to zero if required seems to work reliably. I don't understand. Tests: - Repeatedly start a db download, abort and immediate retry. This should fail and it does. - Repeatedly start a db download, abort and wait a few seconds to retry. This should succeed and it does. - Use callingFrequency values of 97 and 103 to force over and undershoots. Verify the timeout behaviour works as expected. --- src/cansdo.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/cansdo.cpp b/src/cansdo.cpp index df3846d..c00ca82 100644 --- a/src/cansdo.cpp +++ b/src/cansdo.cpp @@ -41,7 +41,10 @@ * */ CanSdo::CanSdo(CanHardware* hw, CanMap* cm) - : canHardware(hw), canMap(cm), nodeId(1), remoteNodeId(255), printRequest(-1) + : canHardware(hw), canMap(cm), nodeId(1), remoteNodeId(255), printRequest(-1), + printByteIn(0), printByteOut(sizeof(printBuffer)), printTimeout(PRINT_TIMEOUT), + mapParam(Param::PARAM_INVALID), mapId(0), sdoReplyValid(false), sdoReplyData(0), + pendingUserSpaceSdo(false) { canHardware->AddCallback(this); HandleClear(); @@ -213,11 +216,14 @@ void CanSdo::ProcessSDO(uint32_t data[2]) */ void CanSdo::TriggerTimeout(int callingFrequency) { - if (printTimeout == 0) return; - if (callingFrequency >= printTimeout) + if (printTimeout > 0) + { printTimeout -= callingFrequency; - else + } + if (printTimeout < 0) + { printTimeout = 0; + } } void CanSdo::PutChar(char c)