💾 hal::flash
Flash Memory Programming - Program Storage and Data Persistence
~340 satır
~15 fonksiyon
STM32/GD32
📖 Genel Bakış
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 için kullanılır.
🔑 Temel Özellikler
- Program memory read/write/erase
- Page/sector based erase operations
- Mass erase support
- Write protection mechanisms
- Option bytes programming
- Dual-bank flash (F4/F7)
- ECC error detection
- Flash memory locking
🚀 Hızlı Başlangıç
içe_aktar hal::flash
// Unlock flash for writing
flash.unlock()
// Erase a page
flash.erase_page(0x0801F800) // Last page
// Write data
değişken data = [0x12345678, 0xABCDEF00, 0xDEADBEEF]
flash.write(0x0801F800, data)
// Lock flash
flash.lock()
// Read back
değişken 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
}
yapı FlashInfo yap
total_size: sayı, // Bytes
page_size: sayı, // Bytes
num_pages: sayı,
write_alignment: sayı // 1, 2, 4, 8 bytes
son
💡 Örnek 1: EEPROM Emulation
Flash'ta key-value storage sistemi
içe_aktar hal::flash
sabit EEPROM_START = 0x0801F000 // Son 4KB
sabit EEPROM_END = 0x08020000
sabit MAGIC_HEADER = 0xDEADBEEF
yapı EEPROMEntry yap
key: sayı,
value: sayı,
checksum: sayı
son
fonksiyon eeprom_write(key: sayı, value: sayı) yap
flash.unlock()
// Boş slot bul
değişken addr = EEPROM_START
döngü addr < EEPROM_END için yap
değişken magic = flash.read_word(addr)
eğer magic == 0xFFFFFFFF ise yap
// 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
son
addr += 16 // Entry size
son
flash.lock()
son
fonksiyon eeprom_read(key: sayı) -> Seçenek[sayı] yap
değişken addr = EEPROM_START
döngü addr < EEPROM_END için yap
değişken magic = flash.read_word(addr)
eğer magic == MAGIC_HEADER ise yap
değişken stored_key = flash.read_word(addr + 4)
eğer stored_key == key ise yap
değişken value = flash.read_word(addr + 8)
değişken checksum = flash.read_word(addr + 12)
// Verify checksum
eğer checksum == (key ^ value) ise yap
dön Bazı(value)
son
son
son
addr += 16
son
dön Hiçbiri
son
fonksiyon eeprom_format() yap
flash.unlock()
flash.erase_page(EEPROM_START)
flash.lock()
io.println("EEPROM formatted")
son
fonksiyon ana() yap
// Write configuration
eeprom_write(1, 12345) // key=1, value=12345
eeprom_write(2, 67890)
// Read back
eğer değişken val = eeprom_read(1) ise yap
io.println("Key 1: " + val.yazıya())
son
son
💡 Örnek 2: Firmware Update (Bootloader)
OTA firmware güncelleme
içe_aktar hal::flash, hal::crc
sabit APP_START = 0x08010000 // Application start
sabit APP_SIZE = 0x00030000 // 192 KB
sabit UPDATE_START = 0x08040000 // Update area
yapı FirmwareHeader yap
magic: sayı, // 0x42455247 (BERK)
version: sayı,
size: sayı,
crc32: sayı
son
fonksiyon firmware_validate(addr: sayı) -> mantık yap
// Read header
değişken header = flash.read_struct::(addr)
eğer header.magic != 0x42455247 ise yap
dön yanlış
son
// Calculate CRC
değişken calculated_crc = crc.calculate(
addr + sizeofreşitli,
header.size
)
dön calculated_crc == header.crc32
son
fonksiyon firmware_copy(src: sayı, dest: sayı, size: sayı) yap
flash.unlock()
// Erase destination
değişken pages = (size + 2047) / 2048
için i içinde 0..pages için yap
flash.erase_page(dest + i * 2048)
son
// Copy data
değişken offset = 0
döngü offset < size için yap
değişken data = flash.read_word(src + offset)
flash.write_word(dest + offset, data)
offset += 4
son
flash.lock()
son
fonksiyon bootloader_ana() yap
io.println("Bootloader başlatılıyor...")
// Check for update
eğer firmware_validate(UPDATE_START) ise yap
io.println("Yeni firmware bulundu, güncelleniyor...")
değişken header = flash.read_struct::(UPDATE_START)
// Copy new firmware to application area
firmware_copy(
UPDATE_START,
APP_START,
header.size
)
// Verify
eğer firmware_validate(APP_START) ise yap
io.println("Güncelleme başarılı!")
// Clear update area
flash.unlock()
flash.erase_sector(UPDATE_START)
flash.lock()
yoksa yap
io.println("Güncelleme başarısız!")
dön
son
son
// Jump to application
io.println("Uygulamaya atlanıyor...")
jump_to_application(APP_START)
son
fonksiyon jump_to_application(addr: sayı) yap
// Read stack pointer and reset vector
değişken sp = flash.read_word(addr)
değişken 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
değişken jump: fonksiyon() = transmute(reset_handler)
jump()
son
💡 Örnek 3: Option Bytes Programming
Read protection ve write protection ayarları
içe_aktar hal::flash
enum ReadProtection {
LEVEL_0, // No protection
LEVEL_1, // Memory read protection
LEVEL_2 // Permanent protection (irreversible!)
}
fonksiyon set_read_protection(level: ReadProtection) yap
flash.unlock()
flash.unlock_option_bytes()
eğer level == ReadProtection.LEVEL_1 ise yap
flash.set_option_byte(flash.OB_RDP, 0x00)
io.println("UYARI: Read protection Level 1 etkinleştirildi")
yoksa eğer level == ReadProtection.LEVEL_2 ise yap
io.println("UYARI: Level 2 GERİ ALINAMAZ! Devam edilsin mi? (y/n)")
// Level 2 is permanent - chip cannot be debugged anymore!
son
flash.lock_option_bytes()
flash.lock()
son
fonksiyon protect_bootloader() yap
// Protect first 16KB (bootloader area)
flash.unlock()
flash.unlock_option_bytes()
flash.set_write_protection(yap
sectors: [flash.SECTOR_0, flash.SECTOR_1],
enable: doğru
son)
flash.lock_option_bytes()
flash.lock()
io.println("Bootloader koruması etkinleştirildi")
son
📊 API Referansı
Lock/Unlock
fonksiyon unlock()
fonksiyon lock()
fonksiyon is_locked() -> mantık
Erase Operations
fonksiyon erase_page(address: sayı)
fonksiyon erase_sector(sector: sayı)
fonksiyon mass_erase()
fonksiyon mass_erase_bank(bank: Bank)
Write Operations
fonksiyon write_byte(address: sayı, data: u8)
fonksiyon write_halfword(address: sayı, data: u16)
fonksiyon write_word(address: sayı, data: u32)
fonksiyon write_doubleword(address: sayı, data: u64)
fonksiyon write(address: sayı, data: Dizi[u32])
Read Operations
fonksiyon read_byte(address: sayı) -> u8
fonksiyon read_halfword(address: sayı) -> u16
fonksiyon read_word(address: sayı) -> u32
fonksiyon read(address: sayı, length: sayı) -> Dizi[u8]
Option Bytes
fonksiyon unlock_option_bytes()
fonksiyon lock_option_bytes()
fonksiyon set_option_byte(option: sayı, value: sayı)
fonksiyon get_option_byte(option: sayı) -> sayı
⚙️ Platform Desteği
| Platform | Flash Size | Page Size | Write Align |
|---|---|---|---|
| STM32F1 | 64-512 KB | 1-2 KB | 2 bytes |
| STM32F4 | 512 KB-2 MB | 16-128 KB | 4 bytes |
| STM32F7 | 1-2 MB | 32-256 KB | 4 bytes |
| GD32VF103 | 64-128 KB | 1 KB | 4 bytes |
💡 Best Practices
- Write alignment: Data her zaman belirtilen alignment'a uygun olmalı
- Erase before write: Flash sadece 1 → 0 yazabilir, önce erase (0xFF) gerekli
- Wear leveling: Aynı sayfaya çok sık yazma yapılmamalı (100K cycle limit)
- Power loss: Yazma sırasında güç kaybında data corruption olabilir
- Interrupts: Flash programming sırasında interrupt'ları dikkatli kullanın
- Read-while-write: Bazı MCU'lar yazarken okuma yapamaz
⚠️ Önemli Notlar
- Flash programming CPU'yu bloklar (~20-50ms per page)
- Option bytes Level 2 read protection geri alınamaz!
- Flash endurance tipik 10K-100K erase cycle
- Data retention: 10+ yıl (25°C'de)
🔗 İlgili Modüller
- hal::crc - CRC verification for stored data
- hal::watchdog - Disable during flash erase