⏱️ hal::systick
System Tick Timer - Millisecond Timebase for RTOS and Delays
~240 lines
~10 function
ARM Cortex-M
📖 Overview
SysTick, ARM Cortex-M mimarilerinde bulunan 24-bit sistem timer'ıdır. Genellikle 1ms tick interrupt üretmek for kullanılır ve RTOS (Real-Time Operating System) scheduler'ların temelini oluşturur. Ayrıca ms-based delay functionları ve uptime sayaçları for de kullanılır.
🔑 Key Features
- 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
🚀 Quick Start
import hal::systick, hal::core
let g_tick_count: u64 = 0
// SysTick interrupt handler
@interrupt
function SysTick_Handler() do
g_tick_count += 1
end
function ana() do
// 72 MHz CPU, 1ms tick
systick.init(72000000 / 1000) // 1ms period
systick.enable_interrupt()
systick.enable()
// Now delay_ms() works
loop do
io.println("Uptime: " + g_tick_count.yazıya() + " ms")
systick.delay_ms(1000)
end
end
📦 Tipler ve Enum'lar
// Clock Source
enum ClockSource {
EXTERNAL, // External clock (HCLK/8)
PROCESSOR // Processor clock (HCLK)
}
struct SysTickConfig do
reload_value: int, // 24-bit (0 - 0xFFFFFF)
clock_source: ClockSource,
interrupt_enable: bool
end
💡 Example 1: Millisecond Delay İmplementasyonu
Blocking delay ve non-blocking timeout
import hal::systick
let g_ticks: sayacı64 = 0
@interrupt
function SysTick_Handler() do
g_ticks += 1
end
// Blocking delay
function delay_ms(ms: int) do
let start = g_ticks
loop (g_ticks - start) < ms.to_u64() for do
// Wait
end
end
// Non-blocking timeout
struct Timeout do
start: sayı64,
duration: sayı64
end
function timeout_start(ms: int) -> Timeout do
return Timeout do
start: g_ticks,
duration: ms.to_u64()
end
end
function timeout_expired(timeout: Timeout) -> bool do
return (g_ticks - timeout.start) >= timeout.duration
end
// Kullanım örneği
function main_loop() do
let timeout = timeout_start(5000) // 5 saniye
loop do
// Non-blocking işlemler
process_data()
if timeout_expired(timeout) do
io.println("5 saniye geçti!")
timeout = timeout_start(5000) // Reset
end
end
end
💡 Example 2: Simple RTOS Scheduler
Cooperative multitasking with SysTick
import hal::systick
struct Task do
function: Fonksiyon(),
period_ms: int,
son_calistirma: sayı64
end
let g_ticks: sayı64 = 0
let g_tasks: Dizi[Task] = []
@interrupt
function SysTick_Handler() do
g_ticks += 1
end
function task_register(func: Fonksiyon(), period_ms: int) do
g_tasks.push(Task do
function: func,
period_ms: period_ms,
son_calistirma: 0
end)
end
function scheduler_run() do
loop do
her task in g_tasks for do
let elapsed = g_ticks - task.son_calistirma
if elapsed >= task.period_ms.to_u64() do
// Task zamanı geldi
task.function()
task.son_calistirma = g_ticks
end
end
end
end
// Example tasklar
function led_blink_task() do
gpio.pin_toggle(LED_PIN)
end
function sensor_read_task() do
let temp = sensor.read_temperature()
io.println("Sıcaklık: " + temp.yazıya())
end
function ana() do
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()
end
💡 Example 3: Performance Profiling
Fonksiyon yürütme süresi ölçümü
import hal::systick
function micros() -> sayı64 do
// SysTick counts down from reload value
let reload = systick.get_reload()
let current = systick.get_value()
// Calculate microseconds
let ticks_elapsed = reload - current
let us_per_tick = 1000 / reload // Assuming 1ms period
return (g_ticks * 1000) + (ticks_elapsed * us_per_tick).to_u64()
end
function profile_start() -> sayı64 do
return micros()
end
function profile_end(start: sayı64) -> sayı64 do
return micros() - start
end
// Kullanım
function slow_function() do
for i in 0..1000 for do
math.sqrt(i.float())
end
end
function ana() do
systick.init(72000) // 1ms
systick.enable()
let start = profile_start()
slow_function()
let duration = profile_end(start)
io.println("Süre: " + duration.yazıya() + " μs")
end
📊 API Referansı
Initialization
function init(reload_value: int) // 24-bit max
function deinit()
function enable()
function disable()
Configuration
function enable_interrupt()
function disable_interrupt()
function set_clock_source(source: ClockSource)
function get_reload() -> int
function set_reload(value: int)
Status
function get_value() -> int // Current counter value
function get_calib() -> int // Calibration value
function has_reference() -> bool
Utility
function delay_ms(ms: int)
function delay_us(us: int)
function 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 for reload = 72000
- Interrupt handler'da uzun işlem yapma (context switch overhead)
- Atomic operations for interrupt disable gerekebilir
🔗 Related Modules
- hal::timer - Hardware timers for longer periods
- hal::nvic - Interrupt controller configuration
- hal::power - Tickless idle integration