/** * streamhub_demo.cfg — MARTe2 app for the StreamHub demo. * * Three real-time threads, each feeding a UDPStreamer instance. * * Thread1 1 kHz — 2 scalar sines @ 1 ksps (Accumulate mode) * Sine1 (1 Hz, 5 V, phase 0) * Sine2 (0.3 Hz, 3 V, phase 60 deg) * * Thread2 1 kHz — 2 array sines @ 1 Msps (1000 elem × 1 kHz, Strict) * Ch1 (1 kHz, 1 V, phase 0) * Ch2 (5 kHz, 0.5 V, phase 90 deg) * Strict publishing: every cycle's 1 ms array is sent so the * reconstructed waveform is contiguous (Decimate would drop * whole cycles, leaving periodic gaps in the array trace). * * Thread3 5 kHz — 2 array sines @ 5 Msps (1000 elem × 5 kHz, Strict) * Ch3 (10 kHz, 2 V, phase 0) * Ch4 (50 kHz, 1.5 V, phase 45 deg) */ $App = { Class = RealTimeApplication +Functions = { Class = ReferenceContainer // ── Thread1: 1 kHz scalar sines (1 ksps) ──────────────────────────── +TimerGAM = { Class = IOGAM InputSignals = { Counter = { DataSource = Timer Type = uint32 Frequency = 1000 } Time = { DataSource = Timer Type = uint32 } } OutputSignals = { Counter = { DataSource = DDB1 Type = uint32 } Time = { DataSource = DDB1 Type = uint32 } } } +SineGAM1 = { Class = SineArrayGAM Frequency = 1.0 Amplitude = 5.0 Phase = 0.0 Offset = 0.0 SamplingRate = 1000.0 OutputSignals = { Sine1 = { DataSource = DDB1 Type = float32 } } } +SineGAM2 = { Class = SineArrayGAM Frequency = 0.3 Amplitude = 3.0 Phase = 1.0472 Offset = 0.0 SamplingRate = 1000.0 OutputSignals = { Sine2 = { DataSource = DDB1 Type = float32 } } } +StreamerGAM1 = { Class = IOGAM InputSignals = { Counter = { DataSource = DDB1 Type = uint32 } Time = { DataSource = DDB1 Type = uint32 } Sine1 = { DataSource = DDB1 Type = float32 } Sine2 = { DataSource = DDB1 Type = float32 } } OutputSignals = { Counter = { DataSource = Streamer1 Type = uint32 } Time = { DataSource = Streamer1 Type = uint32 } Sine1 = { DataSource = Streamer1 Type = float32 } Sine2 = { DataSource = Streamer1 Type = float32 } } } // ── Thread2: 1 kHz, 1000-element arrays → 1 Msps ─────────────────── +MedTimerGAM = { Class = IOGAM InputSignals = { Time = { DataSource = MedTimer Type = uint32 Frequency = 1000 } } OutputSignals = { Time = { DataSource = DDB2 Type = uint32 } } } +SineGAM3 = { Class = SineArrayGAM Frequency = 1000.0 Amplitude = 1.0 Phase = 0.0 Offset = 0.0 SamplingRate = 1000000.0 OutputSignals = { Ch1 = { DataSource = DDB2 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 } } } +SineGAM4 = { Class = SineArrayGAM Frequency = 5000.0 Amplitude = 0.5 Phase = 1.5708 Offset = 0.0 SamplingRate = 1000000.0 OutputSignals = { Ch2 = { DataSource = DDB2 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 } } } +TimeArrayGAM1 = { Class = TimeArrayGAM SamplingRate = 1000000.0 Anchor = "FirstSample" InputSignals = { Time = { DataSource = DDB2 Type = uint32 } } OutputSignals = { TimeArray1 = { DataSource = DDB2 Type = uint64 NumberOfDimensions = 1 NumberOfElements = 1000 } } } +StreamerGAM2 = { Class = IOGAM InputSignals = { TimeArray1 = { DataSource = DDB2 Type = uint64 NumberOfDimensions = 1 NumberOfElements = 1000 } Ch1 = { DataSource = DDB2 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 } Ch2 = { DataSource = DDB2 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 } } OutputSignals = { TimeArray1 = { DataSource = Streamer2 Type = uint64 NumberOfDimensions = 1 NumberOfElements = 1000 } Ch1 = { DataSource = Streamer2 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 } Ch2 = { DataSource = Streamer2 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 } } } // ── Thread3: 5 kHz, 1000-element arrays → 5 Msps ─────────────────── +FastTimerGAM = { Class = IOGAM InputSignals = { Time = { DataSource = FastTimer Type = uint32 Frequency = 5000 } } OutputSignals = { Time = { DataSource = DDB3 Type = uint32 } } } +SineGAM5 = { Class = SineArrayGAM Frequency = 10000.0 Amplitude = 2.0 Phase = 0.0 Offset = 0.0 SamplingRate = 5000000.0 OutputSignals = { Ch3 = { DataSource = DDB3 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 } } } +SineGAM6 = { Class = SineArrayGAM Frequency = 50000.0 Amplitude = 1.5 Phase = 0.7854 Offset = 0.0 SamplingRate = 5000000.0 OutputSignals = { Ch4 = { DataSource = DDB3 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 } } } +TimeArrayGAM2 = { Class = TimeArrayGAM SamplingRate = 5000000.0 Anchor = "FirstSample" InputSignals = { Time = { DataSource = DDB3 Type = uint32 } } OutputSignals = { TimeArray2 = { DataSource = DDB3 Type = uint64 NumberOfDimensions = 1 NumberOfElements = 1000 } } } +StreamerGAM3 = { Class = IOGAM InputSignals = { TimeArray2 = { DataSource = DDB3 Type = uint64 NumberOfDimensions = 1 NumberOfElements = 1000 } Ch3 = { DataSource = DDB3 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 } Ch4 = { DataSource = DDB3 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 } } OutputSignals = { TimeArray2 = { DataSource = Streamer3 Type = uint64 NumberOfDimensions = 1 NumberOfElements = 1000 } Ch3 = { DataSource = Streamer3 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 } Ch4 = { DataSource = Streamer3 Type = float32 NumberOfDimensions = 1 NumberOfElements = 1000 } } } } +Data = { Class = ReferenceContainer DefaultDataSource = DDB1 +DDB1 = { Class = GAMDataSource } +DDB2 = { Class = GAMDataSource } +DDB3 = { Class = GAMDataSource } +Timer = { Class = LinuxTimer SleepNature = "Default" Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } } +MedTimer = { Class = LinuxTimer SleepNature = "Default" Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } } +FastTimer = { Class = LinuxTimer SleepNature = "Default" Signals = { Counter = { Type = uint32 } Time = { Type = uint32 } } } +Streamer1 = { Class = UDPStreamer Port = 44500 MulticastGroup = "239.0.0.1" DataPort = 44503 MaxPayloadSize = 1400 PublishingMode = "Accumulate" MinRefreshRate = 100 Signals = { Counter = { Type = uint32 } Time = { Type = uint32 Unit = "us" } Sine1 = { Type = float32 Unit = "V" RangeMin = -5.0 RangeMax = 5.0 } Sine2 = { Type = float32 Unit = "V" RangeMin = -3.0 RangeMax = 3.0 } } } +Streamer2 = { Class = UDPStreamer Port = 44501 // One full cycle = TimeArray1(8000) + Ch1(4000) + Ch2(4000) = 16000 B. // Sizing the payload above a whole cycle sends each cycle as a single // datagram (totalFragments = 1): at Strict 1 kHz / 5 kHz this avoids // saturating the receiver's fragment-reassembly pool, which otherwise // evicts in-flight cycles and reintroduces gaps in the array traces. MaxPayloadSize = 18000 PublishingMode = "Strict" Signals = { TimeArray1 = { Type = uint64 Unit = "ns" NumberOfDimensions = 1 NumberOfElements = 1000 } Ch1 = { Type = float32 Unit = "V" NumberOfDimensions = 1 NumberOfElements = 1000 TimeMode = "FullArray" TimeSignal = TimeArray1 } Ch2 = { Type = float32 Unit = "V" NumberOfDimensions = 1 NumberOfElements = 1000 TimeMode = "FullArray" TimeSignal = TimeArray1 } } } +Streamer3 = { Class = UDPStreamer Port = 44502 // One full cycle = TimeArray2(8000) + Ch3(4000) + Ch4(4000) = 16000 B. // Single-datagram cycles (see Streamer2) — essential here because this // source runs Strict at 5 kHz, where per-cycle fragmentation would flood // the reassembly pool. MaxPayloadSize = 18000 PublishingMode = "Strict" Signals = { TimeArray2 = { Type = uint64 Unit = "ns" NumberOfDimensions = 1 NumberOfElements = 1000 } Ch3 = { Type = float32 Unit = "V" NumberOfDimensions = 1 NumberOfElements = 1000 TimeMode = "FullArray" TimeSignal = TimeArray2 } Ch4 = { Type = float32 Unit = "V" NumberOfDimensions = 1 NumberOfElements = 1000 TimeMode = "FullArray" TimeSignal = TimeArray2 } } } +Timings = { Class = TimingDataSource } } +States = { Class = ReferenceContainer +Running = { Class = RealTimeState +Threads = { Class = ReferenceContainer +Thread1 = { Class = RealTimeThread CPUs = 0x1 Functions = { TimerGAM, SineGAM1, SineGAM2, StreamerGAM1 } } +Thread2 = { Class = RealTimeThread CPUs = 0x2 Functions = { MedTimerGAM, SineGAM3, SineGAM4, TimeArrayGAM1, StreamerGAM2 } } +Thread3 = { Class = RealTimeThread CPUs = 0x4 Functions = { FastTimerGAM, SineGAM5, SineGAM6, TimeArrayGAM2, StreamerGAM3 } } } } } +Scheduler = { Class = GAMScheduler TimingDataSource = Timings } }