Endüstriyel Ethernet
TEKNİK REHBER ENDÜSTRİYEL ETHERNET PROFINET 2026

PROFINET —
Siemens endüstriyel Ethernet.

IEC 61158/61784: RT ve IRT sınıflarıyla endüstriyel otomasyon ağlarında gerçek zamanlı cyclic IO iletişimi. p-net stack ile Linux üzerinde açık kaynak IO Device implementasyonu.

00 PROFINET nedir — IEC 61158/61784 ve sınıflar

PROFINET (Process Field Network), Siemens ve PROFIBUS & PROFINET International (PI) tarafından geliştirilen, IEC 61158 Type 10 ve IEC 61784-2 CP3/1-4 standartlarıyla tanımlanmış endüstriyel Ethernet protokolüdür. PROFIBUS'un Ethernet üzerine taşınmış ve genişletilmiş halefidir.

PROFINET RT sınıfları

SınıfCycle TimeGecikmeUygulama
CC-A (RT Class 1)≥ 10 msSoft RTPLC → I/O modülü, sensör/aktüatör
CC-B (RT Class 2)1-10 msSoft RTHız kontrol, pozisyonlama (standart)
CC-C (IRT)250 µs - 1 msHard RTÇok eksenli hareket kontrolü
CC-D (IRT+)31.25 µs+Hard RT++Yüksek dinamik servo sistemleri
RT (Real-Time)Standart Ethernet üzerinde VLAN önceliklendirmesi (802.1Q) ile soft gerçek zamanlı iletişim. Özel donanım gerekmez.
IRT (Isochronous Real-Time)Özel switch donanımı gerektirir. Frame'ler önceden hesaplanmış zaman dilimlerine yerleştirilir. Jitter < 1 µs.

PROFINET ve PROFIBUS karşılaştırması

ÖzellikPROFIBUS DPPROFINET
Fiziksel katmanRS-485, 9.6 Kbps – 12 Mbps100/1000 BASE-T
TopolojiBus (daisy-chain)Yıldız, halka, hat
Max cihaz126255+ (switch ile sınırsız)
Parametre aktarımıDPV0/DPV1 acyclicRPC (record data)
IT entegrasyonuGateway gerekirDoğrudan IP üzerinden

01 Mimari — IO Controller, IO Device, IO Supervisor

PROFINET üç temel rol tanımlar: IO Controller (PLC), IO Device (saha cihazı) ve IO Supervisor (engineering/HMI istasyonu). Bu roller, Application Relationships (AR) ve Communication Relationships (CR) üzerinden birbirleriyle iletişim kurar.

Roller ve sorumluluklar

IO ControllerAğı yöneten PLC veya master. IO Device'lara çıkış verisi gönderir ve giriş verisini alır. Konfigürasyonu başlatır, alarmlara tepki verir. Örn: Siemens S7-1500, Beckhoff CX.
IO DeviceSaha cihazı: dijital I/O modülü, servo sürücü, sensör/aktüatör ağ geçidi. IO Controller tarafından konfigüre edilir. Örn: ET 200SP, WAGO 750-352.
IO SupervisorEngineering istasyonu veya HMI. IO Device'ları programlar, parametrize eder ve diagnostics okur. Sadece geliştirme/bakım sırasında aktif.

Application Relationship (AR) yapısı

IO Controller (PLC)
    │
    │ AR (Application Relationship — UUID ile tanımlanır)
    │ ├── IO-CR (Cyclic IO Communication Relationship)
    │ │     ├── Output CR: Controller → Device (RxData)
    │ │     └── Input  CR: Device → Controller (TxData)
    │ ├── Record-Data CR (acyclic read/write — RPC)
    │ └── Alarm CR (alarmlar için)
    │
IO Device (ET200SP gibi)
    ├── Slot 0: Device Access Point (DAP)
    ├── Slot 1: 8DI module
    ├── Slot 2: 8DO module
    └── Slot 3: 4AI module
NOT

AR UUID, her konfigürasyonda benzersizdir. IO Controller, AR'ı başlatırken UUID oluşturur; IO Device bu UUID ile AR'ı tanır. Konfigürasyon değiştiğinde AR yeniden kurulur.

02 GSD dosyası — GSDML v2.x, slot/subslot, module

GSDML (General Station Description Markup Language), bir IO Device'ın desteklediği modülleri, parametreleri ve iletişim özelliklerini tanımlayan XML tabanlı dosyasıdır. IO Controller engineering aracı (TIA Portal gibi) bu dosyayı okuyarak cihazı konfigüre eder.

