diff options
author | David Crocker <dcrocker@eschertech.com> | 2021-05-24 19:55:36 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2021-05-24 19:55:36 +0300 |
commit | 0dc6a333f2fd6f7156ec1b1586be5d7f01487faf (patch) | |
tree | 8ec8fa001fb23c707e52828c3e88dcdd2c2a1a7d | |
parent | c8fe0ca9e43438cd63bcbbe5833eda5ce35db220 (diff) |
Use a mutex in SendRequestAndGetStandardReply
Also initialise the step timer before starting the scheduler
Also clear packTimeSyncTxDelay after reporting it
-rw-r--r-- | src/CAN/CanInterface.cpp | 117 | ||||
-rw-r--r-- | src/Platform/Platform.cpp | 2 | ||||
-rw-r--r-- | src/Platform/Tasks.cpp | 1 |
3 files changed, 60 insertions, 60 deletions
diff --git a/src/CAN/CanInterface.cpp b/src/CAN/CanInterface.cpp index 5c0a4a96..3b0644fa 100644 --- a/src/CAN/CanInterface.cpp +++ b/src/CAN/CanInterface.cpp @@ -57,6 +57,8 @@ constexpr float DefaultJumpWidth = 0.25; constexpr const char *NoCanBufferMessage = "no CAN buffer available"; +static Mutex transactionMutex; + static uint32_t lastTimeSent = 0; static uint32_t longestWaitTime = 0; static uint16_t longestWaitMessageType = 0; @@ -220,6 +222,8 @@ void CanInterface::Init() noexcept CanMessageBuffer::Init(NumCanBuffers); pendingBuffers = nullptr; + transactionMutex.Create("CanTrans"); + #if SAME70 # ifdef USE_CAN0 SetPinFunction(APIN_CAN0_TX, CAN0PinPeriphMode); @@ -610,82 +614,78 @@ GCodeResult CanInterface::SendRequestAndGetCustomReply(CanMessageBuffer *buf, Ca const CanAddress dest = buf->id.Dst(); const CanMessageType msgType = buf->id.MsgType(); // save for possible error message - // This code isn't re-entrant, so check that we are the main task - if (TaskBase::GetCallerTaskHandle() != Tasks::GetMainTask()) { - reply.printf("SendReq call from wrong task type=%u dst=%u",(unsigned int)msgType, (unsigned int)dest); - reprap.GetPlatform().MessageF(ErrorMessage, "%s\n", reply.c_str()); // send it directly in case the caller discards the reply - CanMessageBuffer::Free(buf); - return GCodeResult::error; - } + // This code isn't re-entrant and it can get called from a task other than Main to shut the system down, so we need to use a mutex + MutexLocker lock(transactionMutex); - can0dev->SendMessage(TxBufferIndexRequest, MaxRequestSendWait, buf); - const uint32_t whenStartedWaiting = millis(); - unsigned int fragmentsReceived = 0; - for (;;) - { - const uint32_t timeWaiting = millis() - whenStartedWaiting; - if (!can0dev->ReceiveMessage(RxBufferIndexResponse, CanResponseTimeout - timeWaiting, buf)) + can0dev->SendMessage(TxBufferIndexRequest, MaxRequestSendWait, buf); + const uint32_t whenStartedWaiting = millis(); + unsigned int fragmentsReceived = 0; + for (;;) { - break; - } + const uint32_t timeWaiting = millis() - whenStartedWaiting; + if (!can0dev->ReceiveMessage(RxBufferIndexResponse, CanResponseTimeout - timeWaiting, buf)) + { + break; + } - if (reprap.Debug(moduleCan)) - { - buf->DebugPrint("Rx1:"); - } + if (reprap.Debug(moduleCan)) + { + buf->DebugPrint("Rx1:"); + } - const bool matchesRequest = buf->id.Src() == dest && (buf->msg.standardReply.requestId == rid || buf->msg.standardReply.requestId == CanRequestIdAcceptAlways); - if (matchesRequest && buf->id.MsgType() == CanMessageType::standardReply && buf->msg.standardReply.fragmentNumber == fragmentsReceived) - { - if (fragmentsReceived == 0) + const bool matchesRequest = buf->id.Src() == dest && (buf->msg.standardReply.requestId == rid || buf->msg.standardReply.requestId == CanRequestIdAcceptAlways); + if (matchesRequest && buf->id.MsgType() == CanMessageType::standardReply && buf->msg.standardReply.fragmentNumber == fragmentsReceived) { - const size_t textLength = buf->msg.standardReply.GetTextLength(buf->dataLength); - if (textLength != 0) // avoid concatenating blank lines to existing output + if (fragmentsReceived == 0) { - reply.lcatn(buf->msg.standardReply.text, textLength); + const size_t textLength = buf->msg.standardReply.GetTextLength(buf->dataLength); + if (textLength != 0) // avoid concatenating blank lines to existing output + { + reply.lcatn(buf->msg.standardReply.text, textLength); + } + if (extra != nullptr) + { + *extra = buf->msg.standardReply.extra; + } + uint32_t waitedFor = millis() - whenStartedWaiting; + if (waitedFor > longestWaitTime) + { + longestWaitTime = waitedFor; + longestWaitMessageType = (uint16_t)msgType; + } } - if (extra != nullptr) + else { - *extra = buf->msg.standardReply.extra; + reply.catn(buf->msg.standardReply.text, buf->msg.standardReply.GetTextLength(buf->dataLength)); } - uint32_t waitedFor = millis() - whenStartedWaiting; - if (waitedFor > longestWaitTime) + if (!buf->msg.standardReply.moreFollows) { - longestWaitTime = waitedFor; - longestWaitMessageType = (uint16_t)msgType; + const GCodeResult rslt = (GCodeResult)buf->msg.standardReply.resultCode; + CanMessageBuffer::Free(buf); + return rslt; } + ++fragmentsReceived; } - else - { - reply.catn(buf->msg.standardReply.text, buf->msg.standardReply.GetTextLength(buf->dataLength)); - } - if (!buf->msg.standardReply.moreFollows) + else if (matchesRequest && buf->id.MsgType() == replyType && fragmentsReceived == 0) { - const GCodeResult rslt = (GCodeResult)buf->msg.standardReply.resultCode; + callback(buf); CanMessageBuffer::Free(buf); - return rslt; - } - ++fragmentsReceived; - } - else if (matchesRequest && buf->id.MsgType() == replyType && fragmentsReceived == 0) - { - callback(buf); - CanMessageBuffer::Free(buf); - return GCodeResult::ok; - } - else - { - // We received an unexpected message. Don't tack it on to 'reply' because some replies contain important data, e.g. request for board short name. - if (buf->id.MsgType() == CanMessageType::standardReply) - { - reprap.GetPlatform().MessageF(WarningMessage, "Discarded std reply src=%u RID=%u exp %u \"%s\"\n", - buf->id.Src(), (unsigned int)buf->msg.standardReply.requestId, rid, buf->msg.standardReply.text); + return GCodeResult::ok; } else { - reprap.GetPlatform().MessageF(WarningMessage, "Discarded msg src=%u typ=%u RID=%u exp %u\n", - buf->id.Src(), (unsigned int)buf->id.MsgType(), (unsigned int)buf->msg.standardReply.requestId, rid); + // We received an unexpected message. Don't tack it on to 'reply' because some replies contain important data, e.g. request for board short name. + if (buf->id.MsgType() == CanMessageType::standardReply) + { + reprap.GetPlatform().MessageF(WarningMessage, "Discarded std reply src=%u RID=%u exp %u \"%s\"\n", + buf->id.Src(), (unsigned int)buf->msg.standardReply.requestId, rid, buf->msg.standardReply.text); + } + else + { + reprap.GetPlatform().MessageF(WarningMessage, "Discarded msg src=%u typ=%u RID=%u exp %u\n", + buf->id.Src(), (unsigned int)buf->id.MsgType(), (unsigned int)buf->msg.standardReply.requestId, rid); + } } } } @@ -1064,6 +1064,7 @@ void CanInterface::Diagnostics(MessageType mtype) noexcept longestWaitTime = 0; longestWaitMessageType = 0; + peakTimeSyncTxDelay = 0; } GCodeResult CanInterface::WriteGpio(CanAddress boardAddress, uint8_t portNumber, float pwm, bool isServo, const GCodeBuffer* gb, const StringRef &reply) noexcept diff --git a/src/Platform/Platform.cpp b/src/Platform/Platform.cpp index 3c1c8946..a92df70d 100644 --- a/src/Platform/Platform.cpp +++ b/src/Platform/Platform.cpp @@ -1706,8 +1706,6 @@ void Platform::InitialiseInterrupts() noexcept NVIC_SetPriority(TIMER3_IRQn, NvicPriorityTimerPWM); //Timer 3 runs the microsecond free running timer to generate heater/fan PWM #endif - StepTimer::Init(); // initialise the step pulse timer - // Tick interrupt for ADC conversions tickState = 0; currentFilterNumber = 0; diff --git a/src/Platform/Tasks.cpp b/src/Platform/Tasks.cpp index e433b8d8..c0848d99 100644 --- a/src/Platform/Tasks.cpp +++ b/src/Platform/Tasks.cpp @@ -225,6 +225,7 @@ void *Tasks::GetNVMBuffer(const uint32_t *stk) noexcept filamentsMutex.Create("Filaments"); mainTask.Create(MainTask, "MAIN", nullptr, TaskPriority::SpinPriority); + StepTimer::Init(); // initialise the step pulse timer now because we use it for measuring task CPU usage vTaskStartScheduler(); // doesn't return for (;;) { } // keep gcc happy } |