EtherCAT

Linux PREEMPT_RT ile EtherCAT Cycle Jitter: 47µs → 3.8µs

47µs → 3.8µs P99 — ARM Cortex-A53, PREEMPT_RT 6.1.36-rt10, IgH EtherCAT Master

Spikedge MühendislikMarch 10, 20267 dk okuma

Latency

3.8µs47µs
-92%

Validated on

NXP i.MX8
Linux PREEMPT_RT ile EtherCAT Cycle Jitter: 47µs → 3.8µs
oscilloscope-verified

Latency

3.8µs

-92%

What Was Solved

PREEMPT_RT çekirdeği, CPU izolasyonu ve Distributed Clock senkronizasyonuyla ARM tabanlı endüstriyel kontrolörde EtherCAT cycle jitter'ı 47µs'den 3.8µs P99'a nasıl düşürdüğümüzü osiloskop verileri ve tekrarlanabilir metodoloji ile anlatıyoruz.

This article was prepared based on field experiences and technical evaluations of the Spikedge engineering team.

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_RELTIME her 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:

  1. EtherCAT frame gönderimi sırasında GPIO PA15 high → low
  2. Osiloskop ile yükselen → düşen kenar arasını ölç
  3. 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 .config ve IgH master parametrelerini paylaşabiliriz — İletişim sayfasından talep edin.

İlgili Kaynaklar

Sisteminizde EtherCAT jitter sorunu yaşıyorsanız Mimari Denetim Talebi sayfasından bize ulaşın.

Continue Exploring

EtherCATPREEMPT_RTJitterIgH MasterNXP i.MX8DeterminizmEndüstriyel Otomasyon

Frequently Asked Questions

What is PREEMPT_RT and why is it needed for EtherCAT?+
PREEMPT_RT is a patch set that adds full preemptibility to the Linux kernel. Standard Linux disables interrupts in critical sections, causing EtherCAT cycle jitter. With PREEMPT_RT, all kernel lock points become preemptible mutexes, reducing IRQ latency from 38µs to under 4µs.
Why is EtherCAT DC sync (Distributed Clock) critical?+
DC sync ensures all slave devices operate on the same time reference. Without synchronization, different slaves actuate at different times, causing mechanical stress and precision loss. With proper DC sync, ±100ns synchronization is achieved.
What is IgH EtherCAT Master?+
IgH EtherCAT Master (etherlabmaster) is an open-source EtherCAT master stack for Linux. It runs as a kernel module and when combined with PREEMPT_RT, sub-100µs jitter can be achieved. It is widely used in industrial applications.

Spikedge Engineering

Using this technology in your own system?

Schedule a 1:1 technical analysis with Spikedge engineers.

Schedule Architecture Audit