Device: FlexRay: Add additional configuration options for Controller and Cluster
parent
5f16adc103
commit
6a32823a0f
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>`
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -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()
|
||||||
Loading…
Reference in New Issue