Donanım ve Yazılım Ortamı
| Bileşen | Detay |
|---|---|
| Platform | NXP i.MX8M Plus (Cortex-A53 quad @ 1.8GHz) |
| RAM | 4GB LPDDR4-3200 |
| Linux Çekirdeği | 6.1.36-rt10 (PREEMPT_RT) |
| EtherCAT Stack | IgH EtherCAT Master 1.5.2 |
| Döngü Süresi | 1ms (1kHz) |
| Slave Sayısı | 6 servo sürücü (CoE) |
| Ölçüm Aracı | Osiloskop + GPIO toggle (PA15) |
| Test Süresi | 27.7 saat kesintisiz |
Sorun: Standart Linux Scheduler Determinizmi Kırar
Standart Linux'ta SCHED_FIFO kullanılsa dahi kernel spinlock ve softirq işlemleri gerçek zamanlı thread'lerin preempt edilmesine neden olur. 1ms'lik EtherCAT döngüsünde baseline ölçümler:
P50 jitter: 8µs
P99 jitter: 47µs
P99.9 jitter: 213µs
Missed cycles (1 saat): 12
Bu rakamlar 250W servo motorunda anlık moment dalgalanması olarak görünür; titreşim ve konumsal sapma kabul edilemez düzeye çıkar.
Adım 1: PREEMPT_RT Çekirdeğini Derle
Yocto Scarthgap local.conf:
PREFERRED_VERSION_linux-imx = "6.1.36"
LINUX_KERNEL_TYPE = "preempt-rt"
RT yaması kernel içindeki spinlock'ların büyük bölümünü rt_mutex'e dönüştürür. Derleme sonrası doğrulama:
uname -v
# Linux version 6.1.36-rt10 ... PREEMPT_RT
cat /sys/kernel/realtime
# 1
Adım 2: CPU İzolasyonu ve IRQ Affinity
EtherCAT master thread'ine core-3'ü tamamen tahsis et. Kernel boot parametrelerine ekle:
isolcpus=3 nohz_full=3 rcu_nocbs=3
NIC interrupt'larını da aynı core'a yönlendir:
# ETH0 IRQ numarasını bul
cat /proc/interrupts | grep eth0
# Core-3 için smp_affinity (bit mask 0x8)
echo 8 > /proc/irq/[IRQ_NUM]/smp_affinity
Adım 3: Cyclic Thread — SCHED_FIFO + CLOCK_MONOTONIC
#include <sched.h>
#include <time.h>
#define PERIOD_NS 1000000 /* 1ms */
static void set_rt_priority(void) {
struct sched_param p = { .sched_priority = 99 };
pthread_setschedparam(pthread_self(), SCHED_FIFO, &p);
}
void *cyclic_task(void *arg) {
set_rt_priority();
struct timespec next;
clock_gettime(CLOCK_MONOTONIC, &next);
while (running) {
/* TIMER_ABSTIME: kümülatif drift önlenir */
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, NULL);
ecrt_master_receive(master);
ecrt_domain_process(domain);
update_servo_commands();
ecrt_domain_queue(domain);
ecrt_master_sync_reference_clock(master);
ecrt_master_send(master);
next.tv_nsec += PERIOD_NS;
if (next.tv_nsec >= 1000000000L) {
next.tv_nsec -= 1000000000L;
next.tv_sec++;
}
}
return NULL;
}
Kritik:
clock_nanosleep(TIMER_ABSTIME)zorunludur.TIMER_RELTIMEher iterasyonda küçük sapmalar biriktirir ve 1 saatlik operasyonda P99 jitter ikiye katlanabilir.
Adım 4: EtherCAT Distributed Clock Senkronizasyonu
DC olmadan slave'lerin referans saatleri sistem saatinden kayar:
/* Slave konfigürasyonunda — tek seferlik */
ecrt_slave_config_dc(sc, 0x0300, PERIOD_NS, 0, 0, 0);
/* Her döngü içinde */
ecrt_master_sync_reference_clock(master);
ecrt_master_sync_slave_clocks(master);
Ölçüm Metodolojisi
Yazılım timestamp'i yanlıştır — kernel scheduling gecikmesini ölçüme dahil etmez.
Doğru yöntem:
- EtherCAT frame gönderimi sırasında GPIO PA15 high → low
- Osiloskop ile yükselen → düşen kenar arasını ölç
- 100.000 cycle, 27.7 saat kesintisiz kayıt
gpio_set(PA15, 1);
ecrt_master_send(master);
gpio_set(PA15, 0);
Sonuçlar
| Metrik | Standart Linux | + PREEMPT_RT | + Tam Optimizasyon |
|---|---|---|---|
| P50 jitter | 8µs | 3.2µs | 1.4µs |
| P99 jitter | 47µs | 12µs | 3.8µs |
| P99.9 jitter | 213µs | 28µs | 4.9µs |
| Missed cycles/saat | 12 | 0 | 0 |
| SYNC0 senkron hatası | ±12µs | ±3µs | ±0.6µs |
Tekrarlanabilirlik Notları
- Ortam: 25°C ± 2°C, 6 slave, 1kHz, 8B IN + 8B OUT PDO/slave
- CPU arka plan yükü: %20 ortalama (EtherCAT thread haricinde)
- Reproduksiyon için tam kernel
.configve IgH master parametrelerini paylaşabiliriz — İletişim sayfasından talep edin.
İlgili Kaynaklar
- EtherCAT ve Endüstriyel Protokoller Yeteneği
- Hard Real-Time & RTOS Yeteneği
- NXP i.MX Platform Sayfası
Sisteminizde EtherCAT jitter sorunu yaşıyorsanız Mimari Denetim Talebi sayfasından bize ulaşın.