GSDML temel yapısı

<?xml version="1.0" encoding="UTF-8"?>
<!-- GSDML-V2.4-EmbeddedDeck-DigitalIO-2026.xml -->
<ISO15745Profile xmlns="http://www.profibus.com/GSDML/2003/11/DeviceProfile">

  <ProfileHeader>
    <ProfileIdentification>PROFINET Device Profile</ProfileIdentification>
    <GSDRevision>2</GSDRevision>
  </ProfileHeader>

  <ProfileBody>
    <DeviceIdentity>
      <VendorName Value="EmbeddedDeck"/>
      <!-- Vendor ID: PROFINET üye numarası (0x0000=test) -->
      <DeviceID Value="0x0001"/>
      <VendorID Value="0x0000"/>
    </DeviceIdentity>

    <DeviceFunction>
      <Family MainFamily="I/O" ProductFamily="Digital I/O"/>
    </DeviceFunction>

    <ApplicationProcess>
      <DeviceAccessPointList>
        <DeviceAccessPointItem ID="DAP1"
          PhysicalSlots="0..3"
          ModuleIdentNumber="0x00000001"
          MinDeviceInterval="32"
          DNS_CompatibleName="embedded-deck-dio">

          <ModuleInfo>
            <Name Value="EmbeddedDeck Digital IO"/>
            <HardwareRelease Value="V1.0"/>
            <SoftwareRelease Value="V1.0"/>
          </ModuleInfo>

          <SubmoduleList>
            <SubmoduleItem SubmoduleIdentNumber="0x00000001"
              Subslot="1">
              <IOData>
                <Output Length="1" Consistency="All items consistency"/>
                <Input  Length="1" Consistency="All items consistency"/>
              </IOData>
            </SubmoduleItem>
          </SubmoduleList>
        </DeviceAccessPointItem>
      </DeviceAccessPointList>

      <ModuleList>
        <!-- 8DI modülü -->
        <ModuleItem ID="8DI_Module"
          ModuleIdentNumber="0x00000002">
          <ModuleInfo>
            <Name Value="8 Channel Digital Input"/>
          </ModuleInfo>
          <SubmoduleList>
            <SubmoduleItem SubmoduleIdentNumber="0x00000002" Subslot="1">
              <IOData>
                <Input Length="1" Consistency="All items consistency"/>
              </IOData>
            </SubmoduleItem>
          </SubmoduleList>
        </ModuleItem>

        <!-- 8DO modülü -->
        <ModuleItem ID="8DO_Module"
          ModuleIdentNumber="0x00000003">
          <ModuleInfo>
            <Name Value="8 Channel Digital Output"/>
          </ModuleInfo>
          <SubmoduleList>
            <SubmoduleItem SubmoduleIdentNumber="0x00000003" Subslot="1">
              <IOData>
                <Output Length="1" Consistency="All items consistency"/>
              </IOData>
            </SubmoduleItem>
          </SubmoduleList>
        </ModuleItem>
      </ModuleList>
    </ApplicationProcess>
  </ProfileBody>

</ISO15745Profile>
SlotFiziksel veya mantıksal modül yuvası. Slot 0 her zaman Device Access Point (DAP) içindir.
SubslotBir slot içindeki alt birim. 0x8000: interface submodule, 0x8001: port 1, 0x8002: port 2, 1+: uygulama submodülleri.
ModuleIdentNumberModülün benzersiz kimliği. IO Controller, bu değeri doğrulayarak doğru modülün takılı olduğunu kontrol eder.
MinDeviceIntervalMinimum cyclic interval. 32 = 1 ms (32 × 31.25 µs). Daha küçük değer daha hızlı döngü = IRT gerektirir.

03 Cyclic data exchange — IO-CR ve DCP protokolü

PROFINET cyclic iletişim iki aşamadan oluşur: DCP ile cihaz keşfi/yapılandırma, ardından IO-CR üzerinden döngüsel veri alışverişi.

DCP (Discovery and Configuration Protocol)

DCP, IO Controller'ın ağdaki IO Device'ları bulmasını ve IP adresi ile station name atamasını sağlar. Ethernet Multicast üzerinden çalışır (EtherType: 0x8892).

# Wireshark ile DCP izleme
tshark -i eth0 -Y "pn_dcp" -V
# DCP Identify All (Multicast: 01:0e:cf:00:00:00)
# DCP Set Station Name: "embedded-deck-dio"
# DCP Set IP Address: 192.168.1.10

