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ıf | Cycle Time | Gecikme | Uygulama |
|---|---|---|---|
| CC-A (RT Class 1) | ≥ 10 ms | Soft RT | PLC → I/O modülü, sensör/aktüatör |
| CC-B (RT Class 2) | 1-10 ms | Soft RT | Hız kontrol, pozisyonlama (standart) |
| CC-C (IRT) | 250 µs - 1 ms | Hard RT | Çok eksenli hareket kontrolü |
| CC-D (IRT+) | 31.25 µs+ | Hard RT++ | Yüksek dinamik servo sistemleri |
PROFINET ve PROFIBUS karşılaştırması
| Özellik | PROFIBUS DP | PROFINET |
|---|---|---|
| Fiziksel katman | RS-485, 9.6 Kbps – 12 Mbps | 100/1000 BASE-T |
| Topoloji | Bus (daisy-chain) | Yıldız, halka, hat |
| Max cihaz | 126 | 255+ (switch ile sınırsız) |
| Parametre aktarımı | DPV0/DPV1 acyclic | RPC (record data) |
| IT entegrasyonu | Gateway gerekir | Doğ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
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
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>
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ı
| Alan | Boyut | Açıklama |
|---|---|---|
| Ethernet Header | 14 byte | EtherType: 0x8892 (PROFINET RT) |
| FrameID | 2 byte | 0x8000-0xBFFF: cyclic RT data |
| CycleCounter | 2 byte | Döngü sayacı (modulo 65536) |
| DataStatus | 1 byte | Primary/Backup, Run/Stop, Valid/Invalid |
| TransferStatus | 1 byte | 0x00 = OK, diğerleri hata |
| IO Data | n byte | Gerç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
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
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
| Filtre | Gösterir |
|---|---|
pn_rt | Tüm PROFINET RT trafiği (cyclic IO) |
pn_dcp | DCP Identify, Set, Get mesajları |
pn_rpc | RPC: Connect, Write, Control (AR kurulumu) |
pn_io | PROFINET IO uygulama katmanı |
pn_ptcp | PROFINET PTCP senkronizasyon |
eth.type == 0x8892 | Tüm PROFINET EtherType frame'leri |
pn_rt.frame_id == 0x8000 | Belirli 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
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
| Optimizasyon | Etki | Tipik Kazanım |
|---|---|---|
| PREEMPT_RT kernel | Kesme gecikmesi azalır | Max latency: 2.8 ms → 50 µs |
| CPU izolasyonu | Scheduler müdahalesi azalır | Jitter: ±200 µs → ±20 µs |
| IRQ affinity | NIC kesmeleri dedike CPU'da | Ortalama: -30 µs |
| mlockall() | Page fault yok | Spike'lar azalır |
| SCHED_FIFO P:80+ | RT görev preempt edilmez | Deterministik döngü |
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.