Skip to content

Commit

Permalink
Bug fixes for builds with only one file channel
Browse files Browse the repository at this point in the history
  • Loading branch information
chrishamm committed Feb 20, 2024
1 parent b1ef5cc commit 610b53a
Showing 1 changed file with 132 additions and 53 deletions.
185 changes: 132 additions & 53 deletions src/SBC/SbcInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,65 +235,78 @@ void SbcInterface::ExchangeData() noexcept

const CodeHeader *code = reinterpret_cast<const CodeHeader*>(transfer.ReadData(packet->length));
const GCodeChannel channel(code->channel);
GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
if (gb->IsInvalidated())
if (channel.IsValid())
{
// Don't deal with codes that will be thrown away
break;
}
GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
if (gb == nullptr)
{
REPORT_INTERNAL_ERROR;
break;
}

// Check if a GB is waiting for a macro file to be started
if (gb->IsWaitingForMacro() && !gb->IsMacroRequestPending())
{
gb->ResolveMacroRequest(false, false);
#ifdef TRACK_FILE_CODES
if (channel == GCodeChannel::File || channel == GCodeChannel::File2)
if (gb->IsInvalidated())
{
fileMacrosRunning++;
// Don't deal with codes that will be thrown away
break;
}

// Check if a GB is waiting for a macro file to be started
if (gb->IsWaitingForMacro() && !gb->IsMacroRequestPending())
{
gb->ResolveMacroRequest(false, false);
#ifdef TRACK_FILE_CODES
if (gb->IsFileChannel())
{
fileMacrosRunning++;
}
#endif
}
}

// Don't process any more codes if we failed to store them last time...
if (!codeBufferAvailable)
{
packetAcknowledged = false;
break;
}
// Don't process any more codes if we failed to store them last time...
if (!codeBufferAvailable)
{
packetAcknowledged = false;
break;
}

TaskCriticalSectionLocker locker;
TaskCriticalSectionLocker locker;

// Make sure no existing codes are overwritten
uint16_t bufferedCodeSize = sizeof(BufferedCodeHeader) + packet->length;
if ((txEnd == 0 && bufferedCodeSize > max<uint16_t>(rxPointer, SpiCodeBufferSize - txPointer)) ||
(txEnd != 0 && bufferedCodeSize > rxPointer - txPointer))
{
// Make sure no existing codes are overwritten
uint16_t bufferedCodeSize = sizeof(BufferedCodeHeader) + packet->length;
if ((txEnd == 0 && bufferedCodeSize > max<uint16_t>(rxPointer, SpiCodeBufferSize - txPointer)) ||
(txEnd != 0 && bufferedCodeSize > rxPointer - txPointer))
{
#if false
// This isn't enabled because the debug call plus critical section would lead to software resets
debugPrintf("Failed to store code, RX/TX %d/%d-%d\n", rxPointer, txPointer, txEnd);
// This isn't enabled because the debug call plus critical section would lead to software resets
debugPrintf("Failed to store code, RX/TX %d/%d-%d\n", rxPointer, txPointer, txEnd);
#endif
packetAcknowledged = codeBufferAvailable = false;
break;
}
packetAcknowledged = codeBufferAvailable = false;
break;
}

// Overlap if necessary
if (txPointer + bufferedCodeSize > SpiCodeBufferSize)
{
txEnd = txPointer;
txPointer = 0;
}

// Store the buffer header
BufferedCodeHeader *bufHeader = reinterpret_cast<BufferedCodeHeader *>(codeBuffer + txPointer);
bufHeader->isPending = true;
bufHeader->length = packet->length;

// Overlap if necessary
if (txPointer + bufferedCodeSize > SpiCodeBufferSize)
// Store the corresponding code. Binary codes are always aligned on a 4-byte boundary
uint32_t *dst = reinterpret_cast<uint32_t *>(codeBuffer + txPointer + sizeof(BufferedCodeHeader));
const uint32_t *src = reinterpret_cast<const uint32_t *>(code);
memcpyu32(dst, src, packet->length / sizeof(uint32_t));
txPointer += bufferedCodeSize;
sendBufferUpdate = true;
}
else
{
txEnd = txPointer;
txPointer = 0;
REPORT_INTERNAL_ERROR;
}