# pnio-cm araçları ile DCP (Linux)
sudo apt install pnio-tools  # veya kaynak koddan
pndcp -i eth0 identify       # Tüm PROFINET cihazları listele

AR kurulum akışı

IO Controller              IO Device
     │                         │
     │── DCP Identify ────────►│  (station name ile bul)
     │◄─ DCP Identify Resp ────│
     │                         │
     │── DCP Set IP/Name ─────►│
     │◄─ DCP Set Response ─────│
     │                         │
     │  ──── RPC üzerinden ──── │
     │── Connect Request ──────►│  (AR oluştur, modül listesi)
     │◄─ Connect Response ──────│  (AR UUID, frame ID'ler)
     │                         │
     │── Write Request ────────►│  (parametreler yaz)
     │◄─ Write Response ────────│
     │                         │
     │── Control Request ──────►│  (ApplicationReady)
     │◄─ Control Response ──────│
     │                         │
     │  ═══ Cyclic IO-CR ══════ │
     │══► [RxData: 0x8000] ════►│  (Output: DO verileri)
     │◄══ [TxData: 0x8001] ◄════│  (Input:  DI verileri)

IO-CR frame yapısı

AlanBoyutAçıklama
Ethernet Header14 byteEtherType: 0x8892 (PROFINET RT)
FrameID2 byte0x8000-0xBFFF: cyclic RT data
CycleCounter2 byteDöngü sayacı (modulo 65536)
DataStatus1 bytePrimary/Backup, Run/Stop, Valid/Invalid
TransferStatus1 byte0x00 = OK, diğerleri hata
IO Datan byteGerçek proses verisi (IOPS+IOCS dahil)

04 Alarm ve diagnostic mekanizması

PROFINET, IO Device'larda oluşan arızaları IO Controller'a bildirmek için kapsamlı bir alarm mekanizması tanımlar. Alarmlar, cyclic veri kanalından bağımsız olarak Alarm CR üzerinden iletilir.

Alarm türleri

Diagnosis AlarmBir kanalda hata oluştuğunda veya düzeldiğinde tetiklenir. Örn: kablo kopması, kısa devre, sensör beslemesi arızası.
Process AlarmSüreç değerinin limitler dışına çıkması gibi uygulama seviyesi olaylar. Kullanıcı tanımlı.
Pull/Plug AlarmSıcak takma/çıkarma (hot swap) olayları. IO Device modül çıkarılabilir olduğunda gönderilir.
Status AlarmIO Device durumu değişikliği. Örn: firmware güncelleme tamamlandı.
Update AlarmIO Device parametrelerinin güncellenmesi gerektiğini bildirir.

Channel diagnostic yapısı

/* p-net ile diagnostic gönderme örneği */
#include "pnet_api.h"

/* Kanal 3'te kısa devre hatası oluştu */
int send_channel_diagnosis(pnet_t *net, uint32_t api,
                           uint16_t slot, uint16_t subslot)
{
    pnet_diag_source_t diag_source = {
        .api     = api,
        .slot    = slot,
        .subslot = subslot,
        .ch      = 3,         /* Kanal numarası */
        .ch_prop = PNET_CH_PROP_TYPE_1_BIT |
                   PNET_CH_PROP_DIR_OUTPUT,
        .ch_error_type = PNET_DIAG_CH_ERR_SHORT_CIRCUIT,
    };

    /* Diagnosis ekle: hata aktif */
    return pnet_diag_std_add(net, &diag_source,
        PNET_DIAG_CH_PROP_SPEC_APPEARS,
        PNET_DIAG_CH_ERR_SHORT_CIRCUIT);
}

/* Hata düzeldikten sonra: */
int clear_channel_diagnosis(pnet_t *net, uint32_t api,
                             uint16_t slot, uint16_t subslot)
{
    pnet_diag_source_t diag_source = {
        .api     = api,
        .slot    = slot,
        .subslot = subslot,
        .ch      = 3,
        .ch_prop = PNET_CH_PROP_TYPE_1_BIT |
                   PNET_CH_PROP_DIR_OUTPUT,
    };

    return pnet_diag_std_add(net, &diag_source,
        PNET_DIAG_CH_PROP_SPEC_DISAPPEARS,
        PNET_DIAG_CH_ERR_SHORT_CIRCUIT);
}

05 p-net — açık kaynak PROFINET stack

p-net, RT Labs AB tarafından geliştirilen Apache 2.0 lisanslı açık kaynak PROFINET IO Device stack'tir. Linux, RTOS ve bare-metal platformlarda IO Device implementasyonu için kullanılır.

p-net özellikleri

Konformans sınıfıCC-A ve CC-B desteği. PROFINET logosu için RT Labs sertifika testi hizmeti sunar.
MultiplatformLinux (POSIX), FreeRTOS, rt-kernel. OSAL (OS Abstraction Layer) ile kolayca yeni platforma taşınır.
Slot/Subslot desteğiÇoklu slot, subslot ve modül desteği. GSDML ile eşleşen dinamik konfigürasyon.

Derleme ve kurulum

sudo apt install cmake libpcap-dev

git clone https://github.com/rtlabs-com/p-net.git
cd p-net && mkdir build && cd build

cmake .. \
    -DCMAKE_BUILD_TYPE=Debug \
    -DBUILD_SHARED_LIBS=OFF \
    -DUSE_SNMP=ON

make -j$(nproc)

# Örnek uygulamayı çalıştır
sudo ./pn_dev -i eth0 -v

p-net callback implementasyonu

/* pnet_callbacks.c — p-net callback fonksiyonları */
#include "pnet_api.h"
#include <stdio.h>
#include <string.h>

/* Cyclic veri yazma callback: IO Controller → Device */
int app_write_ind(pnet_t *net, void *arg,
                  uint32_t api, uint16_t slot,
                  uint16_t subslot, uint16_t idx,
                  uint16_t sequence_number, bool write_request,
                  const pnet_data_cfg_t *p_data_cfg,
                  uint16_t data_length, uint8_t *p_data)
{
    /* Slot 1, Subslot 1: 8DO modülü */
    if (slot == 1 && subslot == 1) {
        uint8_t outputs = p_data[0];
        printf("DO değerleri: 0x%02X\n", outputs);
        /* GPIO'lara yaz */
        gpio_write_byte(outputs);
    }
    return 0;
}

/* Cyclic veri okuma callback: Device → IO Controller */
int app_read_ind(pnet_t *net, void *arg,
                 uint32_t api, uint16_t slot,
                 uint16_t subslot, uint16_t idx,
                 uint16_t sequence_number, bool write_request,
                 const pnet_data_cfg_t *p_data_cfg,
                 uint16_t data_length, uint8_t **pp_read_data,
                 uint16_t *p_read_length, pnet_result_t *p_result)
{
    static uint8_t input_data[1];

    /* Slot 2, Subslot 1: 8DI modülü */
    if (slot == 2 && subslot == 1) {
        input_data[0] = gpio_read_byte();  /* GPIO'dan oku */
        *pp_read_data  = input_data;
        *p_read_length = sizeof(input_data);
    }
    return 0;
}

/* Bağlantı durumu callback */
int app_state_ind(pnet_t *net, void *arg,
                  uint32_t arep, pnet_event_values_t state)
{
    switch (state) {
    case PNET_EVENT_STARTUP:
        printf("IO Controller bağlandı\n"); break;
    case PNET_EVENT_PRMEND:
        printf("Parametreler alındı, IO başlıyor\n"); break;
    case PNET_EVENT_APPLRDY:
        printf("Application Ready: cyclic IO aktif\n"); break;
    case PNET_EVENT_ABORT:
        printf("Bağlantı kesildi\n"); break;
    }
    return 0;
}

06 Wireshark ile PROFINET analizi

Wireshark, PROFINET protokollerini (RT, DCP, PTCP, RPC) yerleşik olarak ayrıştırır. Doğru filtreler ve renk kurallarıyla PROFINET iletişiminin her katmanı detaylıca incelenebilir.

Temel filtreler

FiltreGösterir
pn_rtTüm PROFINET RT trafiği (cyclic IO)
pn_dcpDCP Identify, Set, Get mesajları
pn_rpcRPC: Connect, Write, Control (AR kurulumu)
pn_ioPROFINET IO uygulama katmanı
pn_ptcpPROFINET PTCP senkronizasyon
eth.type == 0x8892Tüm PROFINET EtherType frame'leri
pn_rt.frame_id == 0x8000Belirli FrameID'ye sahip cyclic data
# Komut satırından PROFINET yakalama
tshark -i eth0 -Y "pn_dcp or pn_rpc" \
       -T fields \
       -e frame.time \
       -e pn_dcp.service_id \
       -e pn_dcp.service_type \
       -e ip.src -e ip.dst

# Cyclic veri istatistikleri (FrameID = 0x8000)
tshark -i eth0 -Y "pn_rt.frame_id == 0x8000" \
       -q -z io,stat,1 2>&1 | head -20

# Döngü süresi hesapla (1000 cyclic frame yakala)
tshark -i eth0 -Y "pn_rt" -c 1000 \
       -T fields -e frame.time_relative \
       > times.txt
awk 'NR>1{printf "%.3f ms\n", ($1-prev)*1000} {prev=$1}' times.txt | \
    sort -n | tail -5  # En uzun döngü süreleri

Yaygın sorunlar ve teşhis

Missing CycleCountersCyclic frame'lerde ardışık sayaç atlamaları → Frame kayıpları. Switch port istatistiklerini kontrol et.
DataStatus bit 2 = 0IO Device "Run" değil "Stop" durumunda. AR henüz tamamlanmamış veya watchdog dolmuş.
RPC Connect RejectModuleIdentNumber uyuşmazlığı. GSDML'deki IdentNumber ile fiziksel cihazın döndürdüğü değer farklı.
DCP Station Name mismatchCihazın kayıtlı station name'i Controller'ın beklediğiyle uyuşmuyor. DCP Set Name ile düzelt.

07 PREEMPT_RT kernel ile cycle time optimizasyonu

p-net ile Linux üzerinde PROFINET IO Device çalıştırırken cyclic görevin tutarlı zaman dilimine sahip olması gerekir. PREEMPT_RT yaması ve CPU izolasyonu ile millisaniyenin altında jitter değerleri elde edilebilir.

Kernel konfigürasyonu

# PREEMPT_RT kernel derle
wget https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/linux-6.6.tar.xz
wget https://mirrors.edge.kernel.org/pub/linux/kernel/projects/rt/6.6/\
     patch-6.6-rt14.patch.xz

tar xf linux-6.6.tar.xz && cd linux-6.6
xzcat ../patch-6.6-rt14.patch.xz | patch -p1

# Menü konfigürasyonu
make menuconfig
# General Setup → Preemption Model → "Fully Preemptible Kernel (Real-Time)"
# High Resolution Timers → Enabled (zorunlu)

make -j$(nproc) && sudo make modules_install install

CPU izolasyonu ve IRQ yönetimi

# /boot/cmdline.txt (Raspberry Pi) veya GRUB
# Ek kernel parametreleri:
isolcpus=2,3 nohz_full=2,3 rcu_nocbs=2,3

# PROFINET NIC IRQ'sunu izole edilmiş CPU'ya ata
IFNAME=eth0
IRQ=$(cat /proc/interrupts | grep $IFNAME | awk '{print $1}' | tr -d ':')
echo 4 > /proc/irq/$IRQ/smp_affinity   # CPU 2 ve 3 (bitmask)

# NAPI polling'i disable et (RT için)
ethtool -C eth0 rx-usecs 0 rx-frames 1

# p-net uygulamasını RT thread olarak başlat
chrt -f 80 ./pn_dev -i eth0 --cpu 2

cyclictest ile ölçüm

# PROFINET döngüsüyle eş zamanlı latency ölçümü
sudo cyclictest \
    --mlockall \
    --smp \
    --priority=90 \
    --interval=1000 \
    --distance=0 \
    --loops=100000 \
    --histogram=400 \
    --quiet

# Tipik sonuçlar (PREEMPT_RT + CPU izolasyonu):
# T: 0 (0:X) P:90 I:1000 C:100000 Min:   8 Act:  12 Avg:  14 Max:  47
#
# Standart kernel ile:
# T: 0 (0:X) P:90 I:1000 C:100000 Min:  15 Act:  85 Avg: 120 Max: 2847

p-net RT konfigürasyon özeti

OptimizasyonEtkiTipik Kazanım
PREEMPT_RT kernelKesme gecikmesi azalırMax latency: 2.8 ms → 50 µs
CPU izolasyonuScheduler müdahalesi azalırJitter: ±200 µs → ±20 µs
IRQ affinityNIC kesmeleri dedike CPU'daOrtalama: -30 µs
mlockall()Page fault yokSpike'lar azalır
SCHED_FIFO P:80+RT görev preempt edilmezDeterministik döngü
NOT

PROFINET CC-B sertifikasyon testleri, 1 ms döngüde maksimum ±250 µs jitter gerektirir. PREEMPT_RT + CPU izolasyonu ile bu gereksinim çoğu donanımda karşılanabilir.