🔐 hal::crc
Hardware CRC32 Calculator - Fast Data Integrity Check
~360 satır
~12 function
STM32/GD32
📖 Overview
CRC modülü, hardware accelerated CRC32 hesaplaması sağlar. Polynomial 0x04C11DB7 kullanır (Ethernet standardı). Firmware integrity check, flash verification, communication protocols ve data corruption detection for kritiktir. Software CRC'den 10-100x daha hızlıdır.
🔑 Key Features
- Hardware CRC32: Single-cycle 32-bit CRC calculation
- Standard Polynomial: 0x04C11DB7 (Ethernet, ZIP, PNG)
- Fast Performance: 1 clock cycle per 32-bit word
- Initial Value: Configurable (default 0xFFFFFFFF)
- DMA Compatible: Can be used with DMA transfers
- Accumulation: Sequential CRC calculation support
- Reset Capability: Quick reset to initial value
- Low Power: Minimal power consumption
🚀 Quick Start
import hal::crc, hal::rcc
// Enable CRC clock
rcc.periph_clock_enable(rcc.PERIPH_CRC)
// Initialize CRC
crc.init()
// Calculate CRC32 of data
let data: Array<int> = [0x12345678, 0xABCDEF00, 0xDEADBEEF]
let checksum = crc.calculate(data)
io.yazdir_satır("CRC32: 0x" + checksum.onaltılıya())
// Verify data
if crc.verify(data, checksum) do
io.yazdir_satır("Data integrity OK")
end
📦 Types and Enums'lar
// CRC Configuration
struct CRCConfig do
polynomial: int = 0x04C11DB7, // Default Ethernet polynomial
initial_value: int = 0xFFFFFFFF,
input_reverse: bool = false,
output_reverse: bool = false
end
// CRC Result
struct CRCResult do
value: int,
valid: bool
end
💡 Example 1: Firmware Integrity Check
Problem: Flash'taki firmware'in bozulmadığını truelamak
import hal::crc, hal::flash
const FIRMWARE_START: int = 0x0800_8000 // Application start
const FIRMWARE_SIZE: int = 128 * 1024 // 128 KB
const CRC_STORAGE: int = 0x0807_FFFC // Last 4 bytes of app region
function firmware_calculate_crc() -> int do
crc.reset()
// Calculate CRC of firmware (32-bit words)
let word_count = FIRMWARE_SIZE / 4
let addr = FIRMWARE_START
for i forde 0..word_count do
let word = *(addr cast *int)
crc.accumulate(word)
addr = addr + 4
end
return crc.get_value()
end
function firmware_store_crc(checksum: int) do
// Unlock flash
flash.unlock()
// Erase last page
flash.erase_page(CRC_STORAGE)
// Write CRC
flash.program_word(CRC_STORAGE, checksum)
flash.lock()
io.yazdir_satır("CRC stored: 0x" + checksum.onaltılıya())
end
function firmware_verify() -> bool do
// Read stored CRC
let stored_crc = *(CRC_STORAGE cast *int)
// Calculate current CRC
let calculated_crc = firmware_calculate_crc()
io.yazdir_satır("Stored CRC: 0x" + stored_crc.onaltılıya())
io.yazdir_satır("Calculated CRC: 0x" + calculated_crc.onaltılıya())
if stored_crc == calculated_crc do
io.yazdir_satır("✅ Firmware integrity OK")
return true
else do
io.yazdir_satır("❌ Firmware corrupted!")
return false
end
end
function ana() do
crc.init()
// On firmware update: store CRC
// firmware_store_crc(firmware_calculate_crc())
// On boot: verify firmware
if değil firmware_verify() do
io.yazdir_satır("ERROR: Cannot start corrupted firmware")
// Enter safe mode or bootloader
loop do end // Halt
end
io.yazdir_satır("Starting application...")
end
Result: Boot sırasında firmware corruption detect edilir. Güvenli başlatma sağlanır.
💡 Example 2: UART Packet Verification
Problem: Serial communication'da packet integrity kontrolü
import hal::crc, hal::usart
struct Packet do
header: int8 = 0xAA,
length: int8,
data: Array<int8>,
crc32: int
end
function packet_calculate_crc(pkt: Packet) -> int do
crc.reset()
// CRC over header + length + data
crc.accumulate_byte(pkt.header)
crc.accumulate_byte(pkt.length)
for byte forde pkt.data do
crc.accumulate_byte(byte)
end
return crc.get_value()
end
function packet_send(pkt: Packet) do
// Calculate CRC
pkt.crc32 = packet_calculate_crc(pkt)
// Send packet
usart.write_byte(usart.USART1, pkt.header)
usart.write_byte(usart.USART1, pkt.length)
for byte forde pkt.data do
usart.write_byte(usart.USART1, byte)
end
// Send CRC (big-endian)
usart.write_byte(usart.USART1, (pkt.crc32 >> 24) & 0xFF cast int8)
usart.write_byte(usart.USART1, (pkt.crc32 >> 16) & 0xFF cast int8)
usart.write_byte(usart.USART1, (pkt.crc32 >> 8) & 0xFF cast int8)
usart.write_byte(usart.USART1, pkt.crc32 & 0xFF cast int8)
end
function packet_receive() -> Option<Packet> do
// Read header
let header = usart.read_byte(usart.USART1)
if header != 0xAA do
return Option.Hiçbiri
end
// Read length
let length = usart.read_byte(usart.USART1)
// Read data
let data = Array.yeni(length)
for i forde 0..length do
data[i] = usart.read_byte(usart.USART1)
end
// Read CRC
let crc_recv = 0 cast int
crc_recv = (crc_recv << 8) | usart.read_byte(usart.USART1) cast int
crc_recv = (crc_recv << 8) | usart.read_byte(usart.USART1) cast int
crc_recv = (crc_recv << 8) | usart.read_byte(usart.USART1) cast int
crc_recv = (crc_recv << 8) | usart.read_byte(usart.USART1) cast int
// Create packet
let pkt = Packet do
header: header,
length: length,
data: data,
crc32: crc_recv
end
// Verify CRC
let crc_calc = packet_calculate_crc(pkt)
if crc_calc == crc_recv do
io.yazdir_satır("✅ Packet CRC OK")
return Option.Bazı(pkt)
else do
io.yazdir_satır("❌ Packet CRC mismatch!")
return Option.Hiçbiri
end
end
Result: UART üzerinden gelen corrupt paketler reddedilir. Data integrity garanti edilir.
💡 Example 3: SD Card File Verification
Problem: SD card'dan okunan dosyanın bozulmadığını kontrol etmek
import hal::crc, hal::sdio
function file_calculate_crc(filename: String) -> int do
// Open file
let file = sdio.file_open(filename, sdio.MODE_READ)
if değil file.is_valid() do
io.yazdir_satır("ERROR: Cannot open file")
return 0
end
crc.reset()
// Read file in 512-byte blocks
let buffer: Array<int8> = Array.yeni(512)
loop do
let bytes_read = sdio.file_read(file, buffer)
if bytes_read == 0 do
break // EOF
end
// Process full 32-bit words
for i forde 0..(bytes_read/4) do
let word = (buffer[i*4] cast int) |
((buffer[i*4+1] cast int) << 8) |
((buffer[i*4+2] cast int) << 16) |
((buffer[i*4+3] cast int) << 24)
crc.accumulate(word)
end
// Handle remaining bytes
let remainder = bytes_read % 4
if remainder > 0 do
for i forde (bytes_read - remainder)..bytes_read do
crc.accumulate_byte(buffer[i])
end
end
end
sdio.file_close(file)
return crc.get_value()
end
function file_verify(filename: String, expected_crc: int) -> bool do
io.yazdir_satır("Verifying " + filename + "...")
let calculated = file_calculate_crc(filename)
io.yazdir_satır("Expected: 0x" + expected_crc.onaltılıya())
io.yazdir_satır("Calculated: 0x" + calculated.onaltılıya())
return calculated == expected_crc
end
Kullanım: Firmware update dosyalarının SD card'dan okunurken bozulmadığını garanti eder.
📚 API Reference
Core Functions
// CRC initialization
function init()
function deinit()
function reset() // Reset to initial value
// CRC calculation
function calculate(data: Array<int>) -> int
function accumulate(word: int) // Add 32-bit word
function accumulate_byte(byte: int8) // Add 8-bit byte
// Get result
function get_value() -> int
// Verification
function verify(data: Array<int>, expected: int) -> bool
⚠️ Important Notes:
- Word Alignment: CRC hardware 32-bit word aligned çalışır
- Byte Order: Little-endian işlemci for byte order dikkat edilmeli
- Initial Value: Reset endrası 0xFFFFFFFF (not 0x00000000)
- Final XOR: Bazı protokoller final XOR 0xFFFFFFFF gerektirir
🖥️ Platform Support
| Platform | CRC Support | Polynomial | Speed |
|---|---|---|---|
| STM32F1 | ✅ Var | 0x04C11DB7 | 1 cycle/word |
| STM32F4 | ✅ Var | 0x04C11DB7 | 1 cycle/word |
| STM32F7 | ✅ Var | Configurable | 1 cycle/word |
| STM32H7 | ✅ Var | Configurable | 1 cycle/word |
| GD32VF103 | ✅ Var | 0x04C11DB7 | 1 cycle/word |
✅ Best Practices
- ✅ Firmware check: Boot sırasında firmware CRC kontrolü do
- ✅ Communication: Paketlerde CRC kullan (especially wireless)
- ✅ Storage: Flash/SD card'dan okunan veriler for CRC
- ✅ Reset before use: Her hesaplama öncesi crc.reset() çağır
- ❌ Not for crypto: CRC security for değil, error detection for
- ❌ Byte alignment: Non-aligned erişim performans kaybı yaratır
🔗 Related Modules
- hal::flash - Firmware integrity verification
- hal::usart - UART packet CRC
- hal::sdio - SD card file verification
- hal::dma - DMA with CRC calculation