ADTF_DEVICE_TOOLBOX  3.10.0 (ADTF 3.15.2)
Source Code for Demo CAN FD Coder Generator
Location
./src/examples/src/canfd_coder_generator/
This example shows:
Header
#pragma once
#include <adtf_filtersdk.h>
#include <adtf_base.h>
#include <adtf_systemsdk.h>
class cCANFDCoderGenerator : public adtf::filter::cSampleStreamingSource
{
public:
ADTF_CLASS_ID_NAME(cCANFDCoderGenerator, "demo_canfd_coder_generator.streaming_source.devicetb.cid", "Demo CAN FD Coder Generator");
ADTF_CLASS_DEPENDENCIES(REQUIRE_INTERFACE(adtf::services::IReferenceClock),
cCANFDCoderGenerator();
tResult Init() override;
tResult StartStreaming() override;
tResult StopStreaming() override;
private:
tResult CreateSample();
adtf::base::property_variable<tUInt> m_nTimer = 10;
adtf::base::property_variable<adtf::util::cString> m_strSignal;
adtf::base::property_variable<tUInt> m_nChannelID = 1;
adtf::base::property_variable<tInt> m_nSignalValue = 0;
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;
};
Copyright © Audi Electronics Venture GmbH.
ignition::tSignalID tSignalID
Definition: canfd_types.h:719
Implementation
#include "demo_canfd_coder_generator.h"
using namespace adtf;
ADTF_PLUGIN_VERSION("CAN FD coder generator",
devicetb,
DEVICETB_VERSION_MAJOR,
DEVICETB_VERSION_MINOR,
DEVICETB_VERSION_PATCH,
cCANFDCoderGenerator)
namespace
{
std::vector<tPDUID> get_pdu_ids(const tPduInfo* pPduInfo, ICANFDDatabase& oDB)
{
std::vector<tPDUID> oPduIds;
if (pPduInfo)
{
oPduIds.push_back(pPduInfo->nId);
for (size_t nTransformIndex = 0; nTransformIndex < pPduInfo->nTransformationCount; ++nTransformIndex)
{
const auto nChildPdu = pPduInfo->pTransformations[nTransformIndex].nChildPduId;
const tPduInfo* pChildPduInfo;
THROW_IF_FAILED(oDB.GetPduInfo(nChildPdu, &pChildPduInfo));
const auto oChildIds = get_pdu_ids(pChildPduInfo, oDB);
oPduIds.insert(oPduIds.end(), oChildIds.begin(), oChildIds.end());
}
}
return oPduIds;
}
tMessageID get_message_id_for_signal(tSignalID nSignalID, ICANFDDatabase& oDB)
{
std::unordered_map<tPDUID, tMessageID> oMessageIds;
THROW_IF_FAILED(oDB.GetClusterFrames(ucom::make_function([&](const tFrameInfo* pFrameInfo)
{
for (const auto nPduId: get_pdu_ids(pFrameInfo->pPduInfo, oDB))
{
oMessageIds[nPduId] = pFrameInfo->nMessageId;
}
})));
tMessageID nMessageId = ignition::INVALID_MESSAGE_ID;
THROW_IF_FAILED(oDB.GetPdusBySignal(nSignalID, ucom::make_function([&](const tPduInfo* pPduInfo)
{
const auto itMessageId = oMessageIds.find(pPduInfo->nId);
if (itMessageId != oMessageIds.end())
{
nMessageId = itMessageId->second;
}
})));
if (nMessageId == ignition::INVALID_MESSAGE_ID)
{
THROW_ERROR_DESC(ERR_NOT_FOUND, "Unable to find message id for frame that contains the signal %d", nSignalID);
}
return nMessageId;
}
}
cCANFDCoderGenerator::cCANFDCoderGenerator() :
m_pWriter(CreateOutputPin("canfd_output", stream_meta_type_canfd()))
{
SetDescription("canfd_output", "The outcoming CAN FD sample stream containing the configured signal and value.");
m_nTimer.SetDescription("Generation rate in [ms]");
RegisterPropertyVariable("Timer", m_nTimer);
m_strSignal.SetDescription("The name of the signal.");
RegisterPropertyVariable("Signal", m_strSignal);
m_nChannelID.SetDescription("The channel and database which should be used.");
RegisterPropertyVariable("ChannelID", m_nChannelID);
m_nSignalValue.SetDescription("The value for the signal.");
RegisterPropertyVariable("Signalvalue", m_nSignalValue);
SetDescription("Use this Streaming Source to generate CAN FD data for a specific signal from a CAN FD database.");
SetHelpLink("$(ADTF_DEVICE_TOOLBOX_DIR)/doc/devicetoolbox_html/page_example_source_canfd_coder_generator.html");
}
ucom::object_ptr<streaming::IStreamType> create_canfd_stream_type(tChannelID nChannel, ICANFDDatabase& oDatabase)
{
ucom::object_ptr<streaming::IStreamType> pStreamType = ucom::make_object_ptr<streaming::stream_type<stream_meta_type_canfd>>();
streaming::set_property<std::string>(*pStreamType.Get(), stream_meta_type_canfd::CanFdChannelNumber, std::to_string(nChannel));
const tChar* strClusterName;
THROW_IF_FAILED(oDatabase.GetClusterName(&strClusterName));
streaming::set_property<util::cString>(*pStreamType.Get(), stream_meta_type_canfd::CanFdNetworkName, strClusterName);
return pStreamType;
}
tResult cCANFDCoderGenerator::Init()
{
RETURN_IF_FAILED(cSampleStreamingSource::Init());
if (m_strSignal->IsEmpty())
{
RETURN_ERROR_DESC(ERR_INVALID_ARG, "Please set a signal name");
}
RETURN_IF_FAILED(_runtime->GetObject(m_pClock));
adtf::ucom::object_ptr<ICANFDSupport> pCanFdSupport;
RETURN_IF_FAILED(_runtime->GetObject(pCanFdSupport));
adtf::ucom::object_ptr<ICANFDDatabase> pDatabase;
RETURN_IF_FAILED(pCanFdSupport->GetDatabase(static_cast<tChannelID>(m_nChannelID), pDatabase));
const tSignalInfo* pInfo;
RETURN_IF_FAILED(pDatabase->GetSignalInfo(*m_strSignal, &pInfo));
m_nSignalId = pInfo->nId;
RETURN_IF_FAILED(pCanFdSupport->CreateCoder(m_pCoder));
RETURN_IF_FAILED(m_pCoder->CreateMessage(get_message_id_for_signal(m_nSignalId, *pDatabase), static_cast<tChannelID>(m_nChannelID)));
m_pWriter->ChangeType(create_canfd_stream_type(static_cast<tChannelID>(m_nChannelID), *pDatabase));
RETURN_NOERROR;
}
tResult cCANFDCoderGenerator::StartStreaming()
{
RETURN_IF_FAILED(cSampleStreamingSource::StartStreaming());
auto strMyName = adtf::streaming::get_named_graph_object_full_name(*this);
m_oLooper = system::kernel_timer(strMyName, m_nTimer * 1000, 0, &cCANFDCoderGenerator::CreateSample, this);
RETURN_NOERROR;
}
tResult cCANFDCoderGenerator::StopStreaming()
{
m_oLooper.Stop();
return cSampleStreamingSource::StopStreaming();
}
tResult cCANFDCoderGenerator::CreateSample()
{
const auto tmNow = m_pClock->GetStreamTimeNs();
RETURN_IF_FAILED(m_pCoder->SetPhysicalSignalValue(m_nSignalId, m_nSignalValue));
streaming::output_sample_data<tCANFDData> oSample(tmNow);
RETURN_IF_FAILED(m_pCoder->GetMessageData(oSample.GetDataPtr()));
oSample->sHeader.tmTimeStamp = base::duration_cast<tTimeStamp>(tmNow);
m_pWriter->Write(oSample.Release());
return m_pWriter->ManualTrigger();
}
Copyright © Audi Electronics Venture GmbH.
axle::tSignalInfo tSignalInfo
Definition: can_types.h:290
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:733
jack::ICANFDDatabase ICANFDDatabase
The ICANFDDatabase interface.
ignition::tMessageID tMessageID
Definition: canfd_types.h:720
axle::stream_meta_type_canfd stream_meta_type_canfd
Definition of Stream Meta Type CANFD Messages.
ignition::tPduInfo tPduInfo
Message/PDU structure which contain all information about one specific message.
Definition: canfd_types.h:732
ADTF - Namespace.
Copyright © Audi Electronics Venture GmbH.