Skip to content

Commit

Permalink
demos: Reorganized common CAN behavior; Review suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
KonradBkd committed Nov 15, 2024
1 parent 071ac59 commit c4e88dc
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 130 deletions.
91 changes: 0 additions & 91 deletions Demos/Can/CanBehavior.hpp

This file was deleted.

46 changes: 46 additions & 0 deletions Demos/Can/CanDemoCommon.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// SPDX-FileCopyrightText: 2024 Vector Informatik GmbH
//
// SPDX-License-Identifier: MIT

#include "silkit/services/can/all.hpp"
#include "silkit/services/can/string_utils.hpp"
#include "silkit/services/logging/ILogger.hpp"

using namespace SilKit::Services::Can;

std::ostream& operator<<(std::ostream& out, std::chrono::nanoseconds timestamp)
{
auto seconds = std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1, 1>>>(timestamp);
out << seconds.count() << "s";
return out;
}

// This is the common behavior used in CanReaderDemo and CanWriterDemo
namespace CanDemoCommon {

void FrameTransmitHandler(const CanFrameTransmitEvent& canFrameAck, ILogger* logger)
{
// Log
std::stringstream buffer;
buffer << "Ack CAN frame, canId=" << canFrameAck.canId << ", status='" << canFrameAck.status << "'";
logger->Info(buffer.str());
}

void FrameHandler(const CanFrameEvent& canFrameEvent, ILogger* logger)
{
// Indicate frame type in log message
std::string frameTypeHint = "";
if ((canFrameEvent.frame.flags & static_cast<CanFrameFlagMask>(CanFrameFlag::Fdf)) != 0)
{
frameTypeHint = "FD ";
}

// Log
std::string payloadStr(canFrameEvent.frame.dataField.begin(), canFrameEvent.frame.dataField.end());
std::stringstream buffer;
buffer << "Receive CAN " << frameTypeHint << "frame, canId=" << canFrameEvent.frame.canId << ", data ='"
<< payloadStr << "'";
logger->Info(buffer.str());
}

} // namespace CanDemoBehavior
11 changes: 5 additions & 6 deletions Demos/Can/CanReaderDemo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
// SPDX-License-Identifier: MIT

#include "ApplicationBase.hpp"
#include "CanBehavior.hpp"
#include "CanDemoCommon.hpp"

using namespace std::chrono_literals;


class CanApplication : public ApplicationBase
class CanReader: public ApplicationBase
{
public:
// Inherit constructors
Expand All @@ -35,10 +34,10 @@ class CanApplication : public ApplicationBase
_canController = GetParticipant()->CreateCanController("CanController1", networkName);

_canController->AddFrameTransmitHandler([this](ICanController* /*ctrl*/, const CanFrameTransmitEvent& ack) {
CanDemoBehavior::FrameTransmitHandler(ack, GetLogger());
CanDemoCommon::FrameTransmitHandler(ack, GetLogger());
});
_canController->AddFrameHandler([this](ICanController* /*ctrl*/, const CanFrameEvent& frameEvent) {
CanDemoBehavior::FrameHandler(frameEvent, GetLogger());
CanDemoCommon::FrameHandler(frameEvent, GetLogger());
});
}

Expand All @@ -61,7 +60,7 @@ class CanApplication : public ApplicationBase

int main(int argc, char** argv)
{
CanApplication app{"CanReader"};
CanReader app{"CanReader"};

app.SetupCommandLineArgs(argc, argv);

Expand Down
57 changes: 44 additions & 13 deletions Demos/Can/CanWriterDemo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
// SPDX-License-Identifier: MIT

#include "ApplicationBase.hpp"
#include "CanBehavior.hpp"
#include "CanDemoCommon.hpp"

using namespace std::chrono_literals;


class CanApplication : public ApplicationBase
class CanWriter: public ApplicationBase
{
public:
// Inherit constructors
Expand All @@ -34,10 +33,10 @@ class CanApplication : public ApplicationBase
_canController = GetParticipant()->CreateCanController("CanController1", networkName);

_canController->AddFrameTransmitHandler([this](ICanController* /*ctrl*/, const CanFrameTransmitEvent& ack) {
CanDemoBehavior::FrameTransmitHandler(ack, GetLogger());
CanDemoCommon::FrameTransmitHandler(ack, GetLogger());
});
_canController->AddFrameHandler([this](ICanController* /*ctrl*/, const CanFrameEvent& frameEvent) {
CanDemoBehavior::FrameHandler(frameEvent, GetLogger());
CanDemoCommon::FrameHandler(frameEvent, GetLogger());
});
}

Expand All @@ -47,26 +46,58 @@ class CanApplication : public ApplicationBase
_canController->Start();
}

