Fix FlexRay extension bugs and implement FlexRay example

pull/76/merge
Max Brombach 2025-09-04 14:27:32 +00:00
parent a9e1f24f67
commit f53bc2e920
18 changed files with 549 additions and 222 deletions

View File

@ -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
)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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));

View File

@ -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!

View File

@ -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

View File

@ -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()

View File

@ -0,0 +1,2 @@
add_executable(libicsneocpp-flexray-example src/FlexRayExample.cpp)
target_link_libraries(libicsneocpp-flexray-example icsneocpp)

View File

@ -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, &currentMessage](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;
}

View File

@ -10,8 +10,6 @@
namespace icsneo {
class Device;
class DeviceExtension {
public:
DeviceExtension(Device& device) : device(device) {}

View File

@ -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
};

View File

@ -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;

View File

@ -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 {

View File

@ -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

View File

@ -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;
}
};
}