ADTF_DEVICE_TOOLBOX  3.12.1 (ADTF 3.18.3)
Source Code for Demo CAN FD Generator
Location
./src/examples/src/canfd_generator/
This example shows:
  • howto implement a Streaming Source
  • howto work with adtf::devicetb::sdk::can::stream_meta_type_canfd
  • howto work with adtf::devicetb::sdk::can::tCANFDData
Header
#pragma once
#include <adtf_filtersdk.h>
#include <adtf_base.h>
#include <adtf_systemsdk.h>
#include <adtf_devicetb_sdk.h>
class cCanFdGenerator : public adtf::filter::cSampleStreamingSource
{
public:
ADTF_CLASS_ID_NAME(cCanFdGenerator, "demo_canfd_generator.streaming_source.devicetb.cid", "Demo CAN FD Generator");
ADTF_CLASS_DEPENDENCIES(REQUIRE_INTERFACE(adtf::services::IReferenceClock),
cCanFdGenerator();
tResult Init() override;
tResult StartStreaming() override;
tResult StopStreaming() override;
private:
tResult CreateSample();
adtf::base::property_variable<tUInt> m_nTimer = 50;
adtf::base::property_variable<tUInt32> m_nMessageID = 0x30b;
adtf::base::property_variable<tUInt8> m_nChannelID = 1;
adtf::system::kernel_timer m_oLooper;
adtf::ucom::object_ptr<adtf::services::IReferenceClock> m_pClock;
adtf::streaming::ISampleWriter* m_pWriter;
adtf::ucom::object_ptr<adtf::devicetb::sdk::canfd::ICANFDCoder> m_pCoder;
adtf::ucom::object_ptr<adtf::devicetb::sdk::canfd::ICANFDDatabase> m_pDatabase;
adtf::devicetb::sdk::canfd::tSignalValue getSignalValueFromSignalInfo(const adtf::devicetb::sdk::canfd::tSignalInfo &sigInfo) const;
};
Signal info structure which contains all signal information.
Definition: canfd_types.h:437
Signal value structure which keeps one signal specific value.
Definition: canfd_types.h:480
Implementation
#include "demo_canfd_generator.h"
using namespace adtf;
using namespace adtf::util;
using namespace adtf::ucom;
using namespace adtf::streaming;
ADTF_PLUGIN_VERSION("CAN FD Generator",
devicetb,
DEVICETB_VERSION_MAJOR,
DEVICETB_VERSION_MINOR,
DEVICETB_VERSION_PATCH,
cCanFdGenerator)
constexpr const char* description =
R"(Use this Streaming Source to generate a in source predefined CAN FD Sample.
)";
cCanFdGenerator::cCanFdGenerator():
m_pWriter(CreateOutputPin("canfd_output", stream_meta_type_canfd()))
{
SetDescription("canfd_output", "The outcoming CAN FD sample stream containing the configured message.");
m_nTimer.SetDescription("Generation rate in [ms]");
RegisterPropertyVariable("Timer", m_nTimer);
m_nMessageID.SetDescription("The ID of the message.");
RegisterPropertyVariable("Message ID", m_nMessageID);
m_nChannelID.SetDescription("The channel and database which should be used.");
RegisterPropertyVariable("Channel ID", m_nChannelID);
SetDescription(description);
SetHelpLink("$(ADTF_DEVICE_TOOLBOX_DIR)/doc/adtf_device_toolbox_html/page_example_source_canfd_generator.html");
}
tResult cCanFdGenerator::Init()
{
RETURN_IF_FAILED(cSampleStreamingSource::Init());
RETURN_IF_FAILED(_runtime->GetObject(m_pClock));
object_ptr<ICANFDSupport> pCanFdSupport;
RETURN_IF_FAILED(_runtime->GetObject(pCanFdSupport));
RETURN_IF_FAILED(pCanFdSupport->GetDatabase(static_cast<tChannelID>(m_nChannelID), m_pDatabase));
RETURN_IF_FAILED(pCanFdSupport->CreateCoder(m_pCoder));
RETURN_IF_FAILED(m_pCoder->CreateMessage(m_nMessageID, static_cast<tChannelID>(m_nChannelID)));
RETURN_NOERROR;
}
tResult cCanFdGenerator::StartStreaming()
{
RETURN_IF_FAILED(cSampleStreamingSource::StartStreaming());
auto strMyName = get_named_graph_object_full_name(*this);
m_oLooper = system::kernel_timer(strMyName, m_nTimer * 1000, 0, &cCanFdGenerator::CreateSample, this);
RETURN_NOERROR;
}
tResult cCanFdGenerator::StopStreaming()
{
m_oLooper.Stop();
return cSampleStreamingSource::StopStreaming();
}
tResult cCanFdGenerator::CreateSample()
{
const auto tmNow = m_pClock->GetStreamTimeNs();
streaming::output_sample_data<tCANFDData> oSample(tmNow);
const tFrameInfo* pFrameInfo;
m_pDatabase->ResolveFrameInfo(m_nMessageID, &pFrameInfo);
if (pFrameInfo && pFrameInfo->pPduInfo && pFrameInfo->pPduInfo)
{
for (uint32_t nSignalIndex = 0; nSignalIndex < pFrameInfo->pPduInfo->nPduSignalCount; ++nSignalIndex)
{
const tSignalInfo* pSignalInfo = pFrameInfo->pPduInfo->pPduSignalInfo[nSignalIndex].pInfo;
if (pSignalInfo)
{
auto oSignalValue = getSignalValueFromSignalInfo(*pSignalInfo);
m_pCoder->SetPhysicalSignalValue(pSignalInfo->nId, 0.0);
if (IS_FAILED(m_pCoder->SetRawSignalValue(pSignalInfo->nId, oSignalValue)))
LOG_ERROR("could not set signal value for signal %s", pSignalInfo->pstrName);
}
}
}
m_pCoder->GetMessageData(oSample.GetDataPtr());
RETURN_IF_FAILED(m_pWriter->Write(oSample.Release()));
return m_pWriter->ManualTrigger();
}
tSignalValue cCanFdGenerator::getSignalValueFromSignalInfo(const tSignalInfo& oSignalInfo) const
{
tSignalValue oSignalValue;
switch (oSignalInfo.nRawType)
{
case tSignalRawDataType::DT_CANFD_UNSIGNED:
oSignalValue.nTypeTag = tSignalValue::TAG_UINT64;
oSignalValue.oData.nui64Value = static_cast<uint64_t>(oSignalInfo.nDefaultRawValue);
break;
case tSignalRawDataType::DT_CANFD_SIGNED:
oSignalValue.nTypeTag = tSignalValue::TAG_INT64;
oSignalValue.oData.ni64Value = static_cast<int64_t>(oSignalInfo.nDefaultRawValue);
break;
case tSignalRawDataType::DT_CANFD_IEEE_754:
{
if(oSignalInfo.nBitlen == 32)
{
oSignalValue.nTypeTag = tSignalValue::TAG_FLOAT32;
oSignalValue.oData.f32Value = static_cast<float>(oSignalInfo.nDefaultRawValue);
}
else if(oSignalInfo.nBitlen == 64)
{
oSignalValue.nTypeTag = tSignalValue::TAG_FLOAT64;
oSignalValue.oData.f64Value = static_cast<double>(oSignalInfo.nDefaultRawValue);
}
break;
}
default: break;
}
return oSignalValue;
}
axle::tSignalValue tSignalValue
Definition: can_types.h:301
axle::tSignalInfo tSignalInfo
Definition: can_types.h:300
Namespace for CAN FD in ADTF-Devicetoolbox.
ignition::tFrameInfo tFrameInfo
Frame structure which encapsulates one or more PDUs including its specific information.
Definition: canfd_types.h:743
axle::stream_meta_type_canfd stream_meta_type_canfd
Definition of Stream Meta Type CANFD Messages.
ADTF - Namespace.