void DoWorkSync(std::chrono::nanoseconds /*now*/) override
void SendFrame()
{
DoWork();
// Count up message id per frame
static uint64_t messageId = 0;
messageId++;

// Build a CAN frame
CanFrame canFrame{};
canFrame.canId = 3;

// Cycle between normal and FD frames
std::string frameTypeHint = "";
if (messageId % 2 == 1)
{
canFrame.flags = static_cast<CanFrameFlagMask>(CanFrameFlag::Fdf) // FD Format Indicator
| static_cast<CanFrameFlagMask>(CanFrameFlag::Brs); // Bit Rate Switch (for FD Format only)
frameTypeHint = "FD ";
}

// Build a payload with the message Id
std::stringstream payloadBuilder;
payloadBuilder << "Hello CAN Bus, this is frame #" << messageId;
auto payloadStr = payloadBuilder.str();
std::vector<uint8_t> payloadBytes(payloadStr.begin(), payloadStr.end());
canFrame.dataField = payloadBytes;
canFrame.dlc = static_cast<uint16_t>(canFrame.dataField.size());

// Log
std::stringstream buffer;
buffer << "Send CAN " << frameTypeHint << "frame, canId = " << canFrame.canId << ", data = '" << payloadStr
<< "' ";
GetLogger()->Info(buffer.str());

// Send
_canController->SendFrame(std::move(canFrame));
}

void DoWorkAsync() override
void DoWorkSync(std::chrono::nanoseconds /*now*/) override
{
DoWork();
SendFrame();
}

private:
void DoWork()
void DoWorkAsync() override
{
CanDemoBehavior::SendFrame(_canController, GetLogger());
SendFrame();
}

};

int main(int argc, char** argv)
{
CanApplication app{"CanWriter"};
CanWriter app{"CanWriter"};

app.SetupCommandLineArgs(argc, argv);

Expand Down
26 changes: 6 additions & 20 deletions Demos/include/ApplicationBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class ApplicationBase
std::shared_ptr<CommandlineParser> _commandLineParser;

// Default command line argument identifiers (to allow exclusion)
enum DefaultArg
enum struct DefaultArg
{
Name,
Uri,
Expand Down Expand Up @@ -108,7 +108,7 @@ class ApplicationBase
ITimeSyncService* _timeSyncService{nullptr};

// For sync: wait for sil-kit-system-controller start/abort or manual user abort
enum SystemControllerResult
enum struct SystemControllerResult
{
Unknown,
CoordinatedStart,
Expand Down Expand Up @@ -198,7 +198,7 @@ class ApplicationBase

auto ToLowerCase(std::string s) -> std::string
{
std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return (unsigned char)std::tolower(c); });
std::for_each(s.begin(), s.end(), [](char& c) { c = std::tolower(c); });
return s;
}
auto IsValidLogLevel(const std::string& levelStr) -> bool
Expand Down Expand Up @@ -261,7 +261,7 @@ class ApplicationBase

if (hasAsyncFlag && hasDurationOption)
{
std::cerr << "Error: Options '--async' and '--step' cannot be used simultaneously" << std::endl;
std::cerr << "Error: Options '--async' and '--duration' cannot be used simultaneously" << std::endl;
_commandLineParser->PrintUsageInfo(std::cerr, executableName);
exit(-1);
}
Expand Down Expand Up @@ -311,13 +311,6 @@ class ApplicationBase
{
_arguments.participantConfiguration = SilKit::Config::ParticipantConfigurationFromFile(configFileName);
}
catch (const SilKit::SilKitError& error)
{
std::cerr << "Error: Failed to load configuration '" << configFileName << "', " << error.what()
<< std::endl;

exit(-2);
}
catch (const SilKit::ConfigurationError& error)
{
std::cerr << "Error: Failed to load configuration '" << configFileName << "', " << error.what()
Expand All @@ -337,8 +330,7 @@ class ApplicationBase
{
std::cerr
<< "Error: Argument of the '--log' option must be one of 'trace', 'debug', 'warn', 'info', "
"'error', "
"'critical', or 'off'"
"'error', 'critical', or 'off'"
<< std::endl;
exit(-1);
}
Expand Down Expand Up @@ -366,12 +358,6 @@ class ApplicationBase
{
_arguments.participantConfiguration = SilKit::Config::ParticipantConfigurationFromString(configString);
}
catch (const SilKit::SilKitError& error)
{
std::cerr << "Error: Failed to set configuration from string '" << configString << "', " << error.what()
<< std::endl;
exit(-2);
}
catch (const SilKit::ConfigurationError& error)
{
std::cerr << "Error: Failed to set configuration from string '" << configString << "', " << error.what()
Expand Down Expand Up @@ -564,7 +550,7 @@ class ApplicationBase
{
AddCommandLineArgs();
}
catch (const std::runtime_error& e)
catch (const std::exception& e)
{
std::cerr << "Error: " << e.what() << std::endl;
exit(-1);
Expand Down

0 comments on commit c4e88dc

Please sign in to comment.