I’m trying to simulate a network with gPTP and Time-Aware-Shaper, where the gPTP Traffic is in a TAS Stream with pcp=7
. When running this simulation, I get an error after the first GptpPdleayReq Packages transmission is complete:
A runtime error occurred:
Tag 'inet::GptpIngressTimeInd' is absent -- in module (inet::Gptp) TsnNetwork.switch[0].gptp (id=251), at t=0.00000677s, event #47
I tried to find an example online or in the inet showcases, but haven’t found one. Even the invehicle showcase of inet the gPTP traffic is not sheduled with TAS.
network.ned:
import inet.networks.base.TsnNetworkBase;
import inet.node.tsn.TsnSwitch;
import inet.node.tsn.TsnDevice;
import inet.node.tsn.TsnClock;
import inet.node.ethernet.EthernetLink;
network TsnNetwork extends TsnNetworkBase
{
parameters:
*.eth[*].bitrate = default(100Mbps);
submodules:
clock: TsnClock;
client: TsnDevice;
switch[2]: TsnSwitch;
server: TsnDevice;
connections:
clock.ethg++ <--> EthernetLink <--> switch[0].ethg++;
client.ethg++ <--> EthernetLink <--> switch[0].ethg++;
switch[0].ethg++ <--> EthernetLink <--> switch[1].ethg++;
switch[1].ethg++ <--> EthernetLink <--> server.ethg++;
}
config.ini:
[General]
network = TsnNetwork
sim-time-limit = 1s
# disable local multicast loop
**.udp.defaultMulticastLoop = false
# client applications
*.client.numApps = 2
*.client.app[*].typename = "UdpSourceApp"
*.client.app[0].display-name = "dont care"
*.client.app[1].display-name = "important"
*.client.app[*].io.destAddress = "server"
*.client.app[0].io.destPort = 1000
*.client.app[1].io.destPort = 1001
*.client.app[*].source.packetLength = 1000B - 54B # 54B = 8B (UDP) + 20B (IP) + 14B (ETH MAC) + 4B (ETH FCS) + 8B (ETH PHY)
*.client.app[0].source.productionInterval = 200us # ~40Mbps
*.client.app[1].source.productionInterval = 400us # ~20Mbps
# server applications
*.server.numApps = 2
*.server.app[*].typename = "UdpSinkApp"
*.server.app[0].io.localPort = 1000
*.server.app[1].io.localPort = 1001
# enable outgoing streams
*.client.hasOutgoingStreams = true
#gPTP time synchronisation
#enable time synchronization in all network nodes
*.*.hasTimeSynchronization = true
# all oscillators have a random constant drift
**.clock.clock.oscillator.typename = "RandomDriftOscillator"
**.oscillator.changeInterval = 10ms
**.oscillator.driftRate = uniform(-100ppm, 100ppm)
**.oscillator.driftRateChange = uniform(-1ppm, 1ppm)
**.oscillator.driftRateChangeUpperLimit = 100ppm
**.oscillator.driftRateChangeLowerLimit = -100ppm
# Set all reference clocks to master clock so the time difference can be visualized
**.referenceClock = "clock.clock"
*.*.app[*].source.clockModule = "^.^.clock"
# TSN clock gPTP master ports
*.clock.gptp.masterPorts = ["eth0"]
# TSN switch gPTP bridge master ports
*.switch[0].gptp.masterPorts = ["eth1", "eth2"]
*.switch[1].gptp.masterPorts = ["eth1"]
#visualize clock time and device clock diff
*.visualizer.typename = "IntegratedMultiCanvasVisualizer"
*.visualizer.infoVisualizer[*].displayInfos = true
*.visualizer.numInfoVisualizers = 4
*.visualizer.infoVisualizer[0].modules = "*.clock.clock"
*.visualizer.infoVisualizer[1].modules = "*.switch[*].clock"
*.visualizer.infoVisualizer[2].modules = "*.server.clock"
*.visualizer.infoVisualizer[3].modules = "*.client.clock"
*.clock.clock.displayStringTextFormat = "time: %T"
*.server.clock.displayStringTextFormat = "diff: %d"
*.client.clock.displayStringTextFormat = "diff: %d"
*.switch[*].clock.displayStringTextFormat = "diff: %d"
#Time Aware Shaper
#gates use gPTP clock
*.*.eth[*].macLayer.queue.transmissionGate[*].clockModule = "^.^.^.^.clock"
# client stream identification
*.client.bridging.streamIdentifier.identifier.mapping = [{stream: "best effort", packetFilter: expr(has(udp) && udp.destPort == 1000)},
{stream: "high priority", packetFilter: expr(has(udp) && udp.destPort == 1001)},
{stream: "time sync",packetFilter: "Gptp*"}]
# client stream encoding
*.client.bridging.streamCoder.encoder.mapping = [{stream: "best effort", pcp: 0},
{stream: "high priority", pcp: 6},
{stream: "time sync", pcp: 7}]
# enable egress traffic shaping
*.switch[*].hasEgressTrafficShaping = true
# disable forwarding IEEE 802.1Q C-Tag
*.switch[*].bridging.directionReverser.reverser.excludeEncapsulationProtocols = ["ieee8021qctag"]
# time-aware traffic shaping
*.switch[*].eth[*].macLayer.queue.numTrafficClasses = 3
*.switch[*].eth[*].macLayer.queue.*[0].display-name = "dont care gate"
*.switch[*].eth[*].macLayer.queue.*[1].display-name = "important gate"
*.switch[*].eth[*].macLayer.queue.transmissionGate[0].offset = 2ms
*.switch[*].eth[*].macLayer.queue.transmissionGate[0].durations = [4ms, 6ms] # period is 10
*.switch[*].eth[*].macLayer.queue.transmissionGate[1].offset = 8ms
*.switch[*].eth[*].macLayer.queue.transmissionGate[1].durations = [2ms, 8ms]
*.switch[*].eth[*].macLayer.queue.transmissionGate[2].offset = 6ms
*.switch[*].eth[*].macLayer.queue.transmissionGate[2].durations = [2ms, 8ms]
#visualize gate schedules
**.displayGateSchedules = true
**.gateFilter = "**.eth[1].**"