Developer Wiki'ye dön
STM32

STM32'de IRQ Gecikme Ölçümü: GPIO Toggle + Osiloskop Yöntemi

STM32H7 ve STM32F4 serilerinde gerçek IRQ gecikme ölçümü için GPIO toggle + osiloskop yöntemi — yazılım timestamp neden yanıltır, donanımsal doğrulama nasıl yapılır.

Spikedge Mühendislik13 Nisan 20269 dk okuma

STM32'de IRQ Gecikme Ölçümü: GPIO + Osiloskop

Neden Yazılım Timestamp Yanlıştır?

Firmware geliştiricilerin IRQ gecikme ölçümünde yaptığı en yaygın hata DWT->CYCCNT veya TIM->CNT okumaktır. Bu yöntem ISR giriş noktasından itibaren zamanı ölçer — interrupt sinyalinin donanımda üretilmesi ile ISR çalışması arasındaki süreyi değil.

Standart STM32H7 NVIC latency (Cortex-M7 dokümantasyonu): 12 cycle Gerçek observed latency (pipeline, cache miss, interrupt masking): 48–180 cycle

Bu fark, yüksek frekanslı kontrol döngülerinde (10kHz+) ciddi jitter kaynağıdır.

Doğru Yöntem: GPIO Toggle

Prensip: Interrupt kaynağı aktif olduğunda bir GPIO set, ISR'ın ilk satırında reset. Osiloskop bu iki kenar arasındaki süreyi ölçer.

// Interrupt kaynağı konfigürasyonu (TIM2 örneği)
void TIM2_IRQHandler(void) {
    // ISR'ın ilk ifadesi — cache miss öncesi
    GPIOA->BSRR = GPIO_BSRR_BR15;  // PA15 → LOW
    
    // ... gerçek ISR işlemleri ...
    
    HAL_TIM_IRQHandler(&htim2);
}

// Timer callback'te GPIO set
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
    if (htim->Instance == TIM2) {
        GPIOA->BSRR = GPIO_BSRR_BS15;  // PA15 → HIGH (sonraki periyot için hazırla)
    }
}

Kritik: GPIOA->BSRR = GPIO_BSRR_BR15 doğrudan register yazımı kullanın. HAL_GPIO_WritePin() fonksiyonu ek döngüler ekler ve ölçümü bozar.

Osiloskop Konfigürasyonu

  • Kanal A: Interrupt kaynağı (timer output veya external trigger)
  • Kanal B: GPIO (PA15)
  • Trigger: Kanal A yükselen kenar
  • Zaman tabanı: 1µs/div (STM32H7 @ 480MHz için 50ns/div önerilir)
  • Ölçüm: Kanal A yükselen kenar → Kanal B düşen kenar arası

STM32H7 Örnek Sonuçlar

Durum Ölçülen IRQ Latency
Sıfır yük, I-cache açık 125ns (60 cycle @ 480MHz)
Aktif FPU işlemi (float context save) 312ns
DCache miss (ilk çağrı) 480ns
FreeRTOS task context'i içinden 720ns
RTOS + DCache miss ~1.1µs

NVIC Priority Masking Tuzağı

FreeRTOS kullanan projelerde configMAX_SYSCALL_INTERRUPT_PRIORITY yanlış ayarlanmışsa taskENTER_CRITICAL() bölümleri tüm interrupt'ları maskeleyebilir:

// stm32h7xx_hal_conf.h
// Bu değer NVIC_EncodePriority ile encode edilmiş değerdir
#define configMAX_SYSCALL_INTERRUPT_PRIORITY  (5 << 4)  /* Priority 5 */

// Priority 5 ve üzeri interrupt'lar critical section içinde maskelenir
// EtherCAT veya motor kontrol IRQ'ları bu eşiğin altında olmalı
NVIC_SetPriority(TIM2_IRQn, 4);  // Critical section'dan etkilenmez

cyclictest Eşdeğeri: latency_test Pattern

Linux cyclictest aracına benzer şekilde, STM32'de minimum/maksimum/ortalama jitter ölçebilirsiniz:

#define SAMPLE_COUNT 100000

uint32_t samples[SAMPLE_COUNT];
uint32_t min_lat = UINT32_MAX, max_lat = 0, idx = 0;

// DWT cycle counter aktif et
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;

void TIM2_IRQHandler(void) {
    uint32_t lat = DWT->CYCCNT;  // ISR giriş timestamp
    GPIOA->BSRR = GPIO_BSRR_BR15;
    
    // Beklenen periyot cycle sayısı çıkar (480MHz * 100µs = 48000)
    uint32_t jitter = lat > 48000 ? lat - 48000 : 48000 - lat;
    
    if (idx < SAMPLE_COUNT) samples[idx++] = jitter;
    if (jitter < min_lat) min_lat = jitter;
    if (jitter > max_lat) max_lat = jitter;
    
    DWT->CYCCNT = 0;  // Reset for next cycle
    HAL_TIM_IRQHandler(&htim2);
}

İlgili Kaynaklar

#STM32#IRQ#Latency#RTOS#Oscilloscope#NVIC#FreeRTOS#Cortex-M7

Sık Sorulan Sorular

STM32'de IRQ gecikme ölçümü için en doğru yöntem nedir?+
DWT->CYCCNT ile yazılım timestamp alma, ISR giriş noktasından itibaren ölçer — interrupt sinyali üretiminden değil. Doğru yöntem GPIO toggle + osiloskoptur: interrupt kaynağı tetiklendiğinde GPIO set, ISR'ın ilk satırında reset. Osiloskop bu iki kenar arasındaki süreyi ölçer.
FreeRTOS'ta priority inversion nedir ve nasıl önlenir?+
Priority inversion, yüksek öncelikli görevin, düşük öncelikli görevin tuttuğu mutex için beklemesi durumudur. FreeRTOS'ta önlem: configUSE_MUTEXES=1 ile mutex priority inheritance aktif edilir. Bu sayede düşük öncelikli görev geçici olarak yüksek önceliğe yükseltilir ve mutex'i hızla serbest bırakır.
STM32H7 ile FreeRTOS'ta DMA kullanmanın avantajı nedir?+
DMA ile sensör verisi örnekleme, CPU müdahalesi olmadan gerçekleşir. 4000 Hz örnekleme hızında her örnek için CPU interrupt'ı yerine, circular DMA buffer dolduğunda tek bir semaphore verilir. Bu yaklaşım CPU yükünü dramatik biçimde azaltır ve görev zamanlaması jitter'ını <50µs'ye düşürür.

Projenizde bu teknolojiyi kullanıyor musunuz?

Spikedge mühendisleriyle mimari denetim planlayın.

Mimari Denetim Talebi