// Store the buffer header
BufferedCodeHeader *bufHeader = reinterpret_cast<BufferedCodeHeader *>(codeBuffer + txPointer);
bufHeader->isPending = true;
bufHeader->length = packet->length;

// Store the corresponding code. Binary codes are always aligned on a 4-byte boundary
uint32_t *dst = reinterpret_cast<uint32_t *>(codeBuffer + txPointer + sizeof(BufferedCodeHeader));
const uint32_t *src = reinterpret_cast<const uint32_t *>(code);
memcpyu32(dst, src, packet->length / sizeof(uint32_t));
txPointer += bufferedCodeSize;
sendBufferUpdate = true;
break;
}

Expand Down Expand Up @@ -379,19 +392,27 @@ void SbcInterface::ExchangeData() noexcept
// Stop the print with the given reason
printAborted = true;
InvalidateBufferedCodes(GCodeChannel::File);
#if SUPPORT_ASYNC_MOVES
InvalidateBufferedCodes(GCodeChannel::File2);
#endif
}
else
{
// Just mark the print files as finished
GCodeBuffer * const fileGb = reprap.GetGCodes().GetGCodeBuffer(GCodeChannel::File);
GCodeBuffer * const file2Gb = reprap.GetGCodes().GetGCodeBuffer(GCodeChannel::File2);
MutexLocker fileLocker(fileGb->mutex, SbcYieldTimeout);
#if SUPPORT_ASYNC_MOVES
GCodeBuffer * const file2Gb = reprap.GetGCodes().GetGCodeBuffer(GCodeChannel::File2);
MutexLocker file2Locker(file2Gb->mutex, SbcYieldTimeout);
if (fileLocker.IsAcquired() && file2Locker.IsAcquired())
#else
if (fileLocker.IsAcquired())
#endif
{
fileGb->SetPrintFinished();
#if SUPPORT_ASYNC_MOVES
file2Gb->SetPrintFinished();
#endif
}
else
{
Expand All @@ -409,6 +430,12 @@ void SbcInterface::ExchangeData() noexcept
if (channel.IsValid())
{
GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
if (gb == nullptr)
{
REPORT_INTERNAL_ERROR;
break;
}

if (gb->IsWaitingForMacro() && !gb->IsMacroRequestPending())
{
gb->ResolveMacroRequest(error, true);
Expand All @@ -431,7 +458,7 @@ void SbcInterface::ExchangeData() noexcept
else
{
#ifdef TRACK_FILE_CODES
if (channel == GCodeChannel::File || channel == GCodeChannel::File2)
if (gb->IsFileChannel())
{
fileMacrosClosing++;
}
Expand Down Expand Up @@ -464,6 +491,12 @@ void SbcInterface::ExchangeData() noexcept
if (channel.IsValid())
{
GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
if (gb == nullptr)
{
REPORT_INTERNAL_ERROR;
break;
}

MutexLocker locker(gb->mutex, SbcYieldTimeout);
if (locker.IsAcquired() && reprap.GetGCodes().LockAllMovementSystemsAndWaitForStandstill(*gb))
{
Expand All @@ -488,6 +521,12 @@ void SbcInterface::ExchangeData() noexcept
if (channel.IsValid())
{
GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
if (gb == nullptr)
{
REPORT_INTERNAL_ERROR;
break;
}

MutexLocker locker(gb->mutex, SbcYieldTimeout);
if (locker.IsAcquired())
{
Expand Down Expand Up @@ -532,13 +571,18 @@ void SbcInterface::ExchangeData() noexcept
if (channel.IsValid())
{
GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
if (gb == nullptr)
{
REPORT_INTERNAL_ERROR;
break;
}

// If there is a macro file waiting, the first instruction must be conditional. Don't block any longer...
if (gb->IsWaitingForMacro())
{
gb->ResolveMacroRequest(false, false);
#ifdef TRACK_FILE_CODES
if (channel == GCodeChannel::File || channel == GCodeChannel::File2)
if (gb->IsFileChannel())
{
fileMacrosRunning++;
}
Expand Down Expand Up @@ -624,12 +668,18 @@ void SbcInterface::ExchangeData() noexcept
if (channel.IsValid())
{
GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
if (gb == nullptr)
{
REPORT_INTERNAL_ERROR;
break;
}

if (gb->IsWaitingForMacro() && !gb->IsMacroRequestPending())
{
// File exists and is open, but no code has arrived yet
gb->ResolveMacroRequest(false, false);
#ifdef TRACK_FILE_CODES
if (channel == GCodeChannel::File || channel == GCodeChannel::File2)
if (gb->IsFileChannel())
{
fileMacrosRunning++;
}
Expand Down Expand Up @@ -659,6 +709,12 @@ void SbcInterface::ExchangeData() noexcept
if (channel.IsValid())
{
GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
if (gb == nullptr)
{
REPORT_INTERNAL_ERROR;
break;
}

if (gb->IsWaitingForMacro())
{
gb->ResolveMacroRequest(true, false);
Expand Down Expand Up @@ -699,6 +755,12 @@ void SbcInterface::ExchangeData() noexcept
}

GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
if (gb == nullptr)
{
REPORT_INTERNAL_ERROR;
break;
}

MutexLocker lock(gb->mutex, SbcYieldTimeout);
if (!lock.IsAcquired())
{
Expand Down Expand Up @@ -858,6 +920,12 @@ void SbcInterface::ExchangeData() noexcept
}

GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
if (gb == nullptr)
{
REPORT_INTERNAL_ERROR;
break;
}

MutexLocker lock(gb->mutex, SbcYieldTimeout);
if (!lock.IsAcquired())
{
Expand Down Expand Up @@ -1088,6 +1156,11 @@ void SbcInterface::ExchangeData() noexcept
{
const GCodeChannel channel(i);
GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
if (gb == nullptr)
{
// Skip GBs that are not available due to the build configuration
continue;
}

// Invalidate buffered codes if required
if (gb->IsInvalidated())
Expand Down Expand Up @@ -1134,7 +1207,7 @@ void SbcInterface::ExchangeData() noexcept
if (gb->IsAbortRequested() && transfer.WriteAbortFileRequest(channel, gb->IsAbortAllRequested()))
{
#ifdef TRACK_FILE_CODES
if (channel == GCodeChannel::File || channel == GCodeChannel::File2)
if (gb->IsFileChannel())
{
if (gb->IsAbortAllRequested())
{
Expand Down Expand Up @@ -1286,7 +1359,13 @@ void SbcInterface::InvalidateResources() noexcept
// Close all open G-code files
for (size_t i = 0; i < NumGCodeChannels; i++)
{
GCodeBuffer *gb = reprap.GetGCodes().GetGCodeBuffer(GCodeChannel(i));
GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(GCodeChannel(i));
if (gb == nullptr)
{
// Skip GBs that are not available due to the build configuration
break;
}

if (gb->IsWaitingForMacro())
{
gb->ResolveMacroRequest(true, false);
Expand Down Expand Up @@ -1403,7 +1482,7 @@ bool SbcInterface::FillBuffer(GCodeBuffer &gb) noexcept
OutputBuffer *buf;
if (OutputBuffer::Allocate(buf))
{
String<SHORT_GCODE_LENGTH> codeString;
String<StringLength100> codeString;
gb.PrintCommand(codeString.GetRef());
buf->printf("Code %s did not return a code result, delta %d, running macros %d\n", codeString.c_str(), fileCodesRead - fileCodesHandled - fileMacrosRunning, fileMacrosRunning);
gcodeReply.Push(buf, WarningMessage);
Expand Down

0 comments on commit 610b53a

Please sign in to comment.