00 EtherCAT nedir — IEC 61158 ve Beckhoff mirası
EtherCAT (Ethernet for Control Automation Technology), 2003 yılında Beckhoff Automation tarafından geliştirilmiş ve 2007'de IEC 61158 Type 12 / IEC 61784-2 standardı olarak yayımlanmış bir endüstriyel Ethernet protokolüdür. Temel yeniliği, Ethernet frame'inin slave düğümlerden geçerken "on-the-fly" okunup yazılmasıdır.
Geleneksel Ethernet ağlarında her düğüm tam bir frame alır, işler ve iletir. EtherCAT'ta ise frame master'dan çıkar, her slave sadece kendine ait bayt(lar)ı okur ve günceller; frame hattın sonuna ulaştığında tüm process data güncellenmiş olur. Bu yaklaşım, yüzlerce slave için bile 100 µs'nin altında döngü süreleri sağlar.
Master ──► [Slave 1] ──► [Slave 2] ──► [Slave 3] ──┐
▲ │ (son slave geri döner)
└──────────────────────────────────────────────────┘
Frame tek geçişte tüm slave'leri dolaşır
Standart ailesi
| Standart | Kapsam |
|---|---|
| IEC 61158 Type 12 | EtherCAT veri bağı katmanı |
| IEC 61784-2 CP12 | Profil ve konfigürasyon |
| ETG.1000 | EtherCAT Technology Group spesifikasyonu |
| ETG.5000 | Slave Uygulama Katmanı (CoE, FoE, EoE, SoE) |
| ETG.1020 | Redundancy (halka topoloji) |
EtherCAT Technology Group (ETG), 5000'den fazla üyesiyle dünyanın en büyük endüstriyel Ethernet kuruluşudur. Ücretsiz standart dokümanlara ethercat.org adresinden ulaşılabilir.
01 Fiziksel katman — 100BASE-TX ve daisy-chain
EtherCAT, standart 100BASE-TX Ethernet fiziksel katmanını kullanır; bu sayede mevcut RJ-45 kablolar ve anahtarlar kolayca devreye alınabilir. Ancak her slave'in iki portu vardır ve bu portlar birbirine zincirlenerek daisy-chain (ardışık) topoloji oluşturur.
Topoloji seçenekleri
On-the-fly işleme mekanizması
Her EtherCAT slave'inde bir ESC (EtherCAT Slave Controller) yongası bulunur. Bu yonga, gelen Ethernet frame'ini geçirirken kendine ait Process Data alanlarını donanım seviyesinde (FPGA/ASIC) okur ve yazar. Yazılım müdahalesi olmadığından gecikme sabit ve öngörülebilirdir: tipik slave geçiş gecikmesi ~300 ns'dir.
Ethernet Frame (1518 byte maks) ┌──────────┬──────────┬───────────────────────────────┬──────┐ │ Ethernet │ EtherCAT │ EtherCAT Datagram(lar) │ FCS │ │ Header │ Header │ [Hdr|Data|WKC] [Hdr|Data|WKC] │ │ │ 14 byte │ 2 byte │ her biri bir slave grubuna │ 4B │ └──────────┴──────────┴───────────────────────────────┴──────┘ EtherType: 0x88A4
Bir EtherCAT frame'i birden fazla datagram içerebilir. Tipik uygulamalarda PDO verisi için bir datagram, distributed clock senkronizasyonu için ayrı bir datagram kullanılır.
02 Datagram yapısı ve adres modeli
EtherCAT datagramı, komut türü, adres, veri ve WKC (Working Counter) alanlarından oluşur. WKC, kaç slave'in datagramı başarıyla işlediğini sayar; master bu değeri beklenen sayıyla karşılaştırarak iletişim durumunu doğrular.
Datagram başlığı
| Alan | Boyut | Açıklama |
|---|---|---|
| CMD | 1 byte | Komut (APRD, APWR, FPRD, FPWR, BRD, LRD, LWR, LRW…) |
| IDX | 1 byte | Master tarafından atanan datagram index'i |
| ADR | 4 byte | Adres alanı (auto-increment veya configured station address) |
| LEN | 11 bit | Veri uzunluğu (maks 1486 byte) |
| R | 3 bit | Rezerve |
| C | 1 bit | Döngüsel bit (halka topoloji) |
| NEXT | 1 bit | Sonraki datagram var mı? |
| IRQ | 2 byte | Kesme bayrağı |
| DATA | n byte | Process/servis verisi |
| WKC | 2 byte | Working Counter |
Komut türleri
FMMU ve SyncManager
FMMU (Fieldbus Memory Management Unit): Slave içinde mantıksal adreslerden fiziksel ESC kayıt adreslerine dönüşüm yapar. Master, konfigürasyon aşamasında her slave'in FMMU'sunu programlar; böylece tek bir LRW komutu tüm ağın process datasını günceller.
SyncManager: ESC'deki çift tampon mekanizmasıdır. SM0/SM1 mailbox iletişimi (SDO), SM2/SM3 ise cyclic PDO verisi için kullanılır. Datanın tutarlı okunmasını ve yarış koşullarını önler.
Master Mantıksal Adres Alanı (0x00000000 - 0xFFFFFFFF)
│
┌────┴──────────────────────────────────┐
│ FMMU (Slave 1) │
│ Mantıksal 0x1000 → Fiziksel 0x6000 │
└───────────────────────────────────────┘
│
┌────┴──────────────────────────────────┐
│ SyncManager 3 (PDO Rx) │
│ ESC DPRAM: 0x6000 - 0x6007 │
└───────────────────────────────────────┘
03 Distributed Clock — ağ genelinde senkronizasyon
EtherCAT Distributed Clock (DC), tüm slave'lerin aynı zaman referansını paylaşmasını sağlar. Sub-mikrosaniye hassasiyetiyle elde edilen bu senkronizasyon, çok eksenli hareket kontrolü gibi uygulamalarda kritik öneme sahiptir.
DC çalışma prensibi
DC özellikli ilk slave, ağın referans saati olarak atanır. Master, zincirdeki her slave'in ESC saatini ölçerek propagation delay'i hesaplar ve her slave'in saatini referansa göre offset kalibrasyonu ile hizalar.
DC konfigürasyon parametreleri
| ESC Kaydı | Adres | Açıklama |
|---|---|---|
| DC Receive Time Port 0 | 0x0900 | Giriş portundan frame alış zamanı |
| System Time | 0x0910 | 64-bit sistem zamanı (ns cinsinden) |
| System Time Offset | 0x0920 | Master tarafından yazılan offset değeri |
| SYNC0 Cycle Time | 0x09A0 | SYNC0 periyodu (ns). 0 = devre dışı |
| SYNC0 Start Time | 0x0990 | İlk SYNC0'ın mutlak başlangıç zamanı |
IgH Master, DC senkronizasyonunu otomatik olarak yönetir. Uygulama geliştiricisinin yapması gereken tek şey slave'lerde DC'yi etkinleştirmek ve döngü süresini DC SYNC0 periyoduyla eşleştirmektir.
04 PDO ve SDO — süreç verisi ve servis erişimi
EtherCAT'ta veri iletişimi iki ana kanaldan gerçekleşir: döngüsel süreç verisi için PDO (Process Data Object) ve parametre/konfigürasyon erişimi için SDO (Service Data Object). Bu ayrım, CoE (CANopen over EtherCAT) standardından miras alınmıştır.
PDO — Process Data Object
PDO'lar, her döngüde otomatik olarak aktarılan gerçek zamanlı verilerdir. Bir servo sürücünün konum geri bildirimi, hız referansı veya I/O modülünün dijital giriş durumu PDO üzerinden taşınır.
SDO — Service Data Object
SDO'lar, mailbox iletişim kanalı (SM0/SM1) üzerinden çalışır ve başlatma/konfigürasyon aşamalarında kullanılır. Her SDO transferi bir istek-yanıt çiftidir; gerçek zamanlı değildir.
| CoE Nesnesi | İndeks | Açıklama |
|---|---|---|
| Device Type | 0x1000 | Cihaz profil türü |
| Manufacturer Device Name | 0x1008 | Üretici cihaz adı (string) |
| Identity Object | 0x1018 | Vendor ID, Product Code, Revision, Serial |
| Controlword | 0x6040 | CIA-402 motor kontrol kelimesi |
| Statusword | 0x6041 | CIA-402 motor durum kelimesi |
| Target Position | 0x607A | Hedef konum (cyclic position mode) |
| Actual Position | 0x6064 | Gerçek encoder pozisyonu |
/* IgH API ile SDO okuma örneği */
uint32_t vendor_id;
size_t result_size;
/* PREOP veya OP modunda SDO okuma */
if (ecrt_master_sdo_upload(master,
slave_pos, /* slave zincir pozisyonu */
0x1018, /* index: Identity Object */
0x01, /* sub-index: Vendor ID */
(uint8_t *)&vendor_id,
sizeof(vendor_id),
&result_size,
&abort_code) == 0) {
printf("Vendor ID: 0x%08X\n", vendor_id);
}
05 ESC — EtherCAT Slave Controller donanımı
ESC (EtherCAT Slave Controller), her slave'in kalbindeki ASIC veya FPGA IP çekirdeğidir. Ethernet frame'ini "on-the-fly" işleyen, FMMU/SyncManager yönetimini ve DC saatini donanımda gerçekleştiren bu yonga, EtherCAT'ın determinizm garantisinin temelini oluşturur.
Yaygın ESC çözümleri
| Çözüm | Tür | Özellik |
|---|---|---|
| ET1100 (Beckhoff) | ASIC | 4 port, FMMU × 8, SM × 8, DC, 64 KB DPRAM |
| ET1200 (Beckhoff) | ASIC | 2 port, düşük maliyet, FMMU × 3, SM × 4 |
| LAN9252 (Microchip) | ASIC | SPI/SQI arayüzü, MCU entegrasyonu için |
| AMIC110 (TI) | SoC + PRU | ARM + PRU-ICSS ile yazılım tabanlı ESC |
| EtherCAT IP (xilinx) | FPGA IP | Zynq/Artix serisi için lisanslı IP çekirdeği |
| SOES (yazılım) | Soft ESC | PREEMPT_RT Linux üzerinde yazılım slave (test amaçlı) |
ESC iç yapısı
Ethernet PHY (100BASE-TX)
│
┌──────▼──────────────────────────┐
│ ESC (ET1100) │
│ ┌─────────────────────────┐ │
│ │ Frame İşleme (ASIC) │ │
│ │ On-the-fly R/W │ │
│ └──────────┬──────────────┘ │
│ ┌──────────▼──────────────┐ │
│ │ DPRAM (64 KB) │ │
│ │ SM0: Mailbox Out │ │
│ │ SM1: Mailbox In │ │
│ │ SM2: PDO Out (RxPDO) │ │
│ │ SM3: PDO In (TxPDO) │ │
│ └──────────┬──────────────┘ │
│ ┌──────────▼──────────────┐ │
│ │ Yerel işlemci arayüzü │ │
│ │ (SPI / parallel bus / │ │
│ │ HBI / PDI) │ │
│ └─────────────────────────┘ │
│ Distributed Clock (64-bit) │
└─────────────────────────────────┘
│
Uygulama MCU/SoC
LAN9252 + STM32 kombinasyonu, düşük maliyetli EtherCAT slave geliştirme için popüler bir seçimdir. LAN9252'nin SPI arayüzü, herhangi bir MCU'ya kolayca bağlanabilir.
06 IgH EtherCAT Master — Linux kurulumu
IgH EtherCAT Master (Ingenieurgemeinschaft IgH), Linux çekirdeği için açık kaynaklı bir EtherCAT master uygulamasıdır. Kernel modülü olarak çalışır ve raw Ethernet soket yerine kernel seviyesinde NIC sürücüsünü devralarak en düşük gecikmeyi sağlar.
Gereksinimler
Kaynak koddan derleme
# Bağımlılıklar
sudo apt install build-essential linux-headers-$(uname -r) \
autoconf libtool dkms
# Kaynak kodu al (gitlab.com/etherlab.org/ethercat)
git clone https://gitlab.com/etherlab.org/ethercat.git
cd ethercat
git checkout stable-1.5
# Yapılandırma (e1000e sürücüsü için)
./bootstrap
./configure --prefix=/usr/local \
--with-linux-dir=/lib/modules/$(uname -r)/build \
--enable-generic \
--enable-e1000e \
--disable-8139too
make -j$(nproc)
sudo make modules_install install
# Modül yükleme
sudo depmod -a
sudo modprobe ec_master
sudo modprobe ec_e1000e # veya ec_generic
Yapılandırma dosyası
# /etc/ethercat.conf
MASTER0_DEVICE="aa:bb:cc:dd:ee:ff" # NIC MAC adresi
DEVICE_MODULES="e1000e" # kullanılan sürücü
# systemd servisi
sudo systemctl enable ethercat
sudo systemctl start ethercat
# Durum kontrolü
ethercat master # master bilgisi
ethercat slaves # bağlı slave'lerin listesi
ethercat pdos # PDO eşleme bilgisi
ethercat sdo-upload 0 0x1000 0 # slave 0'dan device type oku
ethercat komut satırı araçları
| Komut | Açıklama |
|---|---|
ethercat master | Master durumu, istatistikler, döngü süresi |
ethercat slaves | Slave listesi: pozisyon, vendor, state |
ethercat pdos <pos> | Slave PDO eşleme detayları |
ethercat sdo-upload <pos> <idx> <sub> | SDO okuma |
ethercat sdo-download <pos> <idx> <sub> <val> | SDO yazma |
ethercat graph | Ağ topoloji grafiği (dot formatı) |
ethercat xml <pos> | Slave'den SII ESI verisini XML olarak al |
07 Slave state machine — INIT → OP geçişi
Her EtherCAT slave, dört ana durumdan oluşan bir state machine uygular. Master bu geçişleri yönetir; her geçişte konfigürasyon ve doğrulama adımları gerçekleştirilir.
┌──────────────────────────────────────────────┐
│ INIT │
│ • Temel ESC kaydı erişimi │
│ • Mailbox konfigürasyonu yapılmaz │
└──────────────┬───────────────────────────────┘
│ Master SyncManager'ları konfigüre eder
▼
┌──────────────────────────────────────────────┐
│ PRE-OP │
│ • Mailbox iletişimi aktif (SM0/SM1) │
│ • SDO ile konfigürasyon yapılır │
│ • PDO eşleme ayarlanır │
└──────────────┬───────────────────────────────┘
│ Master FMMU + PDO konfigürasyonu
▼
┌──────────────────────────────────────────────┐
│ SAFE-OP │
│ • Cyclic PDO verisi alınır (TxPDO) │
│ • Çıkış (RxPDO) henüz uygulanmaz │
│ • DC senkronizasyonu başlar │
└──────────────┬───────────────────────────────┘
│ Tüm slave'ler hazır, çıkışlar aktif
▼
┌──────────────────────────────────────────────┐
│ OP │
│ • Tam cyclic iletişim (RxPDO + TxPDO) │
│ • Motor kontrolü, I/O okuma/yazma aktif │
└──────────────────────────────────────────────┘
State geçiş hataları
/* IgH ile state kontrolü */
ec_slave_config_t *sc;
ec_slave_config_state_t sc_state;
ecrt_slave_config_state(sc, &sc_state);
if (sc_state.al_state != EC_AL_STATE_OP) {
fprintf(stderr, "Slave OP durumunda değil! AL state: %u\n",
sc_state.al_state);
if (sc_state.al_state == EC_AL_STATE_SAFEOP) {
/* Watchdog timeout — cyclic göreve devam et */
}
}
08 Pratik: IgH ile motor kontrolü — C API ve RT görev
Bu bölümde IgH EtherCAT Master C API'sini kullanarak bir servo sürücüyü (CIA-402 profili) kontrol eden, PREEMPT_RT ile gerçek zamanlı çalışan döngüsel bir görev yazılır.
Proje yapısı
| Dosya | Açıklama |
|---|---|
| main.c | RT görev, PDO erişimi, CIA-402 state machine |
| Makefile | IgH kütüphane bağlantısı |
| /etc/ethercat.conf | NIC MAC adresi konfigürasyonu |
/* motor_control.c — IgH EtherCAT + PREEMPT_RT */
#include <ecrt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <pthread.h>
#include <signal.h>
#define VENDOR_ID 0x00000002 /* Beckhoff */
#define PRODUCT_CODE 0x06120000 /* AX5206 servo */
#define SLAVE_POS 0 /* Zincir pozisyonu */
#define CYCLE_NS 1000000UL /* 1 ms döngü */
/* PDO ofsetleri (ecrt_domain_data + FMMU offset) */
static unsigned int off_ctrl_word;
static unsigned int off_target_pos;
static unsigned int off_status_word;
static unsigned int off_actual_pos;
/* PDO giriş/çıkış tanımları (CIA-402) */
static ec_pdo_entry_reg_t domain_regs[] = {
{SLAVE_POS, VENDOR_ID, PRODUCT_CODE, 0x6040, 0x00, &off_ctrl_word},
{SLAVE_POS, VENDOR_ID, PRODUCT_CODE, 0x607A, 0x00, &off_target_pos},
{SLAVE_POS, VENDOR_ID, PRODUCT_CODE, 0x6041, 0x00, &off_status_word},
{SLAVE_POS, VENDOR_ID, PRODUCT_CODE, 0x6064, 0x00, &off_actual_pos},
{}
};
static ec_master_t *master;
static ec_domain_t *domain;
static ec_slave_config_t *slave_cfg;
static uint8_t *domain_pd;
static volatile int run = 1;
static void sig_handler(int sig) { run = 0; }
static void *rt_task(void *arg)
{
struct timespec next;
clock_gettime(CLOCK_MONOTONIC, &next);
ecrt_master_activate(master);
domain_pd = ecrt_domain_data(domain);
while (run) {
/* Sonraki uyanma zamanı */
next.tv_nsec += CYCLE_NS;
if (next.tv_nsec >= 1000000000L) {
next.tv_nsec -= 1000000000L;
next.tv_sec++;
}
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, NULL);
/* EtherCAT döngüsü */
ecrt_master_receive(master);
ecrt_domain_process(domain);
/* Durum kelimesini oku */
uint16_t sw = EC_READ_U16(domain_pd + off_status_word);
int32_t ap = EC_READ_S32(domain_pd + off_actual_pos);
/* CIA-402: Operation Enabled durumuna geç */
uint16_t cw = 0x000F; /* Enable Operation */
int32_t tp = 100000; /* Hedef konum: 100000 artım */
EC_WRITE_U16(domain_pd + off_ctrl_word, cw);
EC_WRITE_S32(domain_pd + off_target_pos, tp);
ecrt_domain_queue(domain);
ecrt_master_send(master);
printf("\rSW: 0x%04X Pos: %d", sw, ap);
fflush(stdout);
}
return NULL;
}
int main(void)
{
signal(SIGINT, sig_handler);
master = ecrt_request_master(0);
if (!master) { perror("ecrt_request_master"); return 1; }
domain = ecrt_master_create_domain(master);
slave_cfg = ecrt_master_slave_config(master,
SLAVE_POS, VENDOR_ID, PRODUCT_CODE);
if (!slave_cfg) { fprintf(stderr, "Slave config hatası\n"); return 1; }
/* DC konfigürasyonu: 1 ms SYNC0 */
ecrt_slave_config_dc(slave_cfg,
0x0300, /* AssignActivate (DC + SYNC0) */
CYCLE_NS, /* SYNC0 periyodu */
4400000, /* shift time (ns) */
0, 0);
ecrt_domain_reg_pdo_entry_list(domain, domain_regs);
ecrt_master_config(master);
/* PREEMPT_RT: gerçek zamanlı thread */
struct sched_param sp = { .sched_priority = 80 };
pthread_attr_t attr;
pthread_t tid;
pthread_attr_init(&attr);
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
pthread_attr_setschedparam(&attr, &sp);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
pthread_create(&tid, &attr, rt_task, NULL);
pthread_join(tid, NULL);
ecrt_release_master(master);
return 0;
}
# Makefile
CC = gcc
CFLAGS = -O2 -Wall -I/usr/local/include/ethercat
LDFLAGS = -L/usr/local/lib -lethercat -lpthread -lrt
motor_control: motor_control.c
$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
Çalıştırma ve doğrulama
# Master servisi başlat
sudo systemctl start ethercat
# Slave'lerin listesi
ethercat slaves
# 0 0:0 PREOP + Beckhoff EL7211
# Programı derle ve çalıştır (root veya CAP_NET_RAW gerekir)
make
sudo ./motor_control
# Başka terminal: döngü istatistikleri
ethercat master | grep -E "Frames|Lost|cycle"
SCHED_FIFO ile çalışan RT görev, sistem kaynaklarını tamamen ele geçirebilir. Geliştirme ortamında ulimit veya cgroups ile sınırlandırma yapın. Üretim ortamında watchdog entegrasyonu zorunludur.