From f53bc2e920112c8fd84f4d64f5b8c9f97a13f379 Mon Sep 17 00:00:00 2001 From: Max Brombach Date: Thu, 4 Sep 2025 14:27:32 +0000 Subject: [PATCH] Fix FlexRay extension bugs and implement FlexRay example --- bindings/python/CMakeLists.txt | 3 +- .../message/flexray/flexraymessage.cpp | 57 ----- bindings/python/icsneopy/device/device.cpp | 3 + .../device/extensions/deviceextension.cpp | 14 ++ bindings/python/icsneopy/flexray/flexray.cpp | 191 ++++++++++++++++ bindings/python/icsneopy/icsneocpp.cpp | 6 +- .../flexray/control/flexraycontrolmessage.cpp | 4 +- device/extensions/flexray/controller.cpp | 98 ++++----- device/extensions/flexray/extension.cpp | 20 -- examples/CMakeLists.txt | 5 + examples/cpp/flexray/CMakeLists.txt | 2 + examples/cpp/flexray/src/FlexRayExample.cpp | 204 ++++++++++++++++++ .../device/extensions/deviceextension.h | 2 - .../device/extensions/flexray/cluster.h | 65 +++--- .../device/extensions/flexray/controller.h | 65 ++---- .../device/extensions/flexray/extension.h | 1 - .../device/extensions/flexray/messagebuffer.h | 6 +- .../neovifire3flexray/neovifire3flexray.h | 25 +++ 18 files changed, 549 insertions(+), 222 deletions(-) delete mode 100644 bindings/python/icsneopy/communication/message/flexray/flexraymessage.cpp create mode 100644 bindings/python/icsneopy/device/extensions/deviceextension.cpp create mode 100644 bindings/python/icsneopy/flexray/flexray.cpp create mode 100644 examples/cpp/flexray/CMakeLists.txt create mode 100644 examples/cpp/flexray/src/FlexRayExample.cpp diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index 7e6935f..82b7a14 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -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 ) diff --git a/bindings/python/icsneopy/communication/message/flexray/flexraymessage.cpp b/bindings/python/icsneopy/communication/message/flexray/flexraymessage.cpp deleted file mode 100644 index 7a40795..0000000 --- a/bindings/python/icsneopy/communication/message/flexray/flexraymessage.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include - -#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_ flexray(m, "FlexRay"); - // enumerations - pybind11::enum_(flexray, "Symbol") - .value("None", FlexRayNamespace::Symbol::None) - .value("Unknown", FlexRayNamespace::Symbol::Unknown) - .value("Wakeup", FlexRayNamespace::Symbol::Wakeup) - .value("CAS", FlexRayNamespace::Symbol::CAS); - pybind11::enum_(flexray, "CRCStatus") - .value("OK", FlexRayNamespace::CRCStatus::OK) - .value("Error", FlexRayNamespace::CRCStatus::Error) - .value("NoCRC", FlexRayNamespace::CRCStatus::NoCRC); - pybind11::enum_(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_, 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 - diff --git a/bindings/python/icsneopy/device/device.cpp b/bindings/python/icsneopy/device/device.cpp index 97d58b5..ea2c1e4 100644 --- a/bindings/python/icsneopy/device/device.cpp +++ b/bindings/python/icsneopy/device/device.cpp @@ -4,6 +4,7 @@ #include #include "icsneo/device/device.h" +#include "icsneo/device/extensions/deviceextension.h" #include @@ -20,6 +21,8 @@ void init_device(pybind11::module_& m) { .def("enable_message_polling", &Device::enableMessagePolling, pybind11::arg("filter") = std::nullopt, pybind11::call_guard()) .def("get_current_message_count", &Device::getCurrentMessageCount) .def("get_digital_io", &Device::getDigitalIO, pybind11::arg("type"), pybind11::arg("number"), pybind11::call_guard()) + .def("get_extension", static_cast(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()) .def("get_messages", [](Device& device) { return device.getMessages(); }, pybind11::call_guard()) .def("get_polling_message_limit", &Device::getPollingMessageLimit) diff --git a/bindings/python/icsneopy/device/extensions/deviceextension.cpp b/bindings/python/icsneopy/device/extensions/deviceextension.cpp new file mode 100644 index 0000000..97c610a --- /dev/null +++ b/bindings/python/icsneopy/device/extensions/deviceextension.cpp @@ -0,0 +1,14 @@ +#include +#include +#include + +#include "icsneo/device/extensions/deviceextension.h" + +namespace icsneo { + +void init_deviceextension(pybind11::module_& m) { + pybind11::class_>(m, "DeviceExtension") + .def("get_name", &DeviceExtension::getName); +} + +} // namespace icsneo \ No newline at end of file diff --git a/bindings/python/icsneopy/flexray/flexray.cpp b/bindings/python/icsneopy/flexray/flexray.cpp new file mode 100644 index 0000000..53fe1d9 --- /dev/null +++ b/bindings/python/icsneopy/flexray/flexray.cpp @@ -0,0 +1,191 @@ +#include +#include +#include + +#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_& c) { + pybind11::class_>(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_>(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") + .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_ cluster(c, "Cluster"); + + pybind11::enum_(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") + .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") + .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_, 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_ flexray(m, "FlexRay"); + + pybind11::enum_(flexray, "Symbol") + .value("None", FlexRayNamespace::Symbol::None) + .value("Unknown", FlexRayNamespace::Symbol::Unknown) + .value("Wakeup", FlexRayNamespace::Symbol::Wakeup) + .value("CAS", FlexRayNamespace::Symbol::CAS); + pybind11::enum_(flexray, "CRCStatus") + .value("OK", FlexRayNamespace::CRCStatus::OK) + .value("Error", FlexRayNamespace::CRCStatus::Error) + .value("NoCRC", FlexRayNamespace::CRCStatus::NoCRC); + pybind11::enum_(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 + diff --git a/bindings/python/icsneopy/icsneocpp.cpp b/bindings/python/icsneopy/icsneocpp.cpp index d169444..3158f11 100644 --- a/bindings/python/icsneopy/icsneocpp.cpp +++ b/bindings/python/icsneopy/icsneocpp.cpp @@ -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); diff --git a/communication/message/flexray/control/flexraycontrolmessage.cpp b/communication/message/flexray/control/flexraycontrolmessage.cpp index 00e6ccd..2895dfd 100644 --- a/communication/message/flexray/control/flexraycontrolmessage.cpp +++ b/communication/message/flexray/control/flexraycontrolmessage.cpp @@ -7,9 +7,9 @@ using namespace icsneo; std::vector FlexRayControlMessage::BuildBaseControlArgs(uint8_t controller, FlexRay::Opcode op, const std::vector& args) { - std::vector ret(args.size() + 4); + std::vector ret; ret.push_back(controller); - const uint16_t size = uint16_t((std::min)(args.size() + 1, size_t(std::numeric_limits::max()))); // Add 1 for the opcode + const uint16_t size = static_cast(std::min(args.size() + 1, size_t(std::numeric_limits::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)); diff --git a/device/extensions/flexray/controller.cpp b/device/extensions/flexray/controller.cpp index da13f37..e5a4214 100644 --- a/device/extensions/flexray/controller.cpp +++ b/device/extensions/flexray/controller.cpp @@ -3,16 +3,6 @@ using namespace icsneo; -void FlexRay::Controller::_setStatus(std::shared_ptr msg) { - std::lock_guard lk(statusLock); - status = msg; -} - -std::shared_ptr FlexRay::Controller::getStatus() const { - std::lock_guard lk(statusLock); - return status; -} - std::pair 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> staticTx; @@ -210,7 +201,7 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) { second->isStartup = controllerConfig.KeySlotUsedForStartup; second->isSync = controllerConfig.KeySlotUsedForSync; second->isTransmit = true; - second->channelB =true; + second->channelB = true; second->frameID = controllerConfig.SecondKeySlotID; second->frameLengthBytes = clusterConfig.PayloadLengthOfStaticSlotInWords * 2; second->baseCycle = 0; @@ -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(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(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 FlexRay::Controller::readRegister(ERAYRegister reg, std::chrono::milliseconds timeout) const { - static const std::shared_ptr filter = std::make_shared(icsneo::Network::NetID::FlexRayControl); + static const std::shared_ptr filter = std::make_shared(); + filter->includeInternalInAny = true; if(timeout.count() <= 20) return {false, 0}; // Out of time! diff --git a/device/extensions/flexray/extension.cpp b/device/extensions/flexray/extension.cpp index 96e7d8d..a3f49e4 100644 --- a/device/extensions/flexray/extension.cpp +++ b/device/extensions/flexray/extension.cpp @@ -25,26 +25,6 @@ void FlexRay::Extension::onGoOffline() { controller->halt(); } -void FlexRay::Extension::handleMessage(const std::shared_ptr& message) { - switch(message->type) { - case Message::Type::FlexRayControl: { - auto msg = std::dynamic_pointer_cast(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, bool& success) { if(!frame || frame->network.getType() != Network::Type::FlexRay) return true; // Don't hook non-FlexRay messages diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 2899acb..3aac1db 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -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() diff --git a/examples/cpp/flexray/CMakeLists.txt b/examples/cpp/flexray/CMakeLists.txt new file mode 100644 index 0000000..27205eb --- /dev/null +++ b/examples/cpp/flexray/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(libicsneocpp-flexray-example src/FlexRayExample.cpp) +target_link_libraries(libicsneocpp-flexray-example icsneocpp) \ No newline at end of file diff --git a/examples/cpp/flexray/src/FlexRayExample.cpp b/examples/cpp/flexray/src/FlexRayExample.cpp new file mode 100644 index 0000000..6a2c8a8 --- /dev/null +++ b/examples/cpp/flexray/src/FlexRayExample.cpp @@ -0,0 +1,204 @@ +#include +#include + +#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 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> makeDummyFlexRayMessages(size_t msgCount, size_t msgLen) { + std::vector> messages; + messages.reserve(msgCount); + std::random_device rd; + std::mt19937 engine(rd()); + std::uniform_int_distribution dist(0, 255); + for (size_t i = 0; i < msgCount; i++) { + auto msg = std::make_shared(); + 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(dist(engine))); + } + msg->slotid = (i % 2 == 0) ? SlotOne : SlotTwo; + messages.push_back(msg); + } + return messages; +} + +int main() { + auto devices = icsneo::FindAllDevices(); + std::shared_ptr 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> messages; + size_t currentMessage = 0; + auto filter = std::make_shared(icsneo::Network::NetID::FLEXRAY_01); + auto rxCallback = [&messages, ¤tMessage](std::shared_ptr message) -> void { + std::unique_lock lk(msgRcvdMutex); + auto frmsg = std::static_pointer_cast(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(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; +} \ No newline at end of file diff --git a/include/icsneo/device/extensions/deviceextension.h b/include/icsneo/device/extensions/deviceextension.h index 59dfe3e..244273a 100644 --- a/include/icsneo/device/extensions/deviceextension.h +++ b/include/icsneo/device/extensions/deviceextension.h @@ -10,8 +10,6 @@ namespace icsneo { -class Device; - class DeviceExtension { public: DeviceExtension(Device& device) : device(device) {} diff --git a/include/icsneo/device/extensions/flexray/cluster.h b/include/icsneo/device/extensions/flexray/cluster.h index 5b20d7d..2289623 100644 --- a/include/icsneo/device/extensions/flexray/cluster.h +++ b/include/icsneo/device/extensions/flexray/cluster.h @@ -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 }; diff --git a/include/icsneo/device/extensions/flexray/controller.h b/include/icsneo/device/extensions/flexray/controller.h index 43e6216..aa75e1e 100644 --- a/include/icsneo/device/extensions/flexray/controller.h +++ b/include/icsneo/device/extensions/flexray/controller.h @@ -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 msg); // Begin Public Interface - std::shared_ptr 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 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; diff --git a/include/icsneo/device/extensions/flexray/extension.h b/include/icsneo/device/extensions/flexray/extension.h index 0d70268..aeebefe 100644 --- a/include/icsneo/device/extensions/flexray/extension.h +++ b/include/icsneo/device/extensions/flexray/extension.h @@ -24,7 +24,6 @@ public: void onGoOnline() override; void onGoOffline() override; - void handleMessage(const std::shared_ptr& message) override; bool transmitHook(const std::shared_ptr& frame, bool& success) override; std::shared_ptr getController(uint8_t index) const { diff --git a/include/icsneo/device/extensions/flexray/messagebuffer.h b/include/icsneo/device/extensions/flexray/messagebuffer.h index d8d29c4..8fac695 100644 --- a/include/icsneo/device/extensions/flexray/messagebuffer.h +++ b/include/icsneo/device/extensions/flexray/messagebuffer.h @@ -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 diff --git a/include/icsneo/device/tree/neovifire3flexray/neovifire3flexray.h b/include/icsneo/device/tree/neovifire3flexray/neovifire3flexray.h index 05edc31..73c3a0a 100644 --- a/include/icsneo/device/tree/neovifire3flexray/neovifire3flexray.h +++ b/include/icsneo/device/tree/neovifire3flexray/neovifire3flexray.h @@ -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 flexRayControllers; + flexRayControllers.push_back(Network::NetID::FLEXRAY_01); + flexRayControllers.push_back(Network::NetID::FLEXRAY_01); + addExtension(std::make_shared(*this, flexRayControllers)); + + } + + virtual std::vector> getFlexRayControllers() const override { + auto extension = getExtension(); + if(!extension) + return Device::getFlexRayControllers(); + + std::vector> 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; + } }; }