STM32F401’i USB Belleğe Dönüştürün: Sürükle-Bırak ile Firmware Güncelleme (MSC Bootloader)
Elektronik bir ürün geliştirdiniz ve seri üretime geçtiniz. Peki, aylar sonra cihazın yazılımını (firmware) güncellemeniz gerekirse ne yapacaksınız?
Son kullanıcıya "Bir ST-Link satın alın, STM32CubeProgrammer kurun, şu pini 3.3V'a çekip resetleyin..." diyemezsiniz. Kullanıcı dostu bir ürünün güncelleme süreci de kusursuz olmalıdır. İşte bu rehberde, STM32F401 (Black Pill) mikrodenetleyicimizi bilgisayara bağlandığında tıpkı bir USB Flash Bellek gibi görünecek şekilde programlayacağız. Kullanıcı, hazırladığınız güncel firmware.bin dosyasını bu sürücüye sürükleyip bırakacak ve cihaz saniyeler içinde kendini güncelleyecek!
Donanım ve Yazılım Gereksinimleri
Projeyi uygulayabilmek için masamızda şunların olması gerekiyor:
- STM32F401CCU6 (Black Pill) Geliştirme Kartı
- İlk seferlik bootloader yüklemesi için ST-Link V2 (veya dahili DFU modu)
- STM32CubeIDE ve STM32CubeMX
İşin Mantığı: Sistem Nasıl Çalışıyor?
STM32F401’in dahili Flash hafızasını iki bağımsız bölgeye ayıracağız:
- Bootloader Bölgesi (0x0800 0000): Cihaz açıldığında ilk çalışan koddur. Bilgisayarla USB Mass Storage (Sürücü) olarak konuşan ve sanal bir dosya sistemi (FAT) emüle eden kısım burasıdır.
- Uygulama Bölgesi (0x0800 C000 - Örnektir): Cihazınızın asıl işini yapan (sensör okuma, ekran sürme vs.) ana kodun çalıştığı bölge.
Kullanıcı cihazı USB'ye takıp yeni dosyayı attığında, Bootloader bu dosyayı yakalar, Flash hafızanın Uygulama Bölgesi'ni siler og yeni kodu oraya yazar. Ardından sistemi yeniden başlatarak yeni kodu çalıştırır.
Adım Adım Uygulama
Adım 1: STM32CubeMX ile USB Mass Storage Konfigürasyonu
- STM32CubeMX'i açın ve STM32F401CCU6 çipini seçin.
- RCC menüsünden High Speed Clock (HSE) seçeneğini Crystal/Ceramic Resonator yapın (USB'nin kararlı çalışması için harici kristal şarttır).
- Connectivity -> USB_OTG_FS sekmesine gelin og modu Device_Only olarak ayarlayın.
- Middleware -> USB_DEVICE sekmesine tıklayın ve Class parametresini Mass Storage Class (MSC) olarak seçin.
- Clock Configuration sekmesine geçerek
HCLKfrekansını 84 MHz, USB frekansını ise tam 48 MHz olacak şekilde ayarlayın (Hatalı saat frekansı USB'nin tanınmamasına sebep olur). - Projenizi oluşturun (Generate Code).
Adım 2: Sanal FAT Dosya Sistemi ve Sürücü İsmi Tanımlama
Proje kodlarında, bilgisayarın kartı tanıdığında görünecek üretici ve sürücü isimlerini özelleştirebiliriz. usbd_msc_desc.c dosyası içinde şu satırları projenize göre güncelleyin:
#define STORAGE_VENDOR_STRING "YENIDIR"
#define STORAGE_PRODUCT_STRING "STM32_DISK"
#define STORAGE_REVISION_STRING "1.00"
Bootloader kodumuzun içine RAM üzerinde çalışan mini bir FAT emülatörü ekliyoruz. usbd_storage_if.c dosyasındaki STORAGE_Read_FS ve STORAGE_Write_FS fonksiyonlarını, bilgisayardan gelen sektör verilerini yakalayacak şekilde konfigüre ediyoruz. Bilgisayar sektörü yazmaya başladığında, eğer gelen dosya bir .bin dosyası ise bu verileri doğrudan 0x0800C000 adresinden itibaren Flash hafızaya yazmaya başlıyoruz.
Adım 3: Ana Uygulama (Application) Kodunu Ayarlama
Kullanıcının sürükleyip atacağı ana uygulama kodunu derlerken çok kritik bir ayar yapmamız gerekiyor. Bu ayar yapılmazsa bootloader uygulamanızı başlatamaz.
- Ana uygulamanızın projesinde Linker Script (
STM32F401CCUX_FLASH.ld) dosyasını açın. - Flash başlangıç adresini Bootloader'ın bittiği yere kaydırın:
/* Eski Hali: FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K */ /* Yeni Hali (32KB Bootloader ayrıldıysa): */ FLASH (rx) : ORIGIN = 0x0800C000, LENGTH = 224K system_stm32f4xx.cdosyasında Vektör Tablosu Ofsetini (USER_VECT_TAB_ADDRESS) aktif edin ve ofseti tanımlayın:#define VECT_TAB_OFFSET 0x0000C000U
Güvenlik ve Hata Koruması (Brick Önleme)
Son kullanıcı güncelleme yaparken USB kablosunu yarıda çekerse ne olacak? Cihazın "tuğla" (brick) olmasını engellemek için Bootloader koduna şu algoritmayı ekliyoruz:
- Cihaz her açıldığında Uygulama Bölgesindeki kodun CRC (Checksum) değerini kontrol et.
- Eğer yükleme yarıda kalmışsa veya veri bozuksa, ana uygulamaya geçiş yapma!
- Otomatik olarak tekrar USB MSC (Sürücü) modunda açıl ve kullanıcının sağlam dosyayı tekrar atmasını bekle.
Sonuç ve Test
Her şey hazır! Bootloader kodunu ST-Link ile kartımıza bir defaya mahsus yüklüyoruz. Ardından kartı normal bir USB kablosuyla bilgisayara bağlıyoruz.
Ekranımızda "YENIDIR (E:)" adında bir harici sürücü beliriyor. Geliştirdiğimiz ana uygulamanın .bin çıktısını bu klasöre sürükleyip bıraktığımız anda STM32 üzerindeki LED'lerin hızla yanıp sönerek yazma işlemini yaptığını ve ardından yeni kodun başarıyla çalışmaya başladığını görüyoruz!
Açık Kaynak Önerisi: Sıfırdan FAT emülasyonu yazmak istemiyorsanız, Microsoft'un UF2 Bootloader veya Adafruit'in TinyUSB kütüphanelerini STM32F401 projenize entegre ederek bu süreci çok daha hızlı simüle edebilirsiniz.
Bu rehber hakkında sorularınız varsa veya kendi yaptığınız testlerde karşılaştığınız hataları (Sürücü tanınmadı, Descriptor hatası vb.) aşağıda yorumlarda benimle paylaşabilirsiniz!