CodeBlanks Logo Icon CodeBlanks

Özet - no_std ve gömülü

no_std, alloc ve panic_handler'ı birleştirerek gömülü bir şablon yazarsın.

no_std ve gömülü özeti

Katmanlar: core (her yerde), alloc (ayırıcı varsa), std (işletim sistemi varsa). #![no_std] kütüphaneleri her ortamda kullanılabilir; ikili dosyalar ayrıca #[panic_handler] ve giriş noktası ister. Gömülü dünyada sürücüler embedded-hal trait'lerine karşı yazılır ve sahte donanımla test edilir. WebAssembly için wasm32 hedefleri ve wasm-bindgen. Heap olmadan biçimlendirme için core::fmt::Write uygulayan sabit kapasiteli tamponlar kullanılır.

Sabit kapasiteli tampon

fmt::Write tek bir metot ister: write_str. Sığmayan yazmada hata döndürmek taşmayı güvenle bildirir:

use core::fmt;

struct Tampon {
    veri: [u8; 32],
    uzunluk: usize,
}

impl fmt::Write for Tampon {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        let b = s.as_bytes();
        let son = self.uzunluk + b.len();
        if son > self.veri.len() {
            return Err(fmt::Error);
        }
        self.veri[self.uzunluk..son].copy_from_slice(b);
        self.uzunluk = son;
        Ok(())
    }
}

Uygulama Heap'siz biçimlendirme

Yukarıdaki Tampon türünü yaz ve fn as_str(&self) -> &str ekle (core::str::from_utf8). write!(t, "x={}", 42) ile yazıp metni yazdır; ardından 40 karakterlik bir metni yazmayı dene ve hata dönüp dönmediğini boşlukla yazdır.

Başlangıç kodu

main.rs
use core::fmt::{self, Write};

fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
use core::fmt::{self, Write};

struct Tampon {
    veri: [u8; 32],
    uzunluk: usize,
}

impl Tampon {
    fn as_str(&self) -> &str {
        core::str::from_utf8(&self.veri[..self.uzunluk]).unwrap_or("")
    }
}

impl fmt::Write for Tampon {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        let b = s.as_bytes();
        let son = self.uzunluk + b.len();
        if son > self.veri.len() {
            return Err(fmt::Error);
        }
        self.veri[self.uzunluk..son].copy_from_slice(b);
        self.uzunluk = son;
        Ok(())
    }
}

fn main() {
    let mut t = Tampon { veri: [0; 32], uzunluk: 0 };
    write!(t, "x={}", 42).unwrap();
    let metin = t.as_str().to_string();
    let tasti = t.write_str(&"a".repeat(40)).is_err();
    println!("{} {}", metin, tasti);
}

Beklenen çıktı

x=42 true

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Heap olmadan <code>write!</code> ile metin biçimlendirmek nasıl mümkündür?

  • println! ile
  • core::fmt::Write uygulayan sabit boyutlu bir tampona yazarak Doğru cevap
  • Mümkün değil
  • String ile

Açıklama: heapless crate'i bu deseni String<N>, Vec<T, N> gibi hazır türlerle sunar.

2 Baytları kopyala

Soru
self.veri[self.uzunluk..son].____(b);
Cevap
self.veri[self.uzunluk..son].copy_from_slice(b);

Açıklama: copy_from_slice aynı uzunlukta bir dilimin baytlarını kopyalar.

3 Grubun özeti

Kavram Anlamı
#![no_std] Yalnızca core
extern crate alloc Heap türleri
#[panic_handler] Kendi panic işleyicin
fmt::Write Heap'siz biçimlendirme

Uzman bölümündeki tüm dersler