Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

⚡ hal::int

Nested Vectored Interrupt Controller (NVIC)

366 satır ~8 fonksiyon NVIC

📖 Genel Bakış

Interrupt controller, asenkron olayları işler. GPIO, Timer, USART gibi çevre birimlerinin interrupt'larını yönetir.

🔑 Temel Özellikler

  • Priority levels (0-15)
  • Preemption & sub-priority
  • Enable/Disable interrupts
  • Pending flag management
  • Nested interrupt support

🚀 Hızlı Başlangıç

içe_aktar hal::int

// Enable interrupt
int.enable(int.IRQ_TIM2)

// Set priority
int.set_priority(int.IRQ_TIM2, yap
    preempt: 2,  // Preemption priority
    sub: 0       // Sub priority
son)

// Disable interrupt
int.disable(int.IRQ_TIM2)

// Global interrupt enable/disable
int.global_enable()
int.global_disable()

⚙️ Priority Groups

// Configure priority grouping
int.set_priority_grouping(int.PRIORITY_GROUP_4)

// Groups:
// GROUP_0: 0 bits preemption, 4 bits sub (16 sub-priorities)
// GROUP_4: 4 bits preemption, 0 bits sub (16 preemption levels)

💡 Örnek: Nested Interrupts (Priority Preemption)

içe_aktar hal::int, hal::timer, hal::gpio

değişken high_priority_count = 0
değişken low_priority_count = 0

fonksiyon high_priority_isr() yap
    // High priority interrupt (timer)
    high_priority_count += 1
    io.println("HIGH priority ISR (count: {})", high_priority_count)
    
    // Simulate work
    core.delay_ms(50)
son

fonksiyon low_priority_isr() yap
    // Low priority interrupt (button)
    low_priority_count += 1
    io.println("  LOW priority ISR (count: {})", low_priority_count)
    
    // Simulate work
    core.delay_ms(100)
son

fonksiyon nested_interrupt_demo() yap
    // Set priority grouping (4 bits preemption, 0 bits sub)
    int.set_priority_grouping(int.PRIORITY_GROUP_4)
    
    // Configure Timer2 interrupt (high priority)
    timer.init(timer.TIM2, yap
        frequency: 10,  // 10Hz
        callback: high_priority_isr
    son)
    
    int.set_priority(int.IRQ_TIM2, yap
        preempt: 0,  // Highest priority
        sub: 0
    son)
    int.enable(int.IRQ_TIM2)
    
    // Configure GPIO interrupt (low priority)
    gpio.pin_init(gpio.PORT_A, 0, yap
        mode: gpio.MODE_INPUT,
        interrupt: gpio.INT_RISING,
        callback: low_priority_isr
    son)
    
    int.set_priority(int.IRQ_EXTI0, yap
        preempt: 5,  // Lower priority
        sub: 0
    son)
    int.enable(int.IRQ_EXTI0)
    
    io.println("Nested interrupt demo")
    io.println("Timer interrupt can preempt button interrupt")
    
    timer.start(timer.TIM2)
    
    döngü yap
        core.delay_ms(1000)
    son
son

fonksiyon ana() yap
    nested_interrupt_demo()
son

💡 Örnek: External Interrupts (EXTI)

içe_aktar hal::int, hal::gpio

değişken button1_pressed = 0
değişken button2_pressed = 0

fonksiyon button1_callback() yap
    button1_pressed += 1
    io.println("Button 1 pressed (total: {})", button1_pressed)
son

fonksiyon button2_callback() yap
    button2_pressed += 1
    io.println("Button 2 pressed (total: {})", button2_pressed)
son

fonksiyon multi_button_exti() yap
    // Button 1 on PA0 (EXTI0)
    gpio.clock_enable(gpio.PORT_A)
    gpio.pin_init(gpio.PORT_A, 0, yap
        mode: gpio.MODE_INPUT,
        pull: gpio.PULL_DOWN,
        interrupt: gpio.INT_RISING
    son)
    
    gpio.set_callback(gpio.PORT_A, 0, button1_callback)
    
    int.set_priority(int.IRQ_EXTI0, yap preempt: 5, sub: 0 son)
    int.enable(int.IRQ_EXTI0)
    
    // Button 2 on PB1 (EXTI1)
    gpio.clock_enable(gpio.PORT_B)
    gpio.pin_init(gpio.PORT_B, 1, yap
        mode: gpio.MODE_INPUT,
        pull: gpio.PULL_DOWN,
        interrupt: gpio.INT_RISING
    son)
    
    gpio.set_callback(gpio.PORT_B, 1, button2_callback)
    
    int.set_priority(int.IRQ_EXTI1, yap preempt: 5, sub: 0 son)
    int.enable(int.IRQ_EXTI1)
    
    io.println("EXTI demo: Press buttons")
    
    döngü yap
        core.delay_ms(100)
    son
son

fonksiyon ana() yap
    multi_button_exti()
son

💡 Örnek: Interrupt Latency Measurement

içe_aktar hal::int, hal::timer, hal::gpio

değişken interrupt_timestamp = 0
değişken latency_us = 0

fonksiyon fast_isr() yap
    // Measure interrupt latency
    değişken now = core.uptime_us()
    latency_us = now - interrupt_timestamp
    
    // Toggle LED as visual indicator
    gpio.pin_toggle(gpio.PORT_C, 13)
son

fonksiyon latency_test() yap
    // Configure GPIO interrupt on PA0
    gpio.pin_init(gpio.PORT_A, 0, yap
        mode: gpio.MODE_INPUT,
        interrupt: gpio.INT_RISING,
        callback: fast_isr
    son)
    
    // Set highest priority
    int.set_priority_grouping(int.PRIORITY_GROUP_4)
    int.set_priority(int.IRQ_EXTI0, yap preempt: 0, sub: 0 son)
    int.enable(int.IRQ_EXTI0)
    
    // LED output
    gpio.pin_init(gpio.PORT_C, 13, yap mode: gpio.MODE_OUTPUT son)
    
    io.println("Interrupt latency test")
    io.println("Trigger PA0 rising edge")
    
    döngü yap
        // Wait for interrupt
        eğer latency_us > 0 ise yap
            io.println("Interrupt latency: {}μs", latency_us)
            latency_us = 0
        son
        
        core.delay_ms(100)
    son
son

fonksiyon ana() yap
    latency_test()
son

💡 Örnek: Software Interrupt Trigger

içe_aktar hal::int

değişken software_int_count = 0

fonksiyon software_isr() yap
    software_int_count += 1
    io.println("Software interrupt triggered! ({})", software_int_count)
son

fonksiyon software_interrupt_demo() yap
    // Configure software interrupt
    int.set_callback(int.IRQ_PendSV, software_isr)
    int.set_priority(int.IRQ_PendSV, yap preempt: 15, sub: 0 son)
    int.enable(int.IRQ_PendSV)
    
    io.println("Software interrupt demo")
    
    döngü yap
        io.println("Triggering software interrupt...")
        
        // Trigger PendSV interrupt manually
        int.set_pending(int.IRQ_PendSV)
        
        core.delay_ms(2000)
    son
son

fonksiyon ana() yap
    software_interrupt_demo()
son

💡 Örnek: Critical Section (Interrupt Disable)

içe_aktar hal::int

değişken shared_counter = 0

fonksiyon critical_section_demo() yap
    // Unsafe increment (race condition possible)
    fonksiyon unsafe_increment() yap
        değişken temp = shared_counter
        core.delay_us(10)  // Simulate work
        shared_counter = temp + 1
    son
    
    // Safe increment (atomic with interrupts disabled)
    fonksiyon safe_increment() yap
        // Enter critical section
        int.global_disable()
        
        değişken temp = shared_counter
        core.delay_us(10)
        shared_counter = temp + 1
        
        // Exit critical section
        int.global_enable()
    son
    
    // Better: use RAII-style guard
    fonksiyon best_increment() yap
        değişken guard = int.critical_section()  // Auto disable
        
        değişken temp = shared_counter
        core.delay_us(10)
        shared_counter = temp + 1
        
        // Auto enable on scope exit
    son
    
    // Test
    her i içinde 0..1000 için yap
        safe_increment()
    son
    
    io.println("Counter: {}", shared_counter)  // Should be 1000
son

fonksiyon ana() yap
    critical_section_demo()
son

⚙️ NVIC Yapılandırma

// Priority Configuration
yapı PriorityConfig yap
    preempt: sayı,  // Preemption priority (0-15)
    sub: sayı       // Sub-priority (0-15)
son

// Priority Grouping
enum PriorityGroup {
    PRIORITY_GROUP_0,  // 0:4 (0 preemption, 16 sub)
    PRIORITY_GROUP_1,  // 1:3 (2 preemption, 8 sub)
    PRIORITY_GROUP_2,  // 2:2 (4 preemption, 4 sub)
    PRIORITY_GROUP_3,  // 3:1 (8 preemption, 2 sub)
    PRIORITY_GROUP_4   // 4:0 (16 preemption, 0 sub)
}

// Common IRQ Numbers (STM32F4)
enum IRQ {
    IRQ_WWDG          = 0,   // Window watchdog
    IRQ_EXTI0         = 6,   // External line 0
    IRQ_EXTI1         = 7,   // External line 1
    IRQ_DMA1_STREAM0  = 11,  // DMA1 stream 0
    IRQ_TIM2          = 28,  // Timer 2
    IRQ_USART1        = 37,  // USART1
    IRQ_EXTI15_10     = 40,  // External lines 10-15
    IRQ_SPI1          = 35,  // SPI1
    IRQ_PendSV        = -2,  // Pendable request
    IRQ_SysTick       = -1   // System tick
}

📚 NVIC Fonksiyonları

// Interrupt control
fonksiyon enable(irq: IRQ)
fonksiyon disable(irq: IRQ)
fonksiyon is_enabled(irq: IRQ) -> bool

// Priority management
fonksiyon set_priority(irq: IRQ, config: PriorityConfig)
fonksiyon get_priority(irq: IRQ) -> PriorityConfig
fonksiyon set_priority_grouping(group: PriorityGroup)

// Pending flags
fonksiyon set_pending(irq: IRQ)  // Software trigger
fonksiyon clear_pending(irq: IRQ)
fonksiyon is_pending(irq: IRQ) -> bool

// Global control
fonksiyon global_enable()  // Enable all interrupts
fonksiyon global_disable()  // Disable all interrupts
fonksiyon critical_section() -> Guard  // RAII-style

// Callback registration
fonksiyon set_callback(irq: IRQ, callback: fn())

📊 Priority Level Önerileri

Priority Use Case Örnek
0-2 (Highest) Time-critical, real-time Motor encoder, high-speed ADC
3-7 (High) Fast peripherals USART, SPI, I2C, timers
8-11 (Medium) Normal peripherals GPIO, ADC, RTC alarms
12-15 (Low) Background tasks Software interrupts, low-priority IO

⚡ İyi Pratikler

  • ISR Short: Interrupt handler'ları kısa tutun (<10μs ideal)
  • Defer Work: Ağır işlemi main loop'a erteyin (flag set)
  • Volatile: ISR'den okunan değişkenler volatile olmalı
  • Priority Planning: Time-critical işler yüksek priority
  • Nesting: GROUP_4 kullanın (16 preemption level)
  • Critical Sections: Shared data erişiminde disable interrupts

⚠️ Önemli Notlar

  • Priority Number: Lower number = Higher priority (0 en yüksek)
  • Preemption: Farklı preemption priority → nesting mümkün
  • Sub-priority: Aynı preemption'da hangisinin önce işleneceğini belirler
  • ISR Latency: Tipik 10-20 cycle (~12 cycle push/pop registers)
  • Tail-Chaining: Back-to-back interrupt'larda push/pop skip (6 cycle saved)
  • BASEPRI: Belirli priority altındaki interrupt'ları maske etme
  • Fault Handlers: HardFault, MemManage, BusFault (priority -1, -2, -3)
  • Systick: Tipik priority 15 (en düşük, timing-critical değil)

🔗 İlgili Modüller

  • hal::gpio - EXTI external interrupts
  • hal::timer - Timer interrupts (overflow, capture)
  • hal::usart - USART TX/RX interrupts
  • hal::dma - DMA transfer complete interrupts
  • hal::rtc - RTC alarm interrupts
  • hal::core - Sleep mode wakeup

📖 Referanslar

← HAL Modülleri