⏱️ hal::systick
System Tick Timer - Millisecond Timebase for RTOS and Delays
~240 satır
~10 fonksiyon
ARM Cortex-M
📖 Genel Bakış
SysTick, ARM Cortex-M mimarilerinde bulunan 24-bit sistem timer'ıdır. Genellikle 1ms tick interrupt üretmek için kullanılır ve RTOS (Real-Time Operating System) scheduler'ların temelini oluşturur. Ayrıca ms-based delay fonksiyonları ve uptime sayaçları için de kullanılır.
🔑 Temel Özellikler
- 24-bit down counter (0xFFFFFF)
- Konfigüre edilebilir tick rate (genellikle 1ms)
- Exception/interrupt generation
- CPU clock veya external clock kaynaklı
- Low overhead timing
- RTOS scheduler timebase
- Millisecond delay functions
- Uptime counter
🚀 Hızlı Başlangıç
içe_aktar hal::systick, hal::core
değişken g_tick_count: u64 = 0
// SysTick interrupt handler
@interrupt
fonksiyon SysTick_Handler() yap
g_tick_count += 1
son
fonksiyon ana() yap
// 72 MHz CPU, 1ms tick
systick.init(72000000 / 1000) // 1ms period
systick.enable_interrupt()
systick.enable()
// Now delay_ms() works
döngü yap
io.println("Uptime: " + g_tick_count.yazıya() + " ms")
systick.delay_ms(1000)
son
son
📦 Tipler ve Enum'lar
// Clock Source
enum ClockSource {
EXTERNAL, // External clock (HCLK/8)
PROCESSOR // Processor clock (HCLK)
}
yapı SysTickConfig yap
reload_value: sayı, // 24-bit (0 - 0xFFFFFF)
clock_source: ClockSource,
interrupt_enable: mantık
son
💡 Örnek 1: Millisecond Delay İmplementasyonu
Blocking delay ve non-blocking timeout
içe_aktar hal::systick
değişken g_ticks: sayacı64 = 0
@interrupt
fonksiyon SysTick_Handler() yap
g_ticks += 1
son
// Blocking delay
fonksiyon delay_ms(ms: sayı) yap
değişken start = g_ticks
döngü (g_ticks - start) < ms.to_u64() için yap
// Wait
son
son
// Non-blocking timeout
yapı Timeout yap
start: sayı64,
duration: sayı64
son
fonksiyon timeout_start(ms: sayı) -> Timeout yap
dön Timeout yap
start: g_ticks,
duration: ms.to_u64()
son
son
fonksiyon timeout_expired(timeout: Timeout) -> mantık yap
dön (g_ticks - timeout.start) >= timeout.duration
son
// Kullanım örneği
fonksiyon main_loop() yap
değişken timeout = timeout_start(5000) // 5 saniye
döngü yap
// Non-blocking işlemler
process_data()
eğer timeout_expired(timeout) ise yap
io.println("5 saniye geçti!")
timeout = timeout_start(5000) // Reset
son
son
son
💡 Örnek 2: Simple RTOS Scheduler
Cooperative multitasking with SysTick
içe_aktar hal::systick
yapı Task yap
fonksiyon: Fonksiyon(),
period_ms: sayı,
son_calistirma: sayı64
son
değişken g_ticks: sayı64 = 0
değişken g_tasks: Dizi[Task] = []
@interrupt
fonksiyon SysTick_Handler() yap
g_ticks += 1
son
fonksiyon task_register(func: Fonksiyon(), period_ms: sayı) yap
g_tasks.push(Task yap
fonksiyon: func,
period_ms: period_ms,
son_calistirma: 0
son)
son
fonksiyon scheduler_run() yap
döngü yap
her task içinde g_tasks için yap
değişken elapsed = g_ticks - task.son_calistirma
eğer elapsed >= task.period_ms.to_u64() ise yap
// Task zamanı geldi
task.fonksiyon()
task.son_calistirma = g_ticks
son
son
son
son
// Örnek tasklar
fonksiyon led_blink_task() yap
gpio.pin_toggle(LED_PIN)
son
fonksiyon sensor_read_task() yap
değişken temp = sensor.read_temperature()
io.println("Sıcaklık: " + temp.yazıya())
son
fonksiyon ana() yap
systick.init(72000000 / 1000) // 1ms
systick.enable_interrupt()
systick.enable()
// Register tasks
task_register(led_blink_task, 500) // 500ms period
task_register(sensor_read_task, 1000) // 1000ms period
// Run scheduler
scheduler_run()
son
💡 Örnek 3: Performance Profiling
Fonksiyon yürütme süresi ölçümü
içe_aktar hal::systick
fonksiyon micros() -> sayı64 yap
// SysTick counts down from reload value
değişken reload = systick.get_reload()
değişken current = systick.get_value()
// Calculate microseconds
değişken ticks_elapsed = reload - current
değişken us_per_tick = 1000 / reload // Assuming 1ms period
dön (g_ticks * 1000) + (ticks_elapsed * us_per_tick).to_u64()
son
fonksiyon profile_start() -> sayı64 yap
dön micros()
son
fonksiyon profile_end(start: sayı64) -> sayı64 yap
dön micros() - start
son
// Kullanım
fonksiyon slow_function() yap
için i içinde 0..1000 için yap
math.sqrt(i.kesir())
son
son
fonksiyon ana() yap
systick.init(72000) // 1ms
systick.enable()
değişken start = profile_start()
slow_function()
değişken duration = profile_end(start)
io.println("Süre: " + duration.yazıya() + " μs")
son
📊 API Referansı
Initialization
fonksiyon init(reload_value: sayı) // 24-bit max
fonksiyon deinit()
fonksiyon enable()
fonksiyon disable()
Configuration
fonksiyon enable_interrupt()
fonksiyon disable_interrupt()
fonksiyon set_clock_source(source: ClockSource)
fonksiyon get_reload() -> sayı
fonksiyon set_reload(value: sayı)
Status
fonksiyon get_value() -> sayı // Current counter value
fonksiyon get_calib() -> sayı // Calibration value
fonksiyon has_reference() -> mantık
Utility
fonksiyon delay_ms(ms: sayı)
fonksiyon delay_us(us: sayı)
fonksiyon get_ticks() -> sayı64
⚙️ Platform Desteği
| Platform | Clock Source | Max Reload | Precision |
|---|---|---|---|
| Cortex-M0 | HCLK, HCLK/8 | 0xFFFFFF (16.7M) | 1 cycle |
| Cortex-M3 | HCLK, HCLK/8 | 0xFFFFFF | 1 cycle |
| Cortex-M4 | HCLK, HCLK/8 | 0xFFFFFF | 1 cycle |
| Cortex-M7 | HCLK, HCLK/8 | 0xFFFFFF | 1 cycle |
💡 Best Practices
- Tick rate: 1ms industry standard for RTOS
- Interrupt priority: SysTick genellikle en düşük priority (15)
- Handler duration: Interrupt handler minimal tutulmalı (<10μs)
- Overflow handling: 64-bit counter kullanarak overflow'u önleyin
- Power optimization: Tickless idle mode düşünün (RTOS)
- Debug freeze: Debug sırasında SysTick'i durdurabilirsiniz
⚠️ Önemli Notlar
- 24-bit counter: Maximum reload value 0xFFFFFF (16,777,215)
- 72 MHz'de 1ms için reload = 72000
- Interrupt handler'da uzun işlem yapma (context switch overhead)
- Atomic operations için interrupt disable gerekebilir
🔗 İlgili Modüller
- hal::timer - Hardware timers for longer periods
- hal::nvic - Interrupt controller configuration
- hal::power - Tickless idle integration