Fix FlexRay extension bugs and implement FlexRay example
parent
a9e1f24f67
commit
f53bc2e920
|
|
@ -35,9 +35,10 @@ pybind11_add_module(icsneopy
|
|||
icsneopy/communication/message/scriptstatusmessage.cpp
|
||||
icsneopy/communication/message/callback/messagecallback.cpp
|
||||
icsneopy/communication/message/filter/messagefilter.cpp
|
||||
icsneopy/communication/message/flexray/flexraymessage.cpp
|
||||
icsneopy/flexray/flexray.cpp
|
||||
icsneopy/disk/diskdriver.cpp
|
||||
icsneopy/device/device.cpp
|
||||
icsneopy/device/extensions/deviceextension.cpp
|
||||
icsneopy/device/idevicesettings.cpp
|
||||
icsneopy/icsneocpp.cpp
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,57 +0,0 @@
|
|||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/flexray/flexraymessage.h"
|
||||
#include "icsneo/device/extensions/flexray/symbol.h"
|
||||
#include "icsneo/device/extensions/flexray/channel.h"
|
||||
#include "icsneo/device/extensions/flexray/crcstatus.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
struct FlexRayNamespace {
|
||||
using Symbol = icsneo::FlexRay::Symbol;
|
||||
using CRCStatus = icsneo::FlexRay::CRCStatus;
|
||||
using Channel = icsneo::FlexRay::Channel;
|
||||
};
|
||||
|
||||
void init_flexraymessage(pybind11::module_& m) {
|
||||
// dummy class to hold the enums
|
||||
pybind11::class_<FlexRayNamespace> flexray(m, "FlexRay");
|
||||
// enumerations
|
||||
pybind11::enum_<FlexRayNamespace::Symbol>(flexray, "Symbol")
|
||||
.value("None", FlexRayNamespace::Symbol::None)
|
||||
.value("Unknown", FlexRayNamespace::Symbol::Unknown)
|
||||
.value("Wakeup", FlexRayNamespace::Symbol::Wakeup)
|
||||
.value("CAS", FlexRayNamespace::Symbol::CAS);
|
||||
pybind11::enum_<FlexRayNamespace::CRCStatus>(flexray, "CRCStatus")
|
||||
.value("OK", FlexRayNamespace::CRCStatus::OK)
|
||||
.value("Error", FlexRayNamespace::CRCStatus::Error)
|
||||
.value("NoCRC", FlexRayNamespace::CRCStatus::NoCRC);
|
||||
pybind11::enum_<FlexRayNamespace::Channel>(flexray, "Channel")
|
||||
.value("None", FlexRayNamespace::Channel::None)
|
||||
.value("A", FlexRayNamespace::Channel::A)
|
||||
.value("B", FlexRayNamespace::Channel::B)
|
||||
.value("AB", FlexRayNamespace::Channel::AB);
|
||||
// read-only until transmit is supported
|
||||
pybind11::class_<FlexRayMessage, std::shared_ptr<FlexRayMessage>, Frame>(m, "FlexRayMessage")
|
||||
.def(pybind11::init())
|
||||
.def_readonly("slotid", &FlexRayMessage::slotid)
|
||||
.def_readonly("tsslen", &FlexRayMessage::tsslen)
|
||||
.def_readonly("framelen", &FlexRayMessage::framelen)
|
||||
.def_readonly("symbol", &FlexRayMessage::symbol)
|
||||
.def_readonly("header_crc_status", &FlexRayMessage::headerCRCStatus)
|
||||
.def_readonly("header_crc", &FlexRayMessage::headerCRC)
|
||||
.def_readonly("frame_crc_status", &FlexRayMessage::crcStatus)
|
||||
.def_readonly("frame_crc", &FlexRayMessage::frameCRC)
|
||||
.def_readonly("channel", &FlexRayMessage::channel)
|
||||
.def_readonly("null_frame", &FlexRayMessage::nullFrame)
|
||||
.def_readonly("payload_preamble", &FlexRayMessage::payloadPreamble)
|
||||
.def_readonly("sync_frame", &FlexRayMessage::sync)
|
||||
.def_readonly("startup_frame", &FlexRayMessage::startup)
|
||||
.def_readonly("dynamic_frame", &FlexRayMessage::dynamic)
|
||||
.def_readonly("cycle", &FlexRayMessage::cycle);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
#include <pybind11/chrono.h>
|
||||
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/device/extensions/deviceextension.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
|
|
@ -20,6 +21,8 @@ void init_device(pybind11::module_& m) {
|
|||
.def("enable_message_polling", &Device::enableMessagePolling, pybind11::arg("filter") = std::nullopt, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_current_message_count", &Device::getCurrentMessageCount)
|
||||
.def("get_digital_io", &Device::getDigitalIO, pybind11::arg("type"), pybind11::arg("number"), pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_extension", static_cast<std::shared_ptr<DeviceExtension>(Device::*)(const std::string&) const>(&Device::getExtension)) // This has to be static_casted rather than overload_casted because DeviceExtension is forward declared in device.h
|
||||
.def("get_flexray_controllers", &Device::getFlexRayControllers)
|
||||
.def("get_gptp_status", &Device::getGPTPStatus, pybind11::arg("timeout") = std::chrono::milliseconds(100), pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_messages", [](Device& device) { return device.getMessages(); }, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_polling_message_limit", &Device::getPollingMessageLimit)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/device/extensions/deviceextension.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_deviceextension(pybind11::module_& m) {
|
||||
pybind11::class_<DeviceExtension, std::shared_ptr<DeviceExtension>>(m, "DeviceExtension")
|
||||
.def("get_name", &DeviceExtension::getName);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/flexray/flexraymessage.h"
|
||||
#include "icsneo/device/extensions/flexray/symbol.h"
|
||||
#include "icsneo/device/extensions/flexray/channel.h"
|
||||
#include "icsneo/device/extensions/flexray/crcstatus.h"
|
||||
#include "icsneo/device/extensions/flexray/controller.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
struct FlexRayNamespace {
|
||||
using Symbol = icsneo::FlexRay::Symbol;
|
||||
using CRCStatus = icsneo::FlexRay::CRCStatus;
|
||||
using Channel = icsneo::FlexRay::Channel;
|
||||
};
|
||||
|
||||
namespace FlexRay {
|
||||
|
||||
struct ClusterNamespace {
|
||||
using SpeedType = icsneo::FlexRay::Cluster::SpeedType;
|
||||
using SPPType = icsneo::FlexRay::Cluster::SPPType;
|
||||
};
|
||||
|
||||
void init_extension(pybind11::class_<FlexRayNamespace>& c) {
|
||||
pybind11::class_<MessageBuffer, std::shared_ptr<MessageBuffer>>(c, "MessageBuffer")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("is_dynamic", &MessageBuffer::isDynamic)
|
||||
.def_readwrite("is_sync", &MessageBuffer::isSync)
|
||||
.def_readwrite("is_startup", &MessageBuffer::isStartup)
|
||||
.def_readwrite("is_network_management_frame", &MessageBuffer::isNetworkManagementFrame)
|
||||
.def_readwrite("is_transmit", &MessageBuffer::isTransmit)
|
||||
.def_readwrite("frame_id", &MessageBuffer::frameID)
|
||||
.def_readwrite("channel_a", &MessageBuffer::channelA)
|
||||
.def_readwrite("channel_b", &MessageBuffer::channelB)
|
||||
.def_readwrite("frame_length_bytes", &MessageBuffer::frameLengthBytes)
|
||||
.def_readwrite("base_cycle", &MessageBuffer::baseCycle)
|
||||
.def_readwrite("cycle_repetition", &MessageBuffer::cycleRepetition)
|
||||
.def_readwrite("continuous_mode", &MessageBuffer::continuousMode);
|
||||
|
||||
auto controller = pybind11::class_<Controller, std::shared_ptr<Controller>>(c, "Controller")
|
||||
.def("get_network", &Controller::getNetwork)
|
||||
.def("get_configuration", &Controller::getConfiguration)
|
||||
.def("set_configuration", &Controller::setConfiguration)
|
||||
.def("get_start_when_going_online", &Controller::getStartWhenGoingOnline)
|
||||
.def("set_start_when_going_online", &Controller::setStartWhenGoingOnline)
|
||||
.def("get_allow_coldstart", &Controller::getAllowColdstart)
|
||||
.def("set_allow_coldstart", &Controller::setAllowColdstart)
|
||||
.def("get_wakeup_before_start", &Controller::getWakeupBeforeStart)
|
||||
.def("set_wakeup_before_start", &Controller::setWakeupBeforeStart)
|
||||
.def("add_message_buffer", &Controller::addMessageBuffer)
|
||||
.def("clear_message_buffers", &Controller::clearMessageBuffers)
|
||||
.def("wakeup", &Controller::wakeup)
|
||||
.def("configure", &Controller::getReady)
|
||||
.def("start", &Controller::start)
|
||||
.def("transmit", &Controller::transmit)
|
||||
.def("halt", &Controller::halt)
|
||||
.def("freeze", &Controller::freeze)
|
||||
.def("trigger_mts", &Controller::triggerMTS);
|
||||
|
||||
pybind11::class_<Controller::Configuration>(controller, "Configuration")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("accept_startup_range_microticks", &Controller::Configuration::AcceptStartupRangeMicroticks)
|
||||
.def_readwrite("allow_passive_to_active_cycle_pairs", &Controller::Configuration::AllowPassiveToActiveCyclePairs)
|
||||
.def_readwrite("cluster_drift_damping", &Controller::Configuration::ClusterDriftDamping)
|
||||
.def_readwrite("channel_a", &Controller::Configuration::ChannelA)
|
||||
.def_readwrite("channel_b", &Controller::Configuration::ChannelB)
|
||||
.def_readwrite("decoding_correction_microticks", &Controller::Configuration::DecodingCorrectionMicroticks)
|
||||
.def_readwrite("delay_compensation_a_microticks", &Controller::Configuration::DelayCompensationAMicroticks)
|
||||
.def_readwrite("delay_compensation_b_microticks", &Controller::Configuration::DelayCompensationBMicroticks)
|
||||
.def_readwrite("extern_offset_correction_control", &Controller::Configuration::ExternOffsetCorrectionControl)
|
||||
.def_readwrite("extern_rate_correction_control", &Controller::Configuration::ExternRateCorrectionControl)
|
||||
.def_readwrite("extern_offset_correction_microticks", &Controller::Configuration::ExternOffsetCorrectionMicroticks)
|
||||
.def_readwrite("extern_rate_correction_microticks", &Controller::Configuration::ExternRateCorrectionMicroticks)
|
||||
.def_readwrite("key_slot_id", &Controller::Configuration::KeySlotID)
|
||||
.def_readwrite("key_slot_used_for_startup", &Controller::Configuration::KeySlotUsedForStartup)
|
||||
.def_readwrite("key_slot_used_for_sync", &Controller::Configuration::KeySlotUsedForSync)
|
||||
.def_readwrite("latest_tx_minislot", &Controller::Configuration::LatestTxMinislot)
|
||||
.def_readwrite("listen_timeout", &Controller::Configuration::ListenTimeout)
|
||||
.def_readwrite("macro_initial_offset_a", &Controller::Configuration::MacroInitialOffsetA)
|
||||
.def_readwrite("macro_initial_offset_b", &Controller::Configuration::MacroInitialOffsetB)
|
||||
.def_readwrite("micro_initial_offset_a", &Controller::Configuration::MicroInitialOffsetA)
|
||||
.def_readwrite("micro_initial_offset_b", &Controller::Configuration::MicroInitialOffsetB)
|
||||
.def_readwrite("micro_per_cycle", &Controller::Configuration::MicroPerCycle)
|
||||
.def_readwrite("mts_on_a", &Controller::Configuration::MTSOnA)
|
||||
.def_readwrite("mts_on_b", &Controller::Configuration::MTSOnB)
|
||||
.def_readwrite("offset_correction_out_microticks", &Controller::Configuration::OffsetCorrectionOutMicroticks)
|
||||
.def_readwrite("rate_correction_out_microticks", &Controller::Configuration::RateCorrectionOutMicroticks)
|
||||
.def_readwrite("second_key_slot_id", &Controller::Configuration::SecondKeySlotID)
|
||||
.def_readwrite("two_key_slot_mode", &Controller::Configuration::TwoKeySlotMode)
|
||||
.def_readwrite("wakeup_pattern", &Controller::Configuration::WakeupPattern)
|
||||
.def_readwrite("wakeup_on_channel_b", &Controller::Configuration::WakeupOnChannelB);
|
||||
|
||||
// Dummy class for cluster namespace
|
||||
pybind11::class_<ClusterNamespace> cluster(c, "Cluster");
|
||||
|
||||
pybind11::enum_<Cluster::SpeedType>(cluster, "SpeedType")
|
||||
.value("FLEXRAY_BAUDRATE_10M", Cluster::SpeedType::FLEXRAY_BAUDRATE_10M)
|
||||
.value("FLEXRAY_BAUDRATE_5M", Cluster::SpeedType::FLEXRAY_BAUDRATE_5M)
|
||||
.value("FLEXRAY_BAUDRATE_2M5", Cluster::SpeedType::FLEXRAY_BAUDRATE_2M5)
|
||||
.value("FLEXRAY_BAUDRATE_2M5_ALT", Cluster::SpeedType::FLEXRAY_BAUDRATE_2M5_ALT);
|
||||
|
||||
pybind11::enum_<Cluster::SPPType>(cluster, "SPPType")
|
||||
.value("FLEXRAY_SPP_5", Cluster::SPPType::FLEXRAY_SPP_5)
|
||||
.value("FLEXRAY_SPP_4", Cluster::SPPType::FLEXRAY_SPP_4)
|
||||
.value("FLEXRAY_SPP_6", Cluster::SPPType::FLEXRAY_SPP_6)
|
||||
.value("FLEXRAY_SPP_5_ALT", Cluster::SPPType::FLEXRAY_SPP_5_ALT);
|
||||
|
||||
pybind11::class_<Cluster::Configuration>(cluster, "Configuration")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("speed", &Cluster::Configuration::Speed)
|
||||
.def_readwrite("strobe_point_position", &Cluster::Configuration::StrobePointPosition)
|
||||
.def_readwrite("action_point_offset", &Cluster::Configuration::ActionPointOffset)
|
||||
.def_readwrite("casr_x_low_max", &Cluster::Configuration::CASRxLowMax)
|
||||
.def_readwrite("cold_start_attempts", &Cluster::Configuration::ColdStartAttempts)
|
||||
.def_readwrite("dynamic_slot_idle_phase_minislots", &Cluster::Configuration::DynamicSlotIdlePhaseMinislots)
|
||||
.def_readwrite("listen_noise_macroticks", &Cluster::Configuration::ListenNoiseMacroticks)
|
||||
.def_readwrite("macroticks_per_cycle", &Cluster::Configuration::MacroticksPerCycle)
|
||||
.def_readwrite("macrotick_duration_micro_sec", &Cluster::Configuration::MacrotickDurationMicroSec)
|
||||
.def_readwrite("max_without_clock_correction_fatal", &Cluster::Configuration::MaxWithoutClockCorrectionFatal)
|
||||
.def_readwrite("max_without_clock_correction_passive", &Cluster::Configuration::MaxWithoutClockCorrectionPassive)
|
||||
.def_readwrite("minislot_action_point_offset_macroticks", &Cluster::Configuration::MinislotActionPointOffsetMacroticks)
|
||||
.def_readwrite("minislot_duration_macroticks", &Cluster::Configuration::MinislotDurationMacroticks)
|
||||
.def_readwrite("network_idle_time_macroticks", &Cluster::Configuration::NetworkIdleTimeMacroticks)
|
||||
.def_readwrite("network_management_vector_length_bytes", &Cluster::Configuration::NetworkManagementVectorLengthBytes)
|
||||
.def_readwrite("number_of_minislots", &Cluster::Configuration::NumberOfMinislots)
|
||||
.def_readwrite("number_of_static_slots", &Cluster::Configuration::NumberOfStaticSlots)
|
||||
.def_readwrite("offset_correction_start_macroticks", &Cluster::Configuration::OffsetCorrectionStartMacroticks)
|
||||
.def_readwrite("payload_length_of_static_slot_in_words", &Cluster::Configuration::PayloadLengthOfStaticSlotInWords)
|
||||
.def_readwrite("static_slot_macroticks", &Cluster::Configuration::StaticSlotMacroticks)
|
||||
.def_readwrite("symbol_window_macroticks", &Cluster::Configuration::SymbolWindowMacroticks)
|
||||
.def_readwrite("symbol_window_action_point_offset_macroticks", &Cluster::Configuration::SymbolWindowActionPointOffsetMacroticks)
|
||||
.def_readwrite("sync_frame_id_count_max", &Cluster::Configuration::SyncFrameIDCountMax)
|
||||
.def_readwrite("transmission_start_sequence_duration_bits", &Cluster::Configuration::TransmissionStartSequenceDurationBits)
|
||||
.def_readwrite("wakeup_rx_idle_bits", &Cluster::Configuration::WakeupRxIdleBits)
|
||||
.def_readwrite("wakeup_rx_low_bits", &Cluster::Configuration::WakeupRxLowBits)
|
||||
.def_readwrite("wakeup_rx_window_bits", &Cluster::Configuration::WakeupRxWindowBits)
|
||||
.def_readwrite("wakeup_tx_active_bits", &Cluster::Configuration::WakeupTxActiveBits)
|
||||
.def_readwrite("wakeup_tx_idle_bits", &Cluster::Configuration::WakeupTxIdleBits);
|
||||
}
|
||||
|
||||
} // namespace FlexRay
|
||||
|
||||
void init_flexraymessage(pybind11::module_& m) {
|
||||
pybind11::class_<FlexRayMessage, std::shared_ptr<FlexRayMessage>, Frame>(m, "FlexRayMessage")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("slotid", &FlexRayMessage::slotid)
|
||||
.def_readwrite("tsslen", &FlexRayMessage::tsslen)
|
||||
.def_readwrite("framelen", &FlexRayMessage::framelen)
|
||||
.def_readwrite("symbol", &FlexRayMessage::symbol)
|
||||
.def_readwrite("header_crc_status", &FlexRayMessage::headerCRCStatus)
|
||||
.def_readwrite("header_crc", &FlexRayMessage::headerCRC)
|
||||
.def_readwrite("frame_crc_status", &FlexRayMessage::crcStatus)
|
||||
.def_readwrite("frame_crc", &FlexRayMessage::frameCRC)
|
||||
.def_readwrite("channel", &FlexRayMessage::channel)
|
||||
.def_readwrite("null_frame", &FlexRayMessage::nullFrame)
|
||||
.def_readwrite("payload_preamble", &FlexRayMessage::payloadPreamble)
|
||||
.def_readwrite("sync_frame", &FlexRayMessage::sync)
|
||||
.def_readwrite("startup_frame", &FlexRayMessage::startup)
|
||||
.def_readwrite("dynamic_frame", &FlexRayMessage::dynamic)
|
||||
.def_readwrite("cycle", &FlexRayMessage::cycle);
|
||||
|
||||
//// TODO: Eliminate FlexRayControlMessage class references in controller class and eliminate getStatus function in bindings
|
||||
}
|
||||
|
||||
void init_flexray(pybind11::module_& m) {
|
||||
// Dummy class to act as FlexRay namespace
|
||||
pybind11::class_<FlexRayNamespace> flexray(m, "FlexRay");
|
||||
|
||||
pybind11::enum_<FlexRayNamespace::Symbol>(flexray, "Symbol")
|
||||
.value("None", FlexRayNamespace::Symbol::None)
|
||||
.value("Unknown", FlexRayNamespace::Symbol::Unknown)
|
||||
.value("Wakeup", FlexRayNamespace::Symbol::Wakeup)
|
||||
.value("CAS", FlexRayNamespace::Symbol::CAS);
|
||||
pybind11::enum_<FlexRayNamespace::CRCStatus>(flexray, "CRCStatus")
|
||||
.value("OK", FlexRayNamespace::CRCStatus::OK)
|
||||
.value("Error", FlexRayNamespace::CRCStatus::Error)
|
||||
.value("NoCRC", FlexRayNamespace::CRCStatus::NoCRC);
|
||||
pybind11::enum_<FlexRayNamespace::Channel>(flexray, "Channel")
|
||||
.value("None", FlexRayNamespace::Channel::None)
|
||||
.value("A", FlexRayNamespace::Channel::A)
|
||||
.value("B", FlexRayNamespace::Channel::B)
|
||||
.value("AB", FlexRayNamespace::Channel::AB);
|
||||
|
||||
init_flexraymessage(m);
|
||||
FlexRay::init_extension(flexray);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
|
|
@ -24,11 +24,12 @@ void init_ethernetstatusmessage(pybind11::module_&);
|
|||
void init_macsecmessage(pybind11::module_&);
|
||||
void init_scriptstatusmessage(pybind11::module_&);
|
||||
void init_diskdriver(pybind11::module_&);
|
||||
void init_deviceextension(pybind11::module_&);
|
||||
void init_device(pybind11::module_&);
|
||||
void init_messagefilter(pybind11::module_&);
|
||||
void init_messagecallback(pybind11::module_&);
|
||||
void init_version(pybind11::module_&);
|
||||
void init_flexraymessage(pybind11::module_& m);
|
||||
void init_flexray(pybind11::module_& m);
|
||||
void init_idevicesettings(pybind11::module_&);
|
||||
|
||||
PYBIND11_MODULE(icsneopy, m) {
|
||||
|
|
@ -57,8 +58,9 @@ PYBIND11_MODULE(icsneopy, m) {
|
|||
init_messagefilter(m);
|
||||
init_messagecallback(m);
|
||||
init_diskdriver(m);
|
||||
init_flexray(m);
|
||||
init_device(m);
|
||||
init_flexraymessage(m);
|
||||
init_deviceextension(m);
|
||||
init_idevicesettings(m);
|
||||
|
||||
m.def("find_all_devices", &FindAllDevices);
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
using namespace icsneo;
|
||||
|
||||
std::vector<uint8_t> FlexRayControlMessage::BuildBaseControlArgs(uint8_t controller, FlexRay::Opcode op, const std::vector<uint8_t>& args) {
|
||||
std::vector<uint8_t> ret(args.size() + 4);
|
||||
std::vector<uint8_t> ret;
|
||||
ret.push_back(controller);
|
||||
const uint16_t size = uint16_t((std::min)(args.size() + 1, size_t(std::numeric_limits<uint16_t>::max()))); // Add 1 for the opcode
|
||||
const uint16_t size = static_cast<uint16_t>(std::min(args.size() + 1, size_t(std::numeric_limits<uint16_t>::max()))); // Add 1 for the opcode
|
||||
ret.push_back(uint8_t(size));
|
||||
ret.push_back(uint8_t(size >> 8));
|
||||
ret.push_back(uint8_t(op));
|
||||
|
|
|
|||
|
|
@ -3,16 +3,6 @@
|
|||
|
||||
using namespace icsneo;
|
||||
|
||||
void FlexRay::Controller::_setStatus(std::shared_ptr<FlexRayControlMessage> msg) {
|
||||
std::lock_guard<std::mutex> lk(statusLock);
|
||||
status = msg;
|
||||
}
|
||||
|
||||
std::shared_ptr<FlexRayControlMessage> FlexRay::Controller::getStatus() const {
|
||||
std::lock_guard<std::mutex> lk(statusLock);
|
||||
return status;
|
||||
}
|
||||
|
||||
std::pair<const FlexRay::Cluster::Configuration&, const FlexRay::Controller::Configuration&> FlexRay::Controller::getConfiguration() const {
|
||||
return { clusterConfig, controllerConfig };
|
||||
}
|
||||
|
|
@ -74,7 +64,7 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
|
|||
((controllerConfig.KeySlotUsedForStartup & 0x1) << 8) | // TXST
|
||||
((controllerConfig.KeySlotUsedForSync & 0x1) << 9) | // TXSY
|
||||
((clusterConfig.ColdStartAttempts & 0x1f) << 11) | // CSA
|
||||
((controllerConfig.AllowPassiveToActiveCyclePairs & 0x1f) << 16) | // PTA
|
||||
((controllerConfig.AllowPassiveToActiveCyclePairs & 0x1F) << 16) | // PTA
|
||||
((controllerConfig.WakeupOnChannelB & 0x1) << 21) | // WUCS
|
||||
((controllerConfig.KeySlotOnlyEnabled & 0x1) << 22) | // TSM
|
||||
((controllerConfig.AllowHaltDueToClock & 0x1) << 23) | // HCSE
|
||||
|
|
@ -85,99 +75,100 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
|
|||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::SUCC2,
|
||||
((controllerConfig.ListenTimeout & 0x1fffff)) |
|
||||
((clusterConfig.ListenNoiseMacroticks - 1) << 24)
|
||||
((controllerConfig.ListenTimeout & 0x1FFFFF)) |
|
||||
(((clusterConfig.ListenNoiseMacroticks - 1) & 0xF) << 24)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::SUCC3,
|
||||
(clusterConfig.MaxWithoutClockCorrectionPassive & 0xF) |
|
||||
((clusterConfig.MaxWithoutClockCorrectionFatal) << 4)
|
||||
((clusterConfig.MaxWithoutClockCorrectionFatal & 0xF) << 4)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::NEMC,
|
||||
clusterConfig.NetworkManagementVectorLengthBytes
|
||||
clusterConfig.NetworkManagementVectorLengthBytes & 0xF
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::PRTC1,
|
||||
(clusterConfig.TransmissionStartSequenceDurationBits & 0xF) |
|
||||
((clusterConfig.CASRxLowMax & 0x3F) << 4) |
|
||||
((clusterConfig.CASRxLowMax & 0x1F) << 4) |
|
||||
(0x1 << 10) | // Most significant bit of CASRxLowMax. Hardwired to 1 and cannot be modified
|
||||
((clusterConfig.StrobePointPosition & 0x3) << 12) |
|
||||
((clusterConfig.Speed & 0x3) << 14) |
|
||||
((clusterConfig.WakeupRxWindowBits & 0x1ff) << 16) |
|
||||
((controllerConfig.WakeupPattern) << 26)
|
||||
((clusterConfig.WakeupRxWindowBits & 0x1FF) << 16) |
|
||||
((controllerConfig.WakeupPattern & 0x3F) << 26)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::PRTC2,
|
||||
(clusterConfig.WakeupRxIdleBits) |
|
||||
((clusterConfig.WakeupRxLowBits) << 8) |
|
||||
(clusterConfig.WakeupRxIdleBits & 0x3F) |
|
||||
((clusterConfig.WakeupRxLowBits & 0x3F) << 8) |
|
||||
((clusterConfig.WakeupTxIdleBits) << 16) |
|
||||
((clusterConfig.WakeupTxActiveBits) << 24)
|
||||
((clusterConfig.WakeupTxActiveBits & 0x3F) << 24)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::MHDC,
|
||||
(clusterConfig.PayloadLengthOfStaticSlotInWords) |
|
||||
((controllerConfig.LatestTxMinislot) << 16)
|
||||
(clusterConfig.PayloadLengthOfStaticSlotInWords & 0x7F) |
|
||||
((controllerConfig.LatestTxMinislot & 0x1FFF) << 16)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC1,
|
||||
controllerConfig.MicroPerCycle
|
||||
controllerConfig.MicroPerCycle & 0xFFFFF
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC2,
|
||||
(clusterConfig.SyncFrameIDCountMax << 16) |
|
||||
clusterConfig.MacroticksPerCycle
|
||||
(clusterConfig.MacroticksPerCycle & 0x3FFF)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC3,
|
||||
(controllerConfig.MicroInitialOffsetA) |
|
||||
((controllerConfig.MicroInitialOffsetB) << 8) |
|
||||
((controllerConfig.MacroInitialOffsetA) << 16) |
|
||||
((controllerConfig.MacroInitialOffsetB) << 24)
|
||||
((controllerConfig.MacroInitialOffsetA & 0x7F) << 16) |
|
||||
((controllerConfig.MacroInitialOffsetB & 0x7F) << 24)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC4,
|
||||
((clusterConfig.MacroticksPerCycle - clusterConfig.NetworkIdleTimeMacroticks - 1) & 0xFFFF) |
|
||||
((clusterConfig.OffsetCorrectionStartMacroticks - 1) << 16)
|
||||
((clusterConfig.MacroticksPerCycle - clusterConfig.NetworkIdleTimeMacroticks - 1) & 0x3FFF) |
|
||||
(((clusterConfig.OffsetCorrectionStartMacroticks - 1) & 0x3FFF) << 16)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC5,
|
||||
controllerConfig.DelayCompensationAMicroticks |
|
||||
(controllerConfig.DelayCompensationBMicroticks << 8) |
|
||||
(controllerConfig.ClusterDriftDamping << 16) |
|
||||
((controllerConfig.ClusterDriftDamping & 0x1F) << 16) |
|
||||
(controllerConfig.DecodingCorrectionMicroticks << 24)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC6,
|
||||
controllerConfig.AcceptStartupRangeMicroticks |
|
||||
(controllerConfig.RateCorrectionOutMicroticks << 16)
|
||||
(controllerConfig.AcceptStartupRangeMicroticks & 0x7FF) |
|
||||
((controllerConfig.RateCorrectionOutMicroticks & 0x7FF) << 16)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC7,
|
||||
(clusterConfig.StaticSlotMacroticks) |
|
||||
(clusterConfig.NumberOfStaticSlots << 16)
|
||||
(clusterConfig.StaticSlotMacroticks & 0x3FF) |
|
||||
((clusterConfig.NumberOfStaticSlots & 0x3FF) << 16)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC8,
|
||||
clusterConfig.MinislotDurationMacroticks |
|
||||
(clusterConfig.NumberOfMinislots << 16)
|
||||
(clusterConfig.MinislotDurationMacroticks & 0x3F) |
|
||||
((clusterConfig.NumberOfMinislots & 0x1FFF) << 16)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC9,
|
||||
clusterConfig.ActionPointOffset |
|
||||
(clusterConfig.MinislotActionPointOffsetMacroticks << 8) |
|
||||
(clusterConfig.DynamicSlotIdlePhaseMinislots << 16)
|
||||
(clusterConfig.ActionPointOffset & 0x3F) |
|
||||
((clusterConfig.MinislotActionPointOffsetMacroticks & 0x1F) << 8) |
|
||||
((clusterConfig.DynamicSlotIdlePhaseMinislots & 0x03) << 16)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC10,
|
||||
controllerConfig.OffsetCorrectionOutMicroticks |
|
||||
(controllerConfig.RateCorrectionOutMicroticks << 16)
|
||||
(controllerConfig.OffsetCorrectionOutMicroticks & 0x3FFF) |
|
||||
((controllerConfig.RateCorrectionOutMicroticks & 0x7FF) << 16)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC11,
|
||||
controllerConfig.ExternOffsetCorrectionControl |
|
||||
(controllerConfig.ExternRateCorrectionControl << 8) |
|
||||
(controllerConfig.ExternOffsetCorrectionMicroticks << 16) |
|
||||
(controllerConfig.ExternRateCorrectionMicroticks << 24)
|
||||
(controllerConfig.ExternOffsetCorrectionControl & 0x3) |
|
||||
((controllerConfig.ExternRateCorrectionControl & 0x3) << 8) |
|
||||
((controllerConfig.ExternOffsetCorrectionMicroticks & 0x7) << 16) |
|
||||
((controllerConfig.ExternRateCorrectionMicroticks & 0x7) << 24)
|
||||
});
|
||||
|
||||
std::vector<std::shared_ptr<MessageBuffer>> staticTx;
|
||||
|
|
@ -266,7 +257,7 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
|
|||
totalBuffers = 128;
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::MRC,
|
||||
(uint8_t(staticTx.size())) | // FDB[7:0] message buffers exclusively for the static segment
|
||||
(static_cast<uint8_t>(staticTx.size())) | // FDB[7:0] message buffers exclusively for the static segment
|
||||
// FFB[7:0] set to 0x80, No message buffer assigned to the FIFO
|
||||
(0x80 << 8) |
|
||||
(uint8_t(totalBuffers - 1) << 16) |
|
||||
|
|
@ -287,12 +278,12 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
|
|||
buf.frameID = static_cast<uint16_t>(i | (1 << 10));
|
||||
|
||||
uint32_t hs1 = (
|
||||
(buf.frameID) |
|
||||
(CalculateCycleFilter(buf.baseCycle, buf.cycleRepetition) << 16) |
|
||||
((buf.channelA & 0x1) << 24) |
|
||||
((buf.channelB & 0x1) << 25) |
|
||||
(buf.frameID) | // FID
|
||||
(CalculateCycleFilter(buf.baseCycle, buf.cycleRepetition) << 16) | // CYA
|
||||
((buf.channelA & 0x1) << 24) | // CHA
|
||||
((buf.channelB & 0x1) << 25) | // CHB
|
||||
((buf.isTransmit & 0x1) << 26) | // CFG
|
||||
((buf.isNMFrame & 0x1) << 27) | // PPIT
|
||||
((buf.isNetworkManagementFrame & 0x1) << 27) | // PPIT
|
||||
((!buf.continuousMode & 0x1) << 28) | // TXM
|
||||
((0 & 0x1) << 29) // MBI, disabled for now but we might want confirmations in the future
|
||||
);
|
||||
|
|
@ -610,7 +601,8 @@ uint16_t FlexRay::Controller::CalculateCycleFilter(uint8_t baseCycle, uint8_t cy
|
|||
}
|
||||
|
||||
std::pair<bool, uint32_t> FlexRay::Controller::readRegister(ERAYRegister reg, std::chrono::milliseconds timeout) const {
|
||||
static const std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(icsneo::Network::NetID::FlexRayControl);
|
||||
static const std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>();
|
||||
filter->includeInternalInAny = true;
|
||||
if(timeout.count() <= 20)
|
||||
return {false, 0}; // Out of time!
|
||||
|
||||
|
|
|
|||
|
|
@ -25,26 +25,6 @@ void FlexRay::Extension::onGoOffline() {
|
|||
controller->halt();
|
||||
}
|
||||
|
||||
void FlexRay::Extension::handleMessage(const std::shared_ptr<Message>& message) {
|
||||
switch(message->type) {
|
||||
case Message::Type::FlexRayControl: {
|
||||
auto msg = std::dynamic_pointer_cast<FlexRayControlMessage>(message);
|
||||
if(!msg || !msg->decoded)
|
||||
return;
|
||||
switch(msg->opcode) {
|
||||
case FlexRay::Opcode::ReadCCStatus:
|
||||
if(msg->controller >= controllers.size())
|
||||
return; // TODO error
|
||||
controllers[msg->controller]->_setStatus(msg);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool FlexRay::Extension::transmitHook(const std::shared_ptr<Frame>& frame, bool& success) {
|
||||
if(!frame || frame->network.getType() != Network::Type::FlexRay)
|
||||
return true; // Don't hook non-FlexRay messages
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ option(LIBICSNEO_BUILD_CPP_COREMINI_EXAMPLE "Build the Coremini example." ON)
|
|||
option(LIBICSNEO_BUILD_CPP_MDIO_EXAMPLE "Build the MDIO example." ON)
|
||||
option(LIBICSNEO_BUILD_CPP_VSA_EXAMPLE "Build the VSA example." ON)
|
||||
option(LIBICSNEO_BUILD_CPP_APP_ERROR_EXAMPLE "Build the app error example." ON)
|
||||
option(LIBICSNEO_BUILD_CPP_FLEXRAY_EXAMPLE "Build the FlexRay example." ON)
|
||||
|
||||
if(LIBICSNEO_BUILD_C_INTERACTIVE_EXAMPLE)
|
||||
add_subdirectory(c/interactive)
|
||||
|
|
@ -58,3 +59,7 @@ endif()
|
|||
if(LIBICSNEO_BUILD_CPP_APP_ERROR_EXAMPLE)
|
||||
add_subdirectory(cpp/apperror)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_CPP_FLEXRAY_EXAMPLE)
|
||||
add_subdirectory(cpp/flexray)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
add_executable(libicsneocpp-flexray-example src/FlexRayExample.cpp)
|
||||
target_link_libraries(libicsneocpp-flexray-example icsneocpp)
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
#include <iostream>
|
||||
#include <random>
|
||||
|
||||
#include "icsneo/icsneocpp.h"
|
||||
#include "icsneo/device/extensions/flexray/cluster.h"
|
||||
|
||||
/* Modifiable Configuration Variables*/
|
||||
|
||||
static size_t NumMessages = 300;
|
||||
static size_t FramePayloadSize = 134;
|
||||
static uint16_t SlotOne = 1;
|
||||
static uint16_t SlotTwo = 3;
|
||||
static bool SuppressRxTxDebugMessages = true;
|
||||
|
||||
static const icsneo::FlexRay::Controller::Configuration DefaultControllerConfig {
|
||||
160, // uint16_t AcceptStartupRangeMicroticks INIT(0); // pdAcceptedStartupRange
|
||||
true, // bool AllowHaltDueToClock INIT(false); // pAllowHaltDueToClock
|
||||
|
||||
15, // uint8_t AllowPassiveToActiveCyclePairs INIT(0); // pAllowPassiveToActive
|
||||
|
||||
2, // uint8_t ClusterDriftDamping INIT(0); // pClusterDriftDamping
|
||||
|
||||
true, // bool ChannelA INIT(false); // pChannels
|
||||
true, // bool ChannelB INIT(false); // pChannels
|
||||
|
||||
56, // uint8_t DecodingCorrectionMicroticks INIT(0); // pDecodingCorrection
|
||||
28, // uint8_t DelayCompensationAMicroticks INIT(0); // pDelayCompensation[A]
|
||||
28, // uint8_t DelayCompensationBMicroticks INIT(0); // pDelayCompensation[B]
|
||||
0, // uint8_t ExternOffsetCorrectionControl INIT(0); // pExternOffsetControl
|
||||
0, // uint8_t ExternRateCorrectionControl INIT(0); // pExternRateControl
|
||||
0, // uint8_t ExternOffsetCorrectionMicroticks INIT(0); // pExternOffsetCorrection
|
||||
0, // uint8_t ExternRateCorrectionMicroticks INIT(0); // pExternRateCorrection
|
||||
|
||||
0, // uint16_t KeySlotID INIT(0);
|
||||
|
||||
false, // bool KeySlotOnlyEnabled INIT(false); // pSingleSlotEnabled (TSM)
|
||||
true, // bool KeySlotUsedForStartup INIT(false); // pKeySlotUsedForStartup (TXST)
|
||||
true, // bool KeySlotUsedForSync INIT(false); // pKeySlotUsedForSync (TXSY)
|
||||
|
||||
226, // uint16_t LatestTxMinislot INIT(0); // pLatestTx
|
||||
401202, // uint32_t ListenTimeout INIT(0); // pdListenTimeout
|
||||
|
||||
7, // uint8_t MacroInitialOffsetA INIT(0); // pMacroInitialOffset[A], Valid 2..72
|
||||
7, // uint8_t MacroInitialOffsetB INIT(0); // pMacroInitialOffset[B], Valid 2..72
|
||||
|
||||
36, // uint8_t MicroInitialOffsetA INIT(0); // pMicroInitialOffset[A], Valid 0..240
|
||||
36, // uint8_t MicroInitialOffsetB INIT(0); // pMicroInitialOffset[B], Valid 0..240
|
||||
|
||||
200000, // uint32_t MicroPerCycle INIT(0); // pMicroPerCycle
|
||||
|
||||
false, // bool MTSOnA INIT(false);
|
||||
false, // bool MTSOnB INIT(false);
|
||||
|
||||
189, // uint16_t OffsetCorrectionOutMicroticks INIT(0); // pOffsetCorrectionOut
|
||||
601, // uint16_t RateCorrectionOutMicroticks INIT(0); // pdMaxDrift and pRateCorrectionOut
|
||||
|
||||
0, // uint16_t SecondKeySlotID INIT(0);
|
||||
false, // bool TwoKeySlotMode INIT(false);
|
||||
|
||||
55, // uint8_t WakeupPattern INIT(0);
|
||||
false, // bool WakeupOnChannelB INIT(false); // pWakeupChannel
|
||||
};
|
||||
|
||||
namespace Cluster = icsneo::FlexRay::Cluster;
|
||||
|
||||
static const Cluster::Configuration DefaultClusterConfig {
|
||||
Cluster::SpeedType::FLEXRAY_BAUDRATE_10M, // neoflexray_speed_t Speed INIT(FLEXRAY_BAUDRATE_10M /* = 0 */); // gdSampleClockPeriod, pSamplesPerMicrotick, Baud Rate Prescaler
|
||||
Cluster::SPPType::FLEXRAY_SPP_5, // neoflexray_spp_t StrobePointPosition INIT(FLEXRAY_SPP_5 /* = 0 */);
|
||||
|
||||
4, // uint8_t ActionPointOffset INIT(0); // gdActionPointOffset
|
||||
64, // uint8_t CASRxLowMax INIT(0); // gdCASRxLowMax
|
||||
8, // uint8_t ColdStartAttempts INIT(0); // gColdStartAttempts
|
||||
5000, // uint16_t CycleDurationMicroSec INIT(0); // gdCycle
|
||||
1, // uint8_t DynamicSlotIdlePhaseMinislots INIT(0); // gdDynamicSlotIdlePhase, In Minislot increments [0..2]
|
||||
4, // uint8_t ListenNoiseMacroticks INIT(0); // gListenNoise
|
||||
5000, // uint16_t MacroticksPerCycle INIT(0); // gMacroPerCycle
|
||||
1, // uint8_t MacrotickDurationMicroSec INIT(0); // gdMacroTick
|
||||
2, // uint8_t MaxWithoutClockCorrectionFatal INIT(0); // gMaxWithoutClockCorrectionFatal
|
||||
2, // uint8_t MaxWithoutClockCorrectionPassive INIT(0); // gMaxWithoutClockCorrectionPassive
|
||||
4, // uint8_t MinislotActionPointOffsetMacroticks INIT(0); // gdMinislotActionPointOffset
|
||||
10, // uint32_t MinislotDurationMacroticks INIT(0); // gdMinislot
|
||||
40, // uint32_t NetworkIdleTimeMacroticks INIT(0); // gdNIT
|
||||
1, // uint8_t NetworkManagementVectorLengthBytes INIT(0); // gNetworkManagementVectorLength
|
||||
0, // uint32_t NumberOfMinislots INIT(0); // gNumberOfMinislots
|
||||
32, // uint16_t NumberOfStaticSlots INIT(0); // gdNumberOfStaticSlots
|
||||
4991, // uint32_t OffsetCorrectionStartMacroticks INIT(0); // gOffsetCorrectionStart
|
||||
67, // uint8_t PayloadLengthOfStaticSlotInWords INIT(0); // gPayloadLengthStatic
|
||||
|
||||
155, // uint16_t StaticSlotMacroticks INIT(0); // gdStaticSlot
|
||||
0, // uint32_t SymbolWindowMacroticks INIT(0); // gdSymbolWindow
|
||||
0, // uint32_t SymbolWindowActionPointOffsetMacroticks INIT(0);
|
||||
15, // uint16_t SyncFrameIDCountMax INIT(0); // gSyncNodeMax
|
||||
|
||||
11, // uint8_t TransmissionStartSequenceDurationBits INIT(0); // gdTSSTransmitter
|
||||
40, // uint8_t WakeupRxIdleBits INIT(0); // gdWakeupSymbolRxIdle
|
||||
40, // uint8_t WakeupRxLowBits INIT(0); // gdWakeupSymbolRxLow
|
||||
301, // uint16_t WakeupRxWindowBits INIT(0); // gdWakeupSymbolRxWindow
|
||||
60, // uint8_t WakeupTxActiveBits INIT(0); // gdWakeupSymbolTxLow (active = low here)
|
||||
180, // uint8_t WakeupTxIdleBits INIT(0); // gdWakeupSymbolTxIdle
|
||||
};
|
||||
|
||||
static std::condition_variable cv;
|
||||
static std::mutex msgRcvdMutex;
|
||||
|
||||
void configureFlexRayDevice(std::shared_ptr<icsneo::Device> device) {
|
||||
auto controllers = device->getFlexRayControllers();
|
||||
for (uint16_t i = 0; i < controllers.size(); i++) {
|
||||
auto controller = controllers[i];
|
||||
icsneo::FlexRay::Cluster::Configuration clusterConfig = DefaultClusterConfig;
|
||||
icsneo::FlexRay::Controller::Configuration controllerConfig = DefaultControllerConfig;
|
||||
controller->setAllowColdstart(true);
|
||||
controllerConfig.KeySlotID = (i == 0) ? SlotOne : SlotTwo;
|
||||
controller->setConfiguration(clusterConfig, controllerConfig);
|
||||
controller->setStartWhenGoingOnline(true);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<icsneo::FlexRayMessage>> makeDummyFlexRayMessages(size_t msgCount, size_t msgLen) {
|
||||
std::vector<std::shared_ptr<icsneo::FlexRayMessage>> messages;
|
||||
messages.reserve(msgCount);
|
||||
std::random_device rd;
|
||||
std::mt19937 engine(rd());
|
||||
std::uniform_int_distribution<unsigned short> dist(0, 255);
|
||||
for (size_t i = 0; i < msgCount; i++) {
|
||||
auto msg = std::make_shared<icsneo::FlexRayMessage>();
|
||||
msg->network = icsneo::Network::NetID::FLEXRAY_01;
|
||||
msg->cycleRepetition = 1;
|
||||
msg->channel = icsneo::FlexRay::Channel::AB;
|
||||
msg->data.reserve(msgLen);
|
||||
for (size_t j = 0; j < msgLen; j++) {
|
||||
msg->data.push_back(static_cast<uint8_t>(dist(engine)));
|
||||
}
|
||||
msg->slotid = (i % 2 == 0) ? SlotOne : SlotTwo;
|
||||
messages.push_back(msg);
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
|
||||
int main() {
|
||||
auto devices = icsneo::FindAllDevices();
|
||||
std::shared_ptr<icsneo::Device> flexrayDevice = nullptr;
|
||||
for (auto&& device : devices) {
|
||||
if (device->getExtension("FlexRay")) {
|
||||
flexrayDevice = device;
|
||||
}
|
||||
}
|
||||
|
||||
if (flexrayDevice) {
|
||||
std::cout << "Found device " << flexrayDevice->getProductName() << " " << flexrayDevice->getSerial() << " which supports FlexRay." << std::endl;
|
||||
auto&& controllers = flexrayDevice->getFlexRayControllers();
|
||||
if (controllers.size() > 0) {
|
||||
std::vector<std::shared_ptr<icsneo::FlexRayMessage>> messages;
|
||||
size_t currentMessage = 0;
|
||||
auto filter = std::make_shared<icsneo::MessageFilter>(icsneo::Network::NetID::FLEXRAY_01);
|
||||
auto rxCallback = [&messages, ¤tMessage](std::shared_ptr<icsneo::Message> message) -> void {
|
||||
std::unique_lock lk(msgRcvdMutex);
|
||||
auto frmsg = std::static_pointer_cast<icsneo::FlexRayMessage>(message);
|
||||
if (currentMessage < messages.size() && frmsg->data.size() > 1 && frmsg->data == messages[currentMessage]->data) {
|
||||
if (!SuppressRxTxDebugMessages) {
|
||||
std::cout << "Message Number " << currentMessage + 1 << " received." << std::endl;
|
||||
}
|
||||
currentMessage++;
|
||||
lk.unlock();
|
||||
cv.notify_all();
|
||||
}
|
||||
};
|
||||
|
||||
auto cb = std::make_shared<icsneo::MessageCallback>(rxCallback, filter);
|
||||
auto cbId = flexrayDevice->addMessageCallback(cb);
|
||||
messages = makeDummyFlexRayMessages(NumMessages, FramePayloadSize);
|
||||
configureFlexRayDevice(flexrayDevice);
|
||||
if (!flexrayDevice->open()) {
|
||||
std::cerr << "Device open failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
if (!flexrayDevice->goOnline()) {
|
||||
std::cerr << "Device go online failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::cout << "Transmitting " << NumMessages << " FlexRay frames." << std::endl;
|
||||
for (auto msg : messages) {
|
||||
std::unique_lock lk(msgRcvdMutex);
|
||||
if (!flexrayDevice->transmit(msg)) {
|
||||
std::cerr << "Failed to transmit message." << std::endl;
|
||||
return -1;
|
||||
} else if (!SuppressRxTxDebugMessages) {
|
||||
std::cout << "Message Number " << currentMessage + 1 << " transmitted." << std::endl;
|
||||
}
|
||||
|
||||
cv.wait(lk);
|
||||
lk.unlock();
|
||||
}
|
||||
std::cout << "All transmitted frames received." << std::endl;
|
||||
flexrayDevice->removeMessageCallback(cbId);
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Unable to find a device which supports FlexRay." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cout << "Finished." << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -10,8 +10,6 @@
|
|||
|
||||
namespace icsneo {
|
||||
|
||||
class Device;
|
||||
|
||||
class DeviceExtension {
|
||||
public:
|
||||
DeviceExtension(Device& device) : device(device) {}
|
||||
|
|
|
|||
|
|
@ -21,14 +21,14 @@ typedef enum {
|
|||
FLEXRAY_BAUDRATE_5M = 1, // 5Mbit currently not supported in the monitor
|
||||
FLEXRAY_BAUDRATE_2M5 = 2, // 2.5Mbit currently not supported in the monitor
|
||||
FLEXRAY_BAUDRATE_2M5_ALT = 3 // Per the ERAY spec, 0b11 also means 2.5MBits
|
||||
} neoflexray_speed_t;
|
||||
} SpeedType;
|
||||
|
||||
typedef enum {
|
||||
FLEXRAY_SPP_5 = 0, // FlexRay 2.1 requires this value to be 0
|
||||
FLEXRAY_SPP_4 = 1,
|
||||
FLEXRAY_SPP_6 = 2,
|
||||
FLEXRAY_SPP_5_ALT = 3 // Per the ERAY spec, 0b11 also means sample point 5
|
||||
} neoflexray_spp_t;
|
||||
} SPPType;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
|
|
@ -48,50 +48,39 @@ typedef struct {
|
|||
|
||||
#endif // __cplusplus
|
||||
|
||||
neoflexray_speed_t Speed INIT(FLEXRAY_BAUDRATE_10M /* = 0 */); // gdSampleClockPeriod, pSamplesPerMicrotick, Baud Rate Prescaler
|
||||
neoflexray_spp_t StrobePointPosition INIT(FLEXRAY_SPP_5 /* = 0 */);
|
||||
SpeedType Speed INIT(FLEXRAY_BAUDRATE_10M /* = 0 */); // gdSampleClockPeriod, pSamplesPerMicrotick, Baud Rate Prescaler
|
||||
SPPType StrobePointPosition INIT(FLEXRAY_SPP_5 /* = 0 */);
|
||||
|
||||
uint8_t ActionPointOffset INIT(0);
|
||||
uint32_t BitTimeNS INIT(0);
|
||||
uint8_t CASRxLowMax INIT(0);
|
||||
uint8_t ColdStartAttempts INIT(0);
|
||||
uint32_t CycleCountMax INIT(0);
|
||||
double CycleDurationSec INIT(0);
|
||||
bool DetectNITError INIT(false);
|
||||
uint8_t DynamicSlotIdlePhaseMinislots INIT(0); // In Minislot increments [0..2]
|
||||
uint32_t IgnoreAfterTx INIT(0);
|
||||
uint8_t ListenNoiseMacroticks INIT(0);
|
||||
uint16_t MacroticksPerCycle INIT(0);
|
||||
double MacrotickDurationSec INIT(0);
|
||||
uint8_t MaxWithoutClockCorrectionFatal INIT(0);
|
||||
uint8_t MaxWithoutClockCorrectionPassive INIT(0);
|
||||
uint8_t MinislotActionPointOffsetMacroticks INIT(0);
|
||||
uint32_t MinislotDurationMacroticks INIT(0); // gdMinislot
|
||||
uint32_t NetworkIdleTimeMacroticks INIT(0);
|
||||
uint8_t NetworkManagementVectorLengthBytes INIT(0);
|
||||
uint32_t NumberOfMinislots INIT(0);
|
||||
uint16_t NumberOfStaticSlots INIT(0);
|
||||
uint32_t OffsetCorrectionStartMacroticks INIT(0);
|
||||
uint8_t PayloadLengthOfStaticSlotInWords INIT(0);
|
||||
uint32_t SafetyMarginMacroticks INIT(0);
|
||||
|
||||
double SampleClockPeriodSec INIT(0);
|
||||
bool UseSampleClockPeriodSec INIT(false);
|
||||
uint8_t ActionPointOffset INIT(0); // gdActionPointOffset
|
||||
uint8_t CASRxLowMax INIT(0); // gdCASRxLowMax
|
||||
uint8_t ColdStartAttempts INIT(0); // gColdStartAttempts
|
||||
uint16_t CycleDurationMicroSec INIT(0); // gdCycle
|
||||
uint8_t DynamicSlotIdlePhaseMinislots INIT(0); // gdDynamicSlotIdlePhase, In Minislot increments [0..2]
|
||||
uint8_t ListenNoiseMacroticks INIT(0); // gListenNoise
|
||||
uint16_t MacroticksPerCycle INIT(0); // gMacroPerCycle
|
||||
uint8_t MacrotickDurationMicroSec INIT(0); // gdMacroTick
|
||||
uint8_t MaxWithoutClockCorrectionFatal INIT(0); // gMaxWithoutClockCorrectionFatal
|
||||
uint8_t MaxWithoutClockCorrectionPassive INIT(0); // gMaxWithoutClockCorrectionPassive
|
||||
uint8_t MinislotActionPointOffsetMacroticks INIT(0); // gdMinislotActionPointOffset
|
||||
uint8_t MinislotDurationMacroticks INIT(0); // gdMinislot
|
||||
uint16_t NetworkIdleTimeMacroticks INIT(0); // gdNIT
|
||||
uint8_t NetworkManagementVectorLengthBytes INIT(0); // gNetworkManagementVectorLength
|
||||
uint16_t NumberOfMinislots INIT(0); // gNumberOfMinislots
|
||||
uint16_t NumberOfStaticSlots INIT(0); // gNumberOfStaticSlots
|
||||
uint16_t OffsetCorrectionStartMacroticks INIT(0); // gOffsetCorrectionStart
|
||||
uint8_t PayloadLengthOfStaticSlotInWords INIT(0); // gPayloadLengthStatic
|
||||
|
||||
uint16_t StaticSlotMacroticks INIT(0); // gdStaticSlot
|
||||
uint32_t SymbolWindowMacroticks INIT(0);
|
||||
uint32_t SymbolWindowMacroticks INIT(0); // gdSymbolWindow
|
||||
uint32_t SymbolWindowActionPointOffsetMacroticks INIT(0);
|
||||
uint16_t SyncFrameIDCountMax INIT(0); // gSyncNodeMax
|
||||
|
||||
double TransceiverStandbyDelaySec INIT(false);
|
||||
bool UseTransceiverStandbyDelaySec INIT(0);
|
||||
uint8_t SyncFrameIDCountMax INIT(0); // gSyncNodeMax
|
||||
|
||||
uint8_t TransmissionStartSequenceDurationBits INIT(0); // gdTSSTransmitter
|
||||
uint8_t WakeupRxIdleBits INIT(0);
|
||||
uint8_t WakeupRxLowBits INIT(0);
|
||||
uint8_t WakeupRxIdleBits INIT(0); // gdWakeupSymbolRxIdle
|
||||
uint8_t WakeupRxLowBits INIT(0); // gdWakeupSymbolRxLow
|
||||
uint16_t WakeupRxWindowBits INIT(0); // gdWakeupSymbolRxWindow
|
||||
uint8_t WakeupTxActiveBits INIT(0); // gdWakeupSymbolTxLow (active = low here)
|
||||
uint8_t WakeupTxIdleBits INIT(0);
|
||||
uint8_t WakeupTxIdleBits INIT(0); // gdWakeupSymbolTxIdle
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
|
|
|
|||
|
|
@ -26,11 +26,8 @@ namespace FlexRay {
|
|||
class Controller {
|
||||
public:
|
||||
Controller(Device& device, uint8_t index, Network net) : device(device), index(index), network(net) {}
|
||||
void _setStatus(std::shared_ptr<FlexRayControlMessage> msg);
|
||||
|
||||
// Begin Public Interface
|
||||
std::shared_ptr<FlexRayControlMessage> getStatus() const;
|
||||
|
||||
const Network& getNetwork() const { return network; }
|
||||
|
||||
struct Configuration; // Forward declaration
|
||||
|
|
@ -104,7 +101,6 @@ private:
|
|||
Network network;
|
||||
mutable std::mutex statusLock;
|
||||
mutable std::mutex readRegisterLock;
|
||||
std::shared_ptr<FlexRayControlMessage> status;
|
||||
bool startWhenGoingOnline = false;
|
||||
bool allowColdstart = false;
|
||||
bool wakeupBeforeStart = false;
|
||||
|
|
@ -124,29 +120,23 @@ public:
|
|||
typedef struct {
|
||||
#endif // __cplusplus
|
||||
|
||||
uint16_t AcceptStartupRangeMicroticks INIT(0);
|
||||
bool AllowHaltDueToClock INIT(false);
|
||||
uint16_t AcceptStartupRangeMicroticks INIT(0); // pdAcceptedStartupRange
|
||||
bool AllowHaltDueToClock INIT(false); // pAllowHaltDueToClock
|
||||
|
||||
uint8_t AllowPassiveToActiveCyclePairs INIT(0);
|
||||
uint8_t AllowPassiveToActiveCyclePairs INIT(0); // pAllowPassiveToActive
|
||||
|
||||
uint8_t ClusterDriftDamping INIT(0);
|
||||
uint8_t ClusterDriftDamping INIT(0); // pClusterDriftDamping
|
||||
|
||||
bool ChannelA INIT(false);
|
||||
bool ChannelB INIT(false);
|
||||
bool ChannelA INIT(false); // pChannels
|
||||
bool ChannelB INIT(false); // pChannels
|
||||
|
||||
uint8_t DecodingCorrectionMicroticks INIT(0);
|
||||
uint8_t DelayCompensationAMicroticks INIT(0);
|
||||
uint8_t DelayCompensationBMicroticks INIT(0);
|
||||
uint8_t ExternOffsetCorrectionControl INIT(0);
|
||||
uint8_t ExternRateCorrectionControl INIT(0);
|
||||
uint8_t ExternOffsetCorrectionMicroticks INIT(0);
|
||||
uint8_t ExternRateCorrectionMicroticks INIT(0);
|
||||
|
||||
bool ExternalSync INIT(false);
|
||||
bool UseExternalSync INIT(false);
|
||||
|
||||
bool FallBackInternal INIT(false);
|
||||
bool UseFallBackInternal INIT(false);
|
||||
uint8_t DecodingCorrectionMicroticks INIT(0); // pDecodingCorrection
|
||||
uint8_t DelayCompensationAMicroticks INIT(0); // pDelayCompensation[A]
|
||||
uint8_t DelayCompensationBMicroticks INIT(0); // pDelayCompensation[B]
|
||||
uint8_t ExternOffsetCorrectionControl INIT(0); // pExternOffsetControl
|
||||
uint8_t ExternRateCorrectionControl INIT(0); // pExternRateControl
|
||||
uint8_t ExternOffsetCorrectionMicroticks INIT(0); // pExternOffsetCorrection
|
||||
uint8_t ExternRateCorrectionMicroticks INIT(0); // pExternRateCorrection
|
||||
|
||||
uint16_t KeySlotID INIT(0);
|
||||
|
||||
|
|
@ -154,39 +144,28 @@ public:
|
|||
bool KeySlotUsedForStartup INIT(false); // pKeySlotUsedForStartup (TXST)
|
||||
bool KeySlotUsedForSync INIT(false); // pKeySlotUsedForSync (TXSY)
|
||||
|
||||
uint16_t LatestTxMinislot INIT(0);
|
||||
uint32_t ListenTimeout INIT(0);
|
||||
uint16_t LatestTxMinislot INIT(0); // pLatestTx
|
||||
uint32_t ListenTimeout INIT(0); // pdListenTimeout
|
||||
|
||||
uint8_t MacroInitialOffsetA INIT(0); // Valid 2..72
|
||||
uint8_t MacroInitialOffsetB INIT(0); // Valid 2..72
|
||||
uint8_t MacroInitialOffsetA INIT(0); // pMacroInitialOffset[A], Valid 2..72
|
||||
uint8_t MacroInitialOffsetB INIT(0); // pMacroInitialOffset[B], Valid 2..72
|
||||
|
||||
uint32_t MaximumDynamicPayloadLengthWords INIT(0);
|
||||
uint8_t MicroInitialOffsetA INIT(0); // pMicroInitialOffset[A], Valid 0..240
|
||||
uint8_t MicroInitialOffsetB INIT(0); // pMicroInitialOffset[B], Valid 0..240
|
||||
|
||||
uint8_t MicroInitialOffsetA INIT(0); // Valid 0..240
|
||||
uint8_t MicroInitialOffsetB INIT(0); // Valid 0..240
|
||||
|
||||
uint32_t MicroPerCycle INIT(0);
|
||||
|
||||
double MicrotickDurationSec INIT(0);
|
||||
bool UseMicrotickDurationSec INIT(false);
|
||||
uint32_t MicroPerCycle INIT(0); // pMicroPerCycle
|
||||
|
||||
bool MTSOnA INIT(false);
|
||||
bool MTSOnB INIT(false);
|
||||
|
||||
bool NMVectorEarlyUpdate INIT(false);
|
||||
bool UseNMVectorEarlyUpdate INIT(false);
|
||||
|
||||
uint16_t OffsetCorrectionOutMicroticks INIT(0);
|
||||
uint16_t OffsetCorrectionOutMicroticks INIT(0); // pOffsetCorrectionOut
|
||||
uint16_t RateCorrectionOutMicroticks INIT(0); // pdMaxDrift and pRateCorrectionOut
|
||||
|
||||
uint32_t SamplesPerMicrotick INIT(0);
|
||||
bool UseSamplesPerMicrotick INIT(false);
|
||||
|
||||
uint16_t SecondKeySlotID INIT(0);
|
||||
bool TwoKeySlotMode INIT(false);
|
||||
|
||||
uint8_t WakeupPattern INIT(0);
|
||||
bool WakeupOnChannelB INIT(false);
|
||||
bool WakeupOnChannelB INIT(false); // pWakeupChannel
|
||||
|
||||
#ifndef __cplusplus
|
||||
} neoflexray_controller_config_t;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ public:
|
|||
void onGoOnline() override;
|
||||
void onGoOffline() override;
|
||||
|
||||
void handleMessage(const std::shared_ptr<Message>& message) override;
|
||||
bool transmitHook(const std::shared_ptr<Frame>& frame, bool& success) override;
|
||||
|
||||
std::shared_ptr<Controller> getController(uint8_t index) const {
|
||||
|
|
|
|||
|
|
@ -27,15 +27,15 @@ typedef struct {
|
|||
bool isDynamic INIT(false);
|
||||
bool isSync INIT(false); // Must be set if isStartup is set!
|
||||
bool isStartup INIT(false);
|
||||
bool isNMFrame INIT(false);
|
||||
bool isNetworkManagementFrame INIT(false);
|
||||
bool isTransmit INIT(false);
|
||||
uint16_t frameID INIT(0);
|
||||
uint16_t frameID INIT(0); // Frame/Slot ID
|
||||
bool channelA INIT(false);
|
||||
bool channelB INIT(false);
|
||||
uint8_t frameLengthBytes INIT(0);
|
||||
uint8_t baseCycle INIT(0);
|
||||
uint8_t cycleRepetition INIT(0);
|
||||
bool continuousMode INIT(false);
|
||||
bool continuousMode INIT(false); // If false, mode is continuous mode
|
||||
uint16_t _dataPointer INIT(0); // For internal use
|
||||
uint16_t _id INIT(0); // For internal use
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "icsneo/disk/extextractordiskreaddriver.h"
|
||||
#include "icsneo/disk/neomemorydiskdriver.h"
|
||||
#include "icsneo/device/tree/neovifire3flexray/neovifire3flexraysettings.h"
|
||||
#include "icsneo/device/extensions/flexray/extension.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
|
|
@ -90,6 +91,30 @@ protected:
|
|||
bool supportsEraseMemory() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void setupExtensions() override {
|
||||
std::vector<Network> flexRayControllers;
|
||||
flexRayControllers.push_back(Network::NetID::FLEXRAY_01);
|
||||
flexRayControllers.push_back(Network::NetID::FLEXRAY_01);
|
||||
addExtension(std::make_shared<FlexRay::Extension>(*this, flexRayControllers));
|
||||
|
||||
}
|
||||
|
||||
virtual std::vector<std::shared_ptr<FlexRay::Controller>> getFlexRayControllers() const override {
|
||||
auto extension = getExtension<FlexRay::Extension>();
|
||||
if(!extension)
|
||||
return Device::getFlexRayControllers();
|
||||
|
||||
std::vector<std::shared_ptr<FlexRay::Controller>> ret;
|
||||
|
||||
if(auto ctrl1 = extension->getController(0))
|
||||
ret.push_back(std::move(ctrl1));
|
||||
|
||||
if(auto ctrl2 = extension->getController(1))
|
||||
ret.push_back(std::move(ctrl2));
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue