Skip to content

Commit

Permalink
Applied comments, using bytespan now amongst other things
Browse files Browse the repository at this point in the history
  • Loading branch information
lpbeliveau-silabs committed Nov 19, 2024
1 parent 4846604 commit 75400f7
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 117 deletions.
38 changes: 38 additions & 0 deletions src/platform/silabs/silabs_utils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
*
* Copyright (c) 2020 Project CHIP Authors
* Copyright (c) 2022 Silabs.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "silabs_utils.h"
#include "SoftwareFaultReports.h"
#include <MatterConfig.h>

void appError(int err)
{
char faultMessage[30] = { 0 }; // App Critical Error: + 10 digit + null character
snprintf(faultMessage, sizeof faultMessage, "App Critical Error:%d", err);
SILABS_LOG("!!!!!!!!!!!! %s !!!!!!!!!!!", faultMessage);
chip::DeviceLayer::Silabs::OnSoftwareFaultEventHandler(faultMessage);
vTaskSuspendAll();
/* Force an assert. */
chipAbort();
}

void appError(CHIP_ERROR error)
{
appError(static_cast<int>(error.AsInteger()));
}
43 changes: 43 additions & 0 deletions src/platform/silabs/silabs_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
*
* Copyright (c) 2020 Project CHIP Authors
* Copyright (c) 2022 Silabs.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

// EFR Logging
#ifdef __cplusplus
extern "C" {
#endif

void silabsInitLog(void);

void silabsLog(const char * aFormat, ...);
#define SILABS_LOG(...) silabsLog(__VA_ARGS__);
void appError(int err);

#ifdef __cplusplus
}

// Output logs to RTT by defaults
#ifndef SILABS_LOG_OUT_UART
#define SILABS_LOG_OUT_UART 0
#endif

#include <lib/core/CHIPError.h>
void appError(CHIP_ERROR error);
#endif
130 changes: 49 additions & 81 deletions src/platform/silabs/tracing/SilabsTracing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,65 +34,33 @@ namespace chip {
namespace Tracing {
namespace Silabs {

// String mapping for TimeTraceOperation
const char * TimeTraceOperationToString(TimeTraceOperation operation)
{
switch (operation)
{
case TimeTraceOperation::kSpake2p:
return "Spake2p";
case TimeTraceOperation::kPake1:
return "Pake1";
case TimeTraceOperation::kPake2:
return "Pake2";
case TimeTraceOperation::kPake3:
return "Pake3";
case TimeTraceOperation::kOperationalCredentials:
return "OperationalCredentials";
case TimeTraceOperation::kAttestationVerification:
return "AttestationVerification";
case TimeTraceOperation::kCSR:
return "CSR";
case TimeTraceOperation::kNOC:
return "NOC";
case TimeTraceOperation::kTransportLayer:
return "TransportLayer";
case TimeTraceOperation::kTransportSetup:
return "TransportSetup";
case TimeTraceOperation::kFindOperational:
return "FindOperational";
case TimeTraceOperation::kCaseSession:
return "CaseSession";
case TimeTraceOperation::kSigma1:
return "Sigma1";
case TimeTraceOperation::kSigma2:
return "Sigma2";
case TimeTraceOperation::kSigma3:
return "Sigma3";
case TimeTraceOperation::kOTA:
return "OTA";
case TimeTraceOperation::kImageUpload:
return "ImageUpload";
case TimeTraceOperation::kImageVerification:
return "ImageVerification";
case TimeTraceOperation::kAppApplyTime:
return "AppApplyTime";
case TimeTraceOperation::kBootup:
return "Bootup";
case TimeTraceOperation::kSilabsInit:
return "SilabsInit";
case TimeTraceOperation::kMatterInit:
return "MatterInit";
case TimeTraceOperation::kNumTraces:
return "NumTraces";
case TimeTraceOperation::kBufferFull:
return "BufferFull";
default:
return "Unknown";
}
}
const char * TimeTraceOperationString[] = {
[static_cast<int>(TimeTraceOperation::kSpake2p)] = "Spake2p",
[static_cast<int>(TimeTraceOperation::kPake1)] = "Pake1",
[static_cast<int>(TimeTraceOperation::kPake2)] = "Pake2",
[static_cast<int>(TimeTraceOperation::kPake3)] = "Pake3",
[static_cast<int>(TimeTraceOperation::kOperationalCredentials)] = "OperationalCredentials",
[static_cast<int>(TimeTraceOperation::kAttestationVerification)] = "AttestationVerification",
[static_cast<int>(TimeTraceOperation::kCSR)] = "CSR",
[static_cast<int>(TimeTraceOperation::kNOC)] = "NOC",
[static_cast<int>(TimeTraceOperation::kTransportLayer)] = "TransportLayer",
[static_cast<int>(TimeTraceOperation::kTransportSetup)] = "TransportSetup",
[static_cast<int>(TimeTraceOperation::kFindOperational)] = "FindOperational",
[static_cast<int>(TimeTraceOperation::kCaseSession)] = "CaseSession",
[static_cast<int>(TimeTraceOperation::kSigma1)] = "Sigma1",
[static_cast<int>(TimeTraceOperation::kSigma2)] = "Sigma2",
[static_cast<int>(TimeTraceOperation::kSigma3)] = "Sigma3",
[static_cast<int>(TimeTraceOperation::kOTA)] = "OTA",
[static_cast<int>(TimeTraceOperation::kImageUpload)] = "ImageUpload",
[static_cast<int>(TimeTraceOperation::kImageVerification)] = "ImageVerification",
[static_cast<int>(TimeTraceOperation::kAppApplyTime)] = "AppApplyTime",
[static_cast<int>(TimeTraceOperation::kBootup)] = "Bootup",
[static_cast<int>(TimeTraceOperation::kSilabsInit)] = "SilabsInit",
[static_cast<int>(TimeTraceOperation::kMatterInit)] = "MatterInit",
[static_cast<int>(TimeTraceOperation::kBufferFull)] = "BufferFull",
[static_cast<int>(TimeTraceOperation::kNumTraces)] = "NumTraces",
};

// String mapping for OperationType
const char * OperationTypeToString(OperationType type)
{
switch (type)
Expand All @@ -116,26 +84,27 @@ struct TimeTrackerStorage : public TimeTracker, PersistentData<kPersistentTimeTr
// TODO implement the Persistent Array class and use it here for logging the watermark array
};

int TimeTracker::ToCharArray(char * buffer, size_t bufferSize) const
int TimeTracker::ToCharArray(MutableByteSpan & buffer) const
{
if (mType == OperationType::kBegin)
switch (mType)
{
return snprintf(buffer, bufferSize, "TimeTracker - StartTime: %" PRIu32 ", Operation: %s, Type: %s, Error: 0x%" PRIx32,
mStartTime.count(), TimeTraceOperationToString(mOperation), OperationTypeToString(mType),
mError.AsInteger());
}
else if (mType == OperationType::kEnd)
{
return snprintf(buffer, bufferSize,
case OperationType::kBegin:
return snprintf(reinterpret_cast<char *>(buffer.data()), buffer.size(),
"TimeTracker - StartTime: %" PRIu32 ", Operation: %s, Type: %s, Error: 0x%" PRIx32, mStartTime.count(),
TimeTraceOperationString[to_underlying(mOperation)], OperationTypeToString(mType), mError.AsInteger());
case OperationType::kEnd:
return snprintf(reinterpret_cast<char *>(buffer.data()), buffer.size(),
"TimeTracker - StartTime: %" PRIu32 ", EndTime: %" PRIu32 ", Duration: %" PRIu32
" ms, Operation: %s, Type: %s, Error: 0x%" PRIx32,
mStartTime.count(), mEndTime.count(), (mEndTime - mStartTime).count(),
TimeTraceOperationToString(mOperation), OperationTypeToString(mType), mError.AsInteger());
TimeTraceOperationString[to_underlying(mOperation)], OperationTypeToString(mType), mError.AsInteger());
case OperationType::kInstant:
return snprintf(reinterpret_cast<char *>(buffer.data()), buffer.size(),
"TimeTracker - EventTime: %" PRIu32 ", Operation: %s, Type: %s, Error: 0x%" PRIx32, mStartTime.count(),
TimeTraceOperationString[to_underlying(mOperation)], OperationTypeToString(mType), mError.AsInteger());
default:
return snprintf(reinterpret_cast<char *>(buffer.data()), buffer.size(), "TimeTracker - Unknown operation type");
}

// Instant operation
return snprintf(buffer, bufferSize, "TimeTracker - EventTime: %" PRIu32 ", Operation: %s, Type: %s, Error: 0x%" PRIx32,
mStartTime.count(), TimeTraceOperationToString(mOperation), OperationTypeToString(mType), mError.AsInteger());
}

SilabsTracer SilabsTracer::sInstance;
Expand Down Expand Up @@ -240,9 +209,9 @@ CHIP_ERROR SilabsTracer::OutputTimeTracker(const TimeTracker & tracker)
{
VerifyOrReturnError(isLogInitialized(), CHIP_ERROR_UNINITIALIZED);
// Allocate a buffer to store the trace
char buffer[256];
auto bufferSize = sizeof(buffer);
tracker.ToCharArray(buffer, bufferSize);
uint8_t buffer[kMaxTraceSize];
MutableByteSpan span(buffer);
tracker.ToCharArray(span);
ChipLogProgress(DeviceLayer, "%s", buffer); // Use format string literal
return CHIP_NO_ERROR;
}
Expand Down Expand Up @@ -287,7 +256,7 @@ CHIP_ERROR SilabsTracer::OutputWaterMark(TimeTraceOperation aOperation)
ChipLogProgress(DeviceLayer,
"Operation: %s, TotalCount=%" PRIu32 ", SuccessFullCount=%" PRIu32 ", MaxTime=%" PRIu32 ", MinTime=%" PRIu32
", AvgTime=%" PRIu32 ", CountAboveAvg=%" PRIu32 "",
TimeTraceOperationToString(aOperation), watermark.mTotalCount, watermark.mSuccessfullCount,
TimeTraceOperationString[to_underlying(aOperation)], watermark.mTotalCount, watermark.mSuccessfullCount,
watermark.mMaxTimeMs.count(), watermark.mMinTimeMs.count(), watermark.mMovingAverage.count(),
watermark.mCountAboveAvg);

Expand Down Expand Up @@ -369,28 +338,27 @@ CHIP_ERROR SilabsTracer::LoadWatermarks()
return CHIP_NO_ERROR;
}

CHIP_ERROR SilabsTracer::GetTraceByOperation(TimeTraceOperation aOperation, char * buffer, size_t & size) const
CHIP_ERROR SilabsTracer::GetTraceByOperation(TimeTraceOperation aOperation, MutableByteSpan & buffer) const
{
auto * current = mTimeTrackerList.head;
while (current != nullptr)
{
if (current->mValue.mOperation == aOperation)
{
// Check if the buffer is large enough
auto requiredSize = current->mValue.ToCharArray(nullptr, 0);
auto requiredSize = current->mValue.GetSize();

if (requiredSize < 0)
{
return CHIP_ERROR_INTERNAL;
}

if (static_cast<size_t>(requiredSize) >= size)
if (static_cast<size_t>(requiredSize) >= buffer.size())
{
size = static_cast<size_t>(requiredSize + 1); // Include null terminator
return CHIP_ERROR_BUFFER_TOO_SMALL;
}

current->mValue.ToCharArray(buffer, size);
current->mValue.ToCharArray(buffer);
return CHIP_NO_ERROR;
}
current = current->mpNext;
Expand Down
19 changes: 15 additions & 4 deletions src/platform/silabs/tracing/SilabsTracing.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <lib/core/CHIPError.h>
#include <lib/core/CHIPPersistentStorageDelegate.h>
#include <lib/support/LinkedList.h>
#include <lib/support/Span.h>
#include <stdint.h>
#include <system/SystemClock.h>

Expand Down Expand Up @@ -82,11 +83,20 @@ struct TimeTracker

/** @brief Convert the TimeTracker to a string for logs
* Behaves like snprintf, but formats the output differently based on the OperationType
* May be used with nullptr and 0 to get the required buffer size
* May be used with a buffer of size == 0 to get the required buffer size
* @param buffer The buffer to write the string to
* @param bufferSize The size of the buffer
* @return The number of characters written to the buffer, or the size of the buffer required if the buffer is too small
*/
int ToCharArray(char * buffer, size_t bufferSize) const;
int ToCharArray(MutableByteSpan & buffer) const;

/** @brief Get the size of the string representation of the TimeTracker
* @return The size of the string representation of the TimeTracker
*/
int GetSize() const
{
MutableByteSpan temp;
return ToCharArray(temp);
}
};

struct Watermark
Expand All @@ -107,6 +117,7 @@ class SilabsTracer
public:
static constexpr size_t kNumTraces = to_underlying(TimeTraceOperation::kNumTraces);
static constexpr size_t kMaxBufferedTraces = 64;
static constexpr size_t kMaxTraceSize = 256;

/** @brief Get the singleton instance of SilabsTracer */
static SilabsTracer & Instance() { return sInstance; }
Expand Down Expand Up @@ -211,7 +222,7 @@ class SilabsTracer
*/
Watermark GetWatermark(TimeTraceOperation aOperation) { return mWatermarks[to_underlying(aOperation)]; }
size_t GetTimeTracesCount() { return mBufferedTrackerCount; }
CHIP_ERROR GetTraceByOperation(TimeTraceOperation aOperation, char * buffer, size_t & size) const;
CHIP_ERROR GetTraceByOperation(TimeTraceOperation aOperation, MutableByteSpan & buffer) const;

private:
struct TimeTrackerList
Expand Down
Loading

0 comments on commit 75400f7

Please sign in to comment.