FlexRay Getting Started

Prerequisites

  • icsneopy installed (see Installation)

  • 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:

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")
  1. Configure FlexRay controller:

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

  1. Open device and go online:

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

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

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

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

FlexRay Coldstart Configuration

To use the Coldstart example, ensure the following:

Set the Flexray network in ICS Device Manager to Coldstart.

No other nodes should be present on the network during testing.

Nothing connected to Fire3 FlexRay bus.

Critical Coldstart Settings

	# 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
	

Configuration Example:

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

Setting Coldstart on Controller:

controller.set_allow_coldstart(True)
controller.set_start_when_going_online(True)

Cleanup and Resource Management

Always close the device when finished:

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

flexray_transmit_basic.py

Receive Basic - Receiving and displaying FlexRay frames with formatted output

flexray_receive_basic.py

Coldstart - Standalone coldstart example demonstrating network initialization

flexray_coldstart.py