Device: FlexRay: Add additional configuration options for Controller and Cluster

master
Thomas Stoddard 2026-01-30 18:06:39 +00:00 committed by Kyle Schwarz
parent 5f16adc103
commit 6a32823a0f
6 changed files with 821 additions and 1 deletions

View File

@ -64,6 +64,7 @@ void init_extension(pybind11::classh<FlexRayNamespace>& c) {
.def_readwrite("accept_startup_range_microticks", &Controller::Configuration::AcceptStartupRangeMicroticks) .def_readwrite("accept_startup_range_microticks", &Controller::Configuration::AcceptStartupRangeMicroticks)
.def_readwrite("allow_passive_to_active_cycle_pairs", &Controller::Configuration::AllowPassiveToActiveCyclePairs) .def_readwrite("allow_passive_to_active_cycle_pairs", &Controller::Configuration::AllowPassiveToActiveCyclePairs)
.def_readwrite("cluster_drift_damping", &Controller::Configuration::ClusterDriftDamping) .def_readwrite("cluster_drift_damping", &Controller::Configuration::ClusterDriftDamping)
.def_readwrite("allow_halt_due_to_clock", &Controller::Configuration::AllowHaltDueToClock)
.def_readwrite("channel_a", &Controller::Configuration::ChannelA) .def_readwrite("channel_a", &Controller::Configuration::ChannelA)
.def_readwrite("channel_b", &Controller::Configuration::ChannelB) .def_readwrite("channel_b", &Controller::Configuration::ChannelB)
.def_readwrite("decoding_correction_microticks", &Controller::Configuration::DecodingCorrectionMicroticks) .def_readwrite("decoding_correction_microticks", &Controller::Configuration::DecodingCorrectionMicroticks)
@ -74,6 +75,7 @@ void init_extension(pybind11::classh<FlexRayNamespace>& c) {
.def_readwrite("extern_offset_correction_microticks", &Controller::Configuration::ExternOffsetCorrectionMicroticks) .def_readwrite("extern_offset_correction_microticks", &Controller::Configuration::ExternOffsetCorrectionMicroticks)
.def_readwrite("extern_rate_correction_microticks", &Controller::Configuration::ExternRateCorrectionMicroticks) .def_readwrite("extern_rate_correction_microticks", &Controller::Configuration::ExternRateCorrectionMicroticks)
.def_readwrite("key_slot_id", &Controller::Configuration::KeySlotID) .def_readwrite("key_slot_id", &Controller::Configuration::KeySlotID)
.def_readwrite("key_slot_only_enabled", &Controller::Configuration::KeySlotOnlyEnabled)
.def_readwrite("key_slot_used_for_startup", &Controller::Configuration::KeySlotUsedForStartup) .def_readwrite("key_slot_used_for_startup", &Controller::Configuration::KeySlotUsedForStartup)
.def_readwrite("key_slot_used_for_sync", &Controller::Configuration::KeySlotUsedForSync) .def_readwrite("key_slot_used_for_sync", &Controller::Configuration::KeySlotUsedForSync)
.def_readwrite("latest_tx_minislot", &Controller::Configuration::LatestTxMinislot) .def_readwrite("latest_tx_minislot", &Controller::Configuration::LatestTxMinislot)
@ -114,6 +116,7 @@ void init_extension(pybind11::classh<FlexRayNamespace>& c) {
.def_readwrite("action_point_offset", &Cluster::Configuration::ActionPointOffset) .def_readwrite("action_point_offset", &Cluster::Configuration::ActionPointOffset)
.def_readwrite("casr_x_low_max", &Cluster::Configuration::CASRxLowMax) .def_readwrite("casr_x_low_max", &Cluster::Configuration::CASRxLowMax)
.def_readwrite("cold_start_attempts", &Cluster::Configuration::ColdStartAttempts) .def_readwrite("cold_start_attempts", &Cluster::Configuration::ColdStartAttempts)
.def_readwrite("cycle_duration_micro_sec", &Cluster::Configuration::CycleDurationMicroSec)
.def_readwrite("dynamic_slot_idle_phase_minislots", &Cluster::Configuration::DynamicSlotIdlePhaseMinislots) .def_readwrite("dynamic_slot_idle_phase_minislots", &Cluster::Configuration::DynamicSlotIdlePhaseMinislots)
.def_readwrite("listen_noise_macroticks", &Cluster::Configuration::ListenNoiseMacroticks) .def_readwrite("listen_noise_macroticks", &Cluster::Configuration::ListenNoiseMacroticks)
.def_readwrite("macroticks_per_cycle", &Cluster::Configuration::MacroticksPerCycle) .def_readwrite("macroticks_per_cycle", &Cluster::Configuration::MacroticksPerCycle)
@ -159,7 +162,8 @@ void init_flexraymessage(pybind11::module_& m) {
.def_readwrite("sync_frame", &FlexRayMessage::sync) .def_readwrite("sync_frame", &FlexRayMessage::sync)
.def_readwrite("startup_frame", &FlexRayMessage::startup) .def_readwrite("startup_frame", &FlexRayMessage::startup)
.def_readwrite("dynamic_frame", &FlexRayMessage::dynamic) .def_readwrite("dynamic_frame", &FlexRayMessage::dynamic)
.def_readwrite("cycle", &FlexRayMessage::cycle); .def_readwrite("cycle", &FlexRayMessage::cycle)
.def_readwrite("cycle_repetition", &FlexRayMessage::cycleRepetition);
//// TODO: Eliminate FlexRayControlMessage class references in controller class and eliminate getStatus function in bindings //// TODO: Eliminate FlexRayControlMessage class references in controller class and eliminate getStatus function in bindings
} }

View File

@ -0,0 +1,191 @@
=======================
FlexRay Getting Started
=======================
Prerequisites
=============
- icsneopy library installed
- FlexRay hardware device connected (e.g., Fire3 Flexray)
- Proper FlexRay bus termination (100Ω on each channel end)
Physical Hardware Setup for Two-Node Testing
---------------------------------------------
For testing the basic transmit and receive examples with a single device:
- Hardware: Device with dual FlexRay controllers (e.g., neoVI FIRE 3 Flexray)
- Connection: FLEXRAY_01 Channel A looped to FLEXRAY_02 Channel A
- Termination: 100Ω termination resistors on both ends of the loopback
- Cable: Use proper FlexRay twisted pair cable (impedance matched)
.. note::
The basic transmit/receive examples are configured for this loopback setup
where both controllers act as coldstart nodes. For use on an existing
FlexRay network, see the passive monitoring configuration notes in the
receive example.
FlexRay Coldstart
-----------------
FlexRay networks require at least one "coldstart node" to initialize the network timing.
The coldstart node is responsible for starting the FlexRay communication cycle.
For a complete standalone coldstart example, see the Additional Examples section below.
Basic Setup
===========
1. Import the library and find FlexRay device:
.. code-block:: python
import icsneopy
devices = icsneopy.find_all_devices()
# Find a device with FlexRay support
device = None
for dev in devices:
if dev.get_extension("FlexRay"):
device = dev
break
if not device:
raise RuntimeError("No FlexRay-capable device found")
2. Configure FlexRay controller:
.. literalinclude:: ../../examples/python/flexray/flexray_transmit_basic.py
:language: python
:lines: 12-111
3. Open device and go online:
.. code-block:: python
if not device.open():
raise RuntimeError("Failed to open device")
if not device.go_online():
raise RuntimeError("Failed to go online")
Transmitting FlexRay Frames
============================
This example demonstrates a coldstart node that initiates a FlexRay network
and transmits simulated sensor data continuously in slot 1.
**Hardware Setup**: FLEXRAY_01 looped to FLEXRAY_02
**Usage**:
1. Start the receive example first
2. Start this transmit example second
3. Network will initialize and frames will be transmitted
.. literalinclude:: ../../examples/python/flexray/flexray_transmit_basic.py
:language: python
:lines: 113-170
Key Configuration Parameters:
- **slotid**: The FlexRay slot ID for transmission (1-2047 for static segment)
- **cycle**: The FlexRay cycle number (0-63)
- **cycle_repetition**: How often the frame repeats (1 = every cycle, 2 = every other cycle)
- **channel**: Transmission channel (A, B, or AB for both)
- **key_slot_id**: Must be unique per node on the network
- **key_slot_used_for_startup**: True for coldstart nodes
- **key_slot_used_for_sync**: True to provide synchronization frames
Receiving FlexRay Frames
=========================
This example demonstrates receiving FlexRay frames on FLEXRAY_02 Channel A.
**Hardware Setup**: FLEXRAY_01 looped to FLEXRAY_02
**Configuration Note**: This example is configured with coldstart capability
for two-node loopback testing. For passive monitoring on an existing FlexRay
network:
1. Set ``key_slot_used_for_startup = False`` in the controller configuration
2. Remove the ``controller.set_allow_coldstart(True)`` call
3. Ensure all cluster parameters match the existing network
4. The node will sync and receive without transmitting
**Usage**:
1. Start this receive example first
2. Start the transmit example second
3. Frames from slot 1 will be displayed with hex and decimal payload views
.. literalinclude:: ../../examples/python/flexray/flexray_receive_basic.py
:language: python
:lines: 103-170
FlexRay Coldstart Configuration
================================
To use the Coldstart example, ensure the following:
Set the Flexray network in neoVI Explorer to Coldstart.
No other nodes should be present on the network during testing.
Nothing connected to Fire3 FlexRay bus.
Critical Coldstart Settings
----------------------------
.. literalinclude:: ../../examples/python/flexray/flexray_coldstart.py
:language: python
:lines: 40-48
Configuration Example:
.. literalinclude:: ../../examples/python/flexray/flexray_coldstart.py
:language: python
:lines: 20-64
Setting Coldstart on Controller:
.. code-block:: python
controller.set_allow_coldstart(True)
controller.set_start_when_going_online(True)
Cleanup and Resource Management
================================
Always close the device when finished:
.. code-block:: python
try:
# Your FlexRay operations here
pass
finally:
device.close()
See the basic transmit and receive examples for complete implementations.
Additional Examples
===================
Transmit Basic
--------------
Complete working example with coldstart node transmitting simulated sensor data.
All example files are available for download:
**Transmit Basic** - Coldstart node transmitting simulated sensor data
:download:`flexray_transmit_basic.py <../../examples/python/flexray/flexray_transmit_basic.py>`
**Receive Basic** - Receiving and displaying FlexRay frames with formatted output
:download:`flexray_receive_basic.py <../../examples/python/flexray/flexray_receive_basic.py>`
**Coldstart** - Standalone coldstart example demonstrating network initialization
:download:`flexray_coldstart.py <../../examples/python/flexray/flexray_coldstart.py>`

View File

@ -7,6 +7,7 @@ icsneopy
can_getting_started can_getting_started
ethernet_getting_started ethernet_getting_started
flexray_getting_started
examples examples
api api
radepsilon radepsilon

View File

@ -0,0 +1,218 @@
"""
FlexRay coldstart example using icsneopy library.
Demonstrates coldstart capability where one FlexRay device can start
the network without needing other devices connected.
CRITICAL COLDSTART REQUIREMENTS:
1. key_slot_used_for_startup = True
2. key_slot_used_for_sync = True
3. set_allow_coldstart(True)
4. Each controller needs a unique key_slot_id
5. Proper bus termination (required for FlexRay)
"""
import icsneopy
import time
def get_coldstart_controller_config(slot_id):
"""
Create FlexRay controller configuration for COLDSTART.
The three critical settings for coldstart are marked below.
"""
config = icsneopy.FlexRay.Controller.Configuration()
config.accept_startup_range_microticks = 160
config.allow_halt_due_to_clock = True
config.allow_passive_to_active_cycle_pairs = 15
config.cluster_drift_damping = 2
config.channel_a = True
config.channel_b = True
config.decoding_correction_microticks = 56
config.delay_compensation_a_microticks = 28
config.delay_compensation_b_microticks = 28
config.extern_offset_correction_control = 0
config.extern_rate_correction_control = 0
config.extern_offset_correction_microticks = 0
config.extern_rate_correction_microticks = 0
# CRITICAL FOR COLDSTART: Set the key slot ID
config.key_slot_id = slot_id
config.key_slot_only_enabled = False
# CRITICAL FOR COLDSTART: Enable startup and sync on key slot
config.key_slot_used_for_startup = True # Required for coldstart
config.key_slot_used_for_sync = True # Required for coldstart
config.latest_tx_minislot = 226
config.listen_timeout = 401202
config.macro_initial_offset_a = 7
config.macro_initial_offset_b = 7
config.micro_initial_offset_a = 36
config.micro_initial_offset_b = 36
config.micro_per_cycle = 200000
config.mts_on_a = False
config.mts_on_b = False
config.offset_correction_out_microticks = 189
config.rate_correction_out_microticks = 601
config.second_key_slot_id = 0
config.two_key_slot_mode = False
config.wakeup_pattern = 55
config.wakeup_on_channel_b = False
return config
def get_cluster_config():
"""Create FlexRay cluster configuration."""
config = icsneopy.FlexRay.Cluster.Configuration()
config.speed = icsneopy.FlexRay.Cluster.SpeedType.FLEXRAY_BAUDRATE_10M
config.strobe_point_position = icsneopy.FlexRay.Cluster.SPPType.FLEXRAY_SPP_5
config.action_point_offset = 4
config.casr_x_low_max = 64
config.cold_start_attempts = 8
config.cycle_duration_micro_sec = 5000
config.dynamic_slot_idle_phase_minislots = 1
config.listen_noise_macroticks = 4
config.macroticks_per_cycle = 5000
config.macrotick_duration_micro_sec = 1
config.max_without_clock_correction_fatal = 2
config.max_without_clock_correction_passive = 2
config.minislot_action_point_offset_macroticks = 4
config.minislot_duration_macroticks = 10
config.network_idle_time_macroticks = 40
config.network_management_vector_length_bytes = 1
config.number_of_minislots = 0
config.number_of_static_slots = 32
config.offset_correction_start_macroticks = 4991
config.payload_length_of_static_slot_in_words = 67
config.static_slot_macroticks = 155
config.symbol_window_macroticks = 0
config.symbol_window_action_point_offset_macroticks = 0
config.sync_frame_id_count_max = 15
config.transmission_start_sequence_duration_bits = 11
config.wakeup_rx_idle_bits = 40
config.wakeup_rx_low_bits = 40
config.wakeup_rx_window_bits = 301
config.wakeup_tx_active_bits = 60
config.wakeup_tx_idle_bits = 180
return config
def flexray_coldstart():
"""Perform FlexRay coldstart operation."""
devices = icsneopy.find_all_devices()
if not devices:
raise RuntimeError("No devices found")
# Find a device with FlexRay support
device = None
for dev in devices:
if dev.get_extension("FlexRay"):
device = dev
break
if not device:
raise RuntimeError("No FlexRay-capable device found")
print(f"Using device: {device.get_product_name()} {device.get_serial()}")
try:
# Get FlexRay controllers
controllers = device.get_flexray_controllers()
if not controllers:
raise RuntimeError("Device has no FlexRay controllers")
print(f"Device has {len(controllers)} FlexRay controller(s)")
# Configure controllers for coldstart
cluster_config = get_cluster_config()
base_slot_id = 1
for i, controller in enumerate(controllers):
slot_id = base_slot_id + i
controller_config = get_coldstart_controller_config(slot_id)
print(f"\nConfiguring controller {i} for COLDSTART:")
print(f" Key Slot ID: {slot_id}")
print(f" Key Slot Used for Startup: {controller_config.key_slot_used_for_startup}")
print(f" Key Slot Used for Sync: {controller_config.key_slot_used_for_sync}")
# CRITICAL FOR COLDSTART: Enable coldstart capability
controller.set_allow_coldstart(True)
print(f" Allow Coldstart: True")
# Configure to start when going online
controller.set_start_when_going_online(True)
# Set the configuration
controller.set_configuration(cluster_config, controller_config)
# Open device
print("\nOpening device...")
if not device.open():
raise RuntimeError("Failed to open device")
print("Device opened successfully")
# Go online - this triggers coldstart
print("\nGoing online (coldstart will initiate)...")
if not device.go_online():
raise RuntimeError("Failed to go online - check bus termination and configuration")
print("Device online successfully!")
print("\n" + "=" * 60)
print("✓ FlexRay network started via COLDSTART")
print("=" * 60)
# Transmit test messages on the coldstart key slot
print("\nTransmitting initial test messages...")
for i in range(5):
frame = icsneopy.FlexRayMessage()
frame.network = icsneopy.Network(icsneopy.Network.NetID.FLEXRAY_01)
frame.slotid = base_slot_id # Use the first key slot
frame.cycle = 0
frame.cycle_repetition = 1
frame.channel = icsneopy.FlexRay.Channel.AB
frame.data = (0xAA, 0xBB, 0xCC, 0xDD, i, i+1, i+2, i+3)
if device.transmit(frame):
print(f" ✓ Transmitted message {i+1}")
else:
print(f" ✗ Failed to transmit message {i+1}")
time.sleep(0.1)
print("\n" + "=" * 60)
print("Network is now active and will stay alive.")
print("You can now run transmit/receive examples in another terminal.")
print("Press Ctrl+C to stop and shut down the network.")
print("=" * 60)
# Keep transmitting periodically to maintain network presence
counter = 0
try:
while True:
frame = icsneopy.FlexRayMessage()
frame.network = icsneopy.Network(icsneopy.Network.NetID.FLEXRAY_01)
frame.slotid = base_slot_id
frame.cycle = 0
frame.cycle_repetition = 1
frame.channel = icsneopy.FlexRay.Channel.AB
frame.data = (0xCA, 0xFE, 0xBA, 0xBE, counter & 0xFF,
(counter >> 8) & 0xFF, (counter >> 16) & 0xFF, (counter >> 24) & 0xFF)
device.transmit(frame)
counter += 1
time.sleep(1) # Transmit every second
except KeyboardInterrupt:
print("\n\nStopping coldstart node...")
print("\n✓ Coldstart example completed successfully!")
finally:
device.close()
if __name__ == "__main__":
flexray_coldstart()

View File

@ -0,0 +1,188 @@
# Basic FlexRay frame reception example using icsneopy library.
import icsneopy
import time
import signal
import sys
def get_controller_config(slot_id):
"""Create a FlexRay controller configuration matching the network.
Args:
slot_id: The key slot ID for this node (must be unique per node)
Returns:
FlexRay.Controller.Configuration with all parameters set
Note:
For passive listening on an existing network, set:
- key_slot_used_for_startup = False
- Remove set_allow_coldstart(True) call below
"""
config = icsneopy.FlexRay.Controller.Configuration()
config.accept_startup_range_microticks = 160
config.allow_halt_due_to_clock = True
config.allow_passive_to_active_cycle_pairs = 15
config.cluster_drift_damping = 2
# Physical channel configuration (Channel A only for this example)
config.channel_a = True
config.channel_b = False # Single channel A only
config.decoding_correction_microticks = 56
config.delay_compensation_a_microticks = 28
config.delay_compensation_b_microticks = 28
config.extern_offset_correction_control = 0
config.extern_rate_correction_control = 0
config.extern_offset_correction_microticks = 0
config.extern_rate_correction_microticks = 0
# KEY SLOT CONFIGURATION - Critical for FlexRay operation
config.key_slot_id = slot_id # Must be unique per node
config.key_slot_only_enabled = False
config.key_slot_used_for_startup = True # True = participate in coldstart
config.key_slot_used_for_sync = True # True = synchronize with network
config.latest_tx_minislot = 226
config.listen_timeout = 401202
config.macro_initial_offset_a = 7
config.macro_initial_offset_b = 7
config.micro_initial_offset_a = 36
config.micro_initial_offset_b = 36
config.micro_per_cycle = 200000
config.mts_on_a = False
config.mts_on_b = False
config.offset_correction_out_microticks = 189
config.rate_correction_out_microticks = 601
config.second_key_slot_id = 0
config.two_key_slot_mode = False
config.wakeup_pattern = 55
config.wakeup_on_channel_b = False
return config
def get_cluster_config():
"""Create a FlexRay cluster configuration matching the network."""
config = icsneopy.FlexRay.Cluster.Configuration()
config.speed = icsneopy.FlexRay.Cluster.SpeedType.FLEXRAY_BAUDRATE_10M
config.strobe_point_position = icsneopy.FlexRay.Cluster.SPPType.FLEXRAY_SPP_5
config.action_point_offset = 4
config.casr_x_low_max = 64
config.cold_start_attempts = 8
config.cycle_duration_micro_sec = 5000
config.dynamic_slot_idle_phase_minislots = 1
config.listen_noise_macroticks = 4
config.macroticks_per_cycle = 5000
config.macrotick_duration_micro_sec = 1
config.max_without_clock_correction_fatal = 2
config.max_without_clock_correction_passive = 2
config.minislot_action_point_offset_macroticks = 4
config.minislot_duration_macroticks = 10
config.network_idle_time_macroticks = 40
config.network_management_vector_length_bytes = 1
config.number_of_minislots = 0
config.number_of_static_slots = 32
config.offset_correction_start_macroticks = 4991
config.payload_length_of_static_slot_in_words = 67
config.static_slot_macroticks = 155
config.symbol_window_macroticks = 0
config.symbol_window_action_point_offset_macroticks = 0
config.sync_frame_id_count_max = 15
config.transmission_start_sequence_duration_bits = 11
config.wakeup_rx_idle_bits = 40
config.wakeup_rx_low_bits = 40
config.wakeup_rx_window_bits = 301
config.wakeup_tx_active_bits = 60
config.wakeup_tx_idle_bits = 180
return config
def receive_flexray_frames():
"""Receive FlexRay frames as passive node with callback handling."""
devices = icsneopy.find_all_devices()
if not devices:
raise RuntimeError("No devices found")
# Find a device with FlexRay support
device = None
for dev in devices:
if dev.get_extension("FlexRay"):
device = dev
break
if not device:
raise RuntimeError("No FlexRay-capable device found")
frame_count = 0
running = True
def on_frame(frame):
nonlocal frame_count
if isinstance(frame, icsneopy.FlexRayMessage):
# Only show frames from slot 1 (filter out null frames)
if frame.slotid == 1:
frame_count += 1
# Nice formatted view of the frame
payload_hex = ' '.join([f'{b:02X}' for b in frame.data[:8]])
payload_dec = ' '.join([f'{b:3d}' for b in frame.data[:8]])
print(f"[Frame {frame_count:4d}] Slot: {frame.slotid:2d} | Cycle: {frame.cycle:2d} | "
f"Channel: {str(frame.channel):10s}")
print(f" Hex: [{payload_hex}]")
print(f" Dec: [{payload_dec}]\n")
def signal_handler(sig, frame):
nonlocal running
print("\nShutting down...")
running = False
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
frame_filter = icsneopy.MessageFilter(icsneopy.Network.NetID.FLEXRAY_02)
callback = icsneopy.MessageCallback(on_frame, frame_filter)
try:
# Configure FlexRay controller 1 (FLEXRAY_02) as passive node
controllers = device.get_flexray_controllers()
if len(controllers) < 2:
raise RuntimeError("Device needs at least 2 FlexRay controllers")
controller = controllers[1] # Use controller 1
cluster_config = get_cluster_config()
controller_config = get_controller_config(slot_id=2)
# Enable coldstart so this node transmits and coldstart node sees activity
controller.set_allow_coldstart(True)
controller.set_configuration(cluster_config, controller_config)
controller.set_start_when_going_online(True)
if not device.open():
raise RuntimeError("Failed to open device")
if not device.go_online():
raise RuntimeError("Failed to go online")
device.add_message_callback(callback)
print("="*60)
print("FlexRay Receive Node - Coldstart Config Loaded")
print("="*60)
print(f"Controller: FLEXRAY_02 | Slot ID: 2 | Channel: A")
print(f"Listening for frames...")
print(f"Start the transmit script now to begin communication")
print("="*60)
print("Press Ctrl+C to stop\n")
while running:
time.sleep(0.1)
print(f"\nTotal frames received: {frame_count}")
finally:
device.close()
if __name__ == "__main__":
receive_flexray_frames()

View File

@ -0,0 +1,218 @@
# Basic FlexRay frame transmission example using icsneopy library.
import icsneopy
import time
import signal
import sys
import random
def get_controller_config(slot_id, is_coldstart=False):
"""Create a FlexRay controller configuration matching the network.
Args:
slot_id: The key slot ID for this node (must be unique per node)
is_coldstart: True if this node participates in coldstart
Returns:
FlexRay.Controller.Configuration with all parameters set
"""
config = icsneopy.FlexRay.Controller.Configuration()
config.accept_startup_range_microticks = 160
config.allow_halt_due_to_clock = True
config.allow_passive_to_active_cycle_pairs = 15
config.cluster_drift_damping = 2
# Physical channel configuration (Channel A only for this example)
config.channel_a = True
config.channel_b = False # Single channel A only
config.decoding_correction_microticks = 56
config.delay_compensation_a_microticks = 28
config.delay_compensation_b_microticks = 28
config.extern_offset_correction_control = 0
config.extern_rate_correction_control = 0
config.extern_offset_correction_microticks = 0
config.extern_rate_correction_microticks = 0
# KEY SLOT CONFIGURATION - Critical for FlexRay operation
config.key_slot_id = slot_id # Must be unique per node
config.key_slot_only_enabled = False
config.key_slot_used_for_startup = is_coldstart # True = coldstart node
config.key_slot_used_for_sync = is_coldstart # True = provides sync
config.latest_tx_minislot = 226
config.listen_timeout = 401202
config.macro_initial_offset_a = 7
config.macro_initial_offset_b = 7
config.micro_initial_offset_a = 36
config.micro_initial_offset_b = 36
config.micro_per_cycle = 200000
config.mts_on_a = False
config.mts_on_b = False
config.offset_correction_out_microticks = 189
config.rate_correction_out_microticks = 601
config.second_key_slot_id = 0
config.two_key_slot_mode = False
config.wakeup_pattern = 55
config.wakeup_on_channel_b = False
return config
def get_cluster_config():
"""Create a FlexRay cluster configuration matching the network.
All nodes on the FlexRay network must have identical cluster parameters.
These define the timing and structure of the FlexRay communication cycle.
Key parameters:
- cycle_duration_micro_sec: 5000 = 5ms cycle time
- macroticks_per_cycle: 5000 macroticks per cycle
- number_of_static_slots: 32 static slots for guaranteed transmission
- payload_length_of_static_slot_in_words: 67 words = 134 bytes max payload
Returns:
FlexRay.Cluster.Configuration with all timing parameters set
"""
config = icsneopy.FlexRay.Cluster.Configuration()
config.speed = icsneopy.FlexRay.Cluster.SpeedType.FLEXRAY_BAUDRATE_10M
config.strobe_point_position = icsneopy.FlexRay.Cluster.SPPType.FLEXRAY_SPP_5
config.action_point_offset = 4
config.casr_x_low_max = 64
config.cold_start_attempts = 8
config.cycle_duration_micro_sec = 5000
config.dynamic_slot_idle_phase_minislots = 1
config.listen_noise_macroticks = 4
config.macroticks_per_cycle = 5000
config.macrotick_duration_micro_sec = 1
config.max_without_clock_correction_fatal = 2
config.max_without_clock_correction_passive = 2
config.minislot_action_point_offset_macroticks = 4
config.minislot_duration_macroticks = 10
config.network_idle_time_macroticks = 40
config.network_management_vector_length_bytes = 1
config.number_of_minislots = 0
config.number_of_static_slots = 32
config.offset_correction_start_macroticks = 4991
config.payload_length_of_static_slot_in_words = 67
config.static_slot_macroticks = 155
config.symbol_window_macroticks = 0
config.symbol_window_action_point_offset_macroticks = 0
config.sync_frame_id_count_max = 15
config.transmission_start_sequence_duration_bits = 11
config.wakeup_rx_idle_bits = 40
config.wakeup_rx_low_bits = 40
config.wakeup_rx_window_bits = 301
config.wakeup_tx_active_bits = 60
config.wakeup_tx_idle_bits = 180
return config
def transmit_flexray_frame():
"""Transmit FlexRay frames as coldstart node."""
devices = icsneopy.find_all_devices()
if not devices:
raise RuntimeError("No devices found")
# Find a device with FlexRay support
device = None
for dev in devices:
if dev.get_extension("FlexRay"):
device = dev
break
if not device:
raise RuntimeError("No FlexRay-capable device found")
running = True
def signal_handler(sig, frame):
nonlocal running
print("\nShutting down...")
running = False
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
try:
# Configure FlexRay controller 0 (FLEXRAY_01) as coldstart node
controllers = device.get_flexray_controllers()
if not controllers:
raise RuntimeError("Device has no FlexRay controllers")
controller = controllers[0] # Use controller 0
cluster_config = get_cluster_config()
controller_config = get_controller_config(slot_id=1, is_coldstart=True)
# Enable coldstart capability
controller.set_allow_coldstart(True)
controller.set_configuration(cluster_config, controller_config)
controller.set_start_when_going_online(True)
if not device.open():
raise RuntimeError("Failed to open device")
if not device.go_online():
raise RuntimeError("Failed to go online")
print("="*60)
print("FlexRay Transmit Node - Starting Network")
print("="*60)
print(f"Controller: FLEXRAY_01 | Slot ID: 1 | Channel: A")
print(f"Transmitting frames continuously...")
print("="*60)
print("Press Ctrl+C to stop\n")
# Transmit frames continuously starting immediately
counter = 0
sensor_temp = 20.0 # Simulated temperature sensor
sensor_pressure = 100.0 # Simulated pressure sensor
while running:
# Create new frame each time (important for FlexRay)
frame = icsneopy.FlexRayMessage()
frame.network = icsneopy.Network(icsneopy.Network.NetID.FLEXRAY_01)
frame.slotid = 1
frame.cycle = 0
frame.cycle_repetition = 1
frame.channel = icsneopy.FlexRay.Channel.A
# Simulate realistic sensor data
sensor_temp += random.uniform(-0.5, 0.5) # Temperature varies
sensor_pressure += random.uniform(-2.0, 2.0) # Pressure varies
# Pack data: [status, counter, temp_high, temp_low, pressure_high, pressure_low, checksum_placeholder, sequence]
status_byte = 0xA0 | (counter % 16) # Status with rolling bits
temp_int = int(sensor_temp * 10) & 0xFFFF
pressure_int = int(sensor_pressure * 10) & 0xFFFF
frame.data = (
status_byte,
counter & 0xFF,
(temp_int >> 8) & 0xFF,
temp_int & 0xFF,
(pressure_int >> 8) & 0xFF,
pressure_int & 0xFF,
random.randint(0, 255), # Random data
(counter >> 8) & 0xFF
)
success = device.transmit(frame)
if counter % 100 == 0: # Print every 100th to reduce spam
if success:
print(f" [TX {counter}] Temp: {sensor_temp:.1f}°C | Pressure: {sensor_pressure:.1f} kPa")
else:
print(f" Frame {counter}: Failed to transmit")
counter += 1
time.sleep(0.005) # 5ms per cycle
print("\nTransmission complete!")
finally:
device.close()
if __name__ == "__main__":
transmit_flexray_frame()