💾 hal::flash

Flash Memory Programming - Program Storage and Data Persistence

~340 lines ~15 function STM32/GD32

📖 Overview

Flash memory modülü, mikrokontrolcünün dahili flash belleğine program kodu yazma, okuma ve silme işlemlerini sağlar. Kalıcı veri saklama, firmware güncelleme (OTA), konfigürasyon ayarları ve EEPROM emülasyonu for kullanılır.

🔑 Key Features

🚀 Quick Start

import hal::flash

// Unlock flash for writing
flash.unlock()

// Erase a page
flash.erase_page(0x0801F800)  // Last page

// Write data
let data = [0x12345678, 0xABCDEF00, 0xDEADBEEF]
flash.write(0x0801F800, data)

// Lock flash
flash.lock()

// Read back
let value = flash.read_word(0x0801F800)
io.println("Okunan değer: 0x" + value.to_hex())

📦 Tipler ve Enum'lar

// Flash Latency
enum Latency {
    WS0,  // 0 wait state
    WS1,  // 1 wait state
    WS2,  // 2 wait states
    WS3,  // 3 wait states
    WS4,  // 4 wait states
    WS5   // 5 wait states
}

// Flash Bank
enum Bank {
    BANK_1,
    BANK_2
}

// Sector Size (STM32F4)
enum SectorSize {
    SECTOR_16K,
    SECTOR_64K,
    SECTOR_128K
}

struct FlashInfo do
    total_size: int,      // Bytes
    page_size: int,       // Bytes
    num_pages: int,
    write_alignment: int  // 1, 2, 4, 8 bytes
end

💡 Example 1: EEPROM Emulation

Flash'ta key-value storage sistemi

import hal::flash

const EEPROM_START = 0x0801F000  // Son 4KB
const EEPROM_END = 0x08020000
const MAGIC_HEADER = 0xDEADBEEF

struct EEPROMEntry do
    key: int,
    value: int,
    checksum: int
end

function eeprom_write(key: int, value: int) do
    flash.unlock()
    
    // Boş slot bul
    let addr = EEPROM_START
    loop addr < EEPROM_END for do
        let magic = flash.read_word(addr)
        if magic == 0xFFFFFFFF  do
            // Boş slot bulundu
            flash.write_word(addr, MAGIC_HEADER)
            flash.write_word(addr + 4, key)
            flash.write_word(addr + 8, value)
            flash.write_word(addr + 12, key ^ value)  // Checksum
            
            çık
        end
        addr += 16  // Entry size
    end
    
    flash.lock()
end

function eeprom_read(key: int) -> Seçenek[int] do
    let addr = EEPROM_START
    loop addr < EEPROM_END for do
        let magic = flash.read_word(addr)
        if magic == MAGIC_HEADER  do
            let stored_key = flash.read_word(addr + 4)
            if stored_key == key  do
                let value = flash.read_word(addr + 8)
                let checksum = flash.read_word(addr + 12)
                
                // Verify checksum
                if checksum == (key ^ value)  do
                    return Bazı(value)
                end
            end
        end
        addr += 16
    end
    
    return Hiçbiri
end

function eeprom_format() do
    flash.unlock()
    flash.erase_page(EEPROM_START)
    flash.lock()
    
    io.println("EEPROM formatted")
end

function ana() do
    // Write configuration
    eeprom_write(1, 12345)  // key=1, value=12345
    eeprom_write(2, 67890)
    
    // Read back
    if let val = eeprom_read(1)  do
        io.println("Key 1: " + val.yazıya())
    end
end

💡 Example 2: Firmware Update (Bootloader)

OTA firmware güncelleme

import hal::flash, hal::crc

const APP_START = 0x08010000  // Application start
const APP_SIZE = 0x00030000   // 192 KB
const UPDATE_START = 0x08040000  // Update area

struct FirmwareHeader do
    magic: int,        // 0x42455247 (BERK)
    version: int,
    size: int,
    crc32: int
end

function firmware_validate(addr: int) -> bool do
    // Read header
    let header = flash.read_struct::(addr)
    
    if header.magic != 0x42455247  do
        return yanlış
    end
    
    // Calculate CRC
    let calculated_crc = crc.calculate(
        addr + sizeofreşitli, 
        header.size
    )
    
    return calculated_crc == header.crc32
end

function firmware_copy(src: int, dest: int, size: int) do
    flash.unlock()
    
    // Erase destination
    let pages = (size + 2047) / 2048
    for i in 0..pages for do
        flash.erase_page(dest + i * 2048)
    end
    
    // Copy data
    let offset = 0
    loop offset < size for do
        let data = flash.read_word(src + offset)
        flash.write_word(dest + offset, data)
        offset += 4
    end
    
    flash.lock()
end

function bootloader_ana() do
    io.println("Bootloader başlatılıyor...")
    
    // Check for update
    if firmware_validate(UPDATE_START)  do
        io.println("Yeni firmware bulundu, güncelleniyor...")
        
        let header = flash.read_struct::(UPDATE_START)
        
        // Copy new firmware to application area
        firmware_copy(
            UPDATE_START,
            APP_START,
            header.size
        )
        
        // Verify
        if firmware_validate(APP_START)  do
            io.println("Güncelleme başarılı!")
            
            // Clear update area
            flash.unlock()
            flash.erase_sector(UPDATE_START)
            flash.lock()
        else do
            io.println("Güncelleme başarısız!")
            return
        end
    end
    
    // Jump to application
    io.println("Uygulamaya atlanıyor...")
    jump_to_application(APP_START)
end

function jump_to_application(addr: int) do
    // Read stack pointer and reset vector
    let sp = flash.read_word(addr)
    let reset_handler = flash.read_word(addr + 4)
    
    // Disable interrupts
    asm!("cpsid i")
    
    // Set stack pointer
    asm!("msr msp, {}", in(reg) sp)
    
    // Jump to reset handler
    let jump: function() = transmute(reset_handler)
    jump()
end

💡 Example 3: Option Bytes Programming

Read protection ve write protection ayarları

import hal::flash

enum ReadProtection {
    LEVEL_0,  // No protection
    LEVEL_1,  // Memory read protection
    LEVEL_2   // Permanent protection (irreversible!)
}

function set_read_protection(level: ReadProtection) do
    flash.unlock()
    flash.unlock_option_bytes()
    
    if level == ReadProtection.LEVEL_1  do
        flash.set_option_byte(flash.OB_RDP, 0x00)
        io.println("UYARI: Read protection Level 1 etkinleştirildi")
    else if level == ReadProtection.LEVEL_2  do
        io.println("UYARI: Level 2 GERİ ALINAMAZ! Devam edilsin mi? (y/n)")
        // Level 2 is permanent - chip cannot be debugged anymore!
    end
    
    flash.lock_option_bytes()
    flash.lock()
end

function protect_bootloader() do
    // Protect first 16KB (bootloader area)
    flash.unlock()
    flash.unlock_option_bytes()
    
    flash.set_write_protection(do
        sectors: [flash.SECTOR_0, flash.SECTOR_1],
        enable: doğru
    end)
    
    flash.lock_option_bytes()
    flash.lock()
    
    io.println("Bootloader koruması etkinleştirildi")
end

📊 API Referansı

Lock/Unlock

function unlock()
function lock()
function is_locked() -> bool

Erase Operations

function erase_page(address: int)
function erase_sector(sector: int)
function mass_erase()
function mass_erase_bank(bank: Bank)

Write Operations

function write_byte(address: int, data: u8)
function write_halfword(address: int, data: u16)
function write_word(address: int, data: u32)
function write_doubleword(address: int, data: u64)
function write(address: int, data: Dizi[u32])

Read Operations

function read_byte(address: int) -> u8
function read_halfword(address: int) -> u16
function read_word(address: int) -> u32
function read(address: int, length: int) -> Dizi[u8]

Option Bytes

function unlock_option_bytes()
function lock_option_bytes()
function set_option_byte(option: int, value: int)
function get_option_byte(option: int) -> int

⚙️ Platform Desteği

PlatformFlash SizePage SizeWrite Align
STM32F164-512 KB1-2 KB2 bytes
STM32F4512 KB-2 MB16-128 KB4 bytes
STM32F71-2 MB32-256 KB4 bytes
GD32VF10364-128 KB1 KB4 bytes

💡 Best Practices

⚠️ Önemli Notlar

🔗 Related Modules

← HAL Modules | 🇬🇧 Turkish