BootLoader, pek çok kişi için tanıdık bir terimdir ve sık sık kullanılır. Örneğin, sistemi çevrimiçi olarak güncellediğimizde veya programı harici bellekte çalıştırdığımızda buna ihtiyaç duyarız. Bu yazıda, STM32 serisi MCU’lar için bir BootLoader programının nasıl tasarlanacağını anlatacağız.
BootLoader'ın Temel İlkesi
STM32 için bir BootLoader programı geliştirmek istediğimizden, öncelikle BootLoader programının temel ilkelerini anlamamız gerekir.
Bildiğimiz gibi, BootLOader programı, BootLOader programının temel işlevi olan sistem yönlendirmesini sağlamalıdır. STM32 serisi MCU için, program sistem başladıktan sonra dahili Flash belleğin başlangıç adresinden çalıştırılacaktır. Ardından uygulama programına girin ve belirlenen sıraya göre çalıştırın. Bu sırada, BootLoader ve uygulama programı şekilde gösterildiği gibi entegre edilir:

Ancak bazen, örneğin sistem için IAP'yi uygulamak istediğimizde olduğu gibi, uygulamanın doğrudan çalışmasını istemeyebiliriz; ya da uygulamanın dahili Flash bellekte çalışmasını istemeyebiliriz; ya da uygulama dahili Flash bellekte çalışıyor olsa da, uygulamanın belirlediğimiz dahili Flash adresinden çalışmasını isteyebiliriz vb. Bu durumlarda ayrı bir BootLoader programına ihtiyacımız vardır. Sistem önce BootLoader programını başlatır ve sistem hazır olduktan sonra uygulama programının çalıştırılmasına geçer, şekilde gösterildiği gibi:

Yukarıdaki resimde, uygulamayı dahili Flash belleğin belirtilen konumuna kaydediyoruz; bu, elbette sistem içi satın alma (IAP) gibi bazı ihtiyaçlarımızı karşılamak içindir. Elbette, uygulama programını harici Flash belleğe de kaydedebiliriz; bu durumda BootLoader programı, uygulama programını çalıştırmak için harici Flash belleğe atlar, ancak bunun ön koşulu, harici Flash bellekte uygulama programının bulunmasıdır. Ayrıntılı süreç şu şekildedir:

Elbette bu sadece bir örnektir; farklı bellekler için yalnızca adresi değiştirmemiz yeterlidir. BootLoader programında uygulanacak işlevlere gelince, bu kullanım amacına bağlıdır. Prensip olarak donanım algılama, sistem güncellemesi vb. gibi istediğimiz herhangi bir işlevi ekleyebiliriz.
STM32 için Önyükleyici Tasarımı
Hızlı Planlama
Hedef MCU olarak 1 MB Flash ve 192 KB SRAM'e sahip STM32F407IGT6'yı kullanıyoruz. Flash belleği iki bölüme ayırıyoruz; biri 16K bayt boyutunda önyükleme programı alanı (0x0800 0000 – 0x0800 3FFF) ve geri kalanı uygulama programı alanı (0x0800 4000 – 0x080F FFFF). Spesifik dağılım şu şekildedir:

BootLoader programının 16K depolama alanı kaplamasına izin verdik. Ancak program, Flash belleğin tamamını kullanabilir.
Önyükleyici Yapısı
BootLoader programının yapısını inceleyelim. BootLoader programını tasarlarken temel amacımız, uygulama programını güncellemektir. Peki, BootLoader programında uygulanması gereken temel işlevler nelerdir? Dikkate alınması gereken birkaç husus vardır. Bunlardan biri, ana programda uyguladığımız saat vb. gibi temel yapılandırmadır; diğeri ise Flash'ın çalışmasıdır ve uygulama programını güncellediğimizde Flash'ı kesinlikle kontrol edip yazacağız; bu bir atlama kontrol programıdır, sonunda uygulama programını çalıştırmamız gerekiyor ve atlama işlevi çok önemlidir. Elbette, farklı ihtiyaçlara göre başka ihtiyaçlar da olabilir. Aşağıdaki şekilde gösterildiği gibi:

Yukarıdaki şekilde, imzalamaya ilişkin üç temel uygulamaya ek olarak, IAP dosyalarını alma işlevini de ekledik. İşlevin bu kısmı da gereklidir, ancak farklı modlarda büyük farklılıklar olabilir. Zira dosyaların alınma yöntemi, Ethernet bağlantı noktası, seri bağlantı noktası vb. gibi çeşitli iletişim türleri olabilir. Ayrıca SD kart, USB bellek vb. gibi çeşitli bellek türleri de olabilir. Bu nedenle, bu işlev gerekli olsa da, uygulama yöntemi oldukça esnektir. Sonraki uygulamada, belirli konuları ayrıntılı olarak inceleyeceğiz.
Önyükleyici Uygulaması
Şimdi, Flash belleğin bölümlerini belirledik ve BootLoader'ın temel iş akışını anladık. Sırada, bir BootLoader programının nasıl uygulanacağını ele alacağım.
Önyükleyici Kodlaması
Çipin güç verildiğinde önce BootLoader programını çalıştırdığını, ardından uygulama programını yürütmek üzere uygulama programı alanına geçtiğini biliyoruz. Bu nedenle, BootLoader programını yazarken, önce sistemde IAP gereksinimi olup olmadığını değerlendiririz. IAP talebi varsa, IAP moduna girer. Tamamlandıktan sonra, yürütme için uygulama programına atlar. IAP talebi yoksa, yürütme için doğrudan uygulama programına atlar. Spesifik süreç şu şekildedir:

IAP işleme konusunda, farklı durumlarda farklı işleme yöntemleri söz konusu olacaktır. Burada esas olarak atlama kontrol programına değineceğiz. Öncelikle uygulamanın başlangıç adresini tanımlayın ve bir işlev işaretçisi türü bildirin. Ayrıntılar aşağıdaki gibidir:
#define ApplicationAddress 0x08004000 //Application first address definition
typedef void (*pFunction)(void); //Define the jump function pointer type
Bazıları, böyle bir işlev işaretçisi türünü neyin tanımladığını sorabilir; çünkü sonunda Reset_Handler işlevine atlıyoruz, dolayısıyla bu işlevi işaret edebilen bir işlev işaretçisine sahip olmamız gerekiyor. Ardından atlama programını yazabiliriz.
/*jump to application processing function*/
static void JumpToApplication(void)
{
uint32_tStackAddr; //Application stack address
uint32_tResetVector; //The address of the application interrupt vector table
pFunctionJumpToApp; //Define the jump function pointer
__set_PRIMASK(1); //Turn off global interrupt
StackAddr= *(__IO uint32_t*)ApplicationAddress; //0x08004000;
ResetVector = *(__IO uint32_t*)(ApplicationAddress + 4); //0x08004004;
if((StackAddr&0x2FFC0000)==0x20000000) //Check whether the stack top address is legal.
{
__set_MSP(StackAddr); //Initialize the application stack pointer
JumpToApp = (pFunction)ResetVector;
JumpToApp();
}
}
Uygulama İşleme
BootLoader kodlamasını tamamladıktan sonra, uygulamanın düzgün bir şekilde çalışması için uygulamaya geçmek istiyorsak, uygulamayı buna göre değiştirmemiz gerekir. Burada iki önemli değişiklik söz konusudur. Uygulama bir bare-metal programıysa, saati yapılandırmadan önce global midrange özelliğini etkinleştirmemiz gerekir.
/*Enable global interrupt, closed in BootLoader*/
__set_PRIMASK(0);
Aynı zamanda, orta uç vektör tablosunun ofset adresinin de değiştirilmesi gerekir. Kullandığımız STM32F07 için bu ayar, system_stm32f4xx.c dosyasında doğrudan değiştirilebilir.
#define VECT_TAB_OFFSET 0x4000 /*!< Vector Table base offsetfield.
Ardından, kullandığımız IAR EWARM V8.4'ü örnek alarak geliştirme ortamında gerekli değişiklikleri de yapmamız gerekiyor. icf dosyasında kesme vektör tablosu ve Flash bellek alanının ayarlarını değiştirin. Ayrıntılar şu şekildedir:


Yukarıdaki yapılandırmayı tamamladıktan sonra, doğru atlamayı gerçekleştirmek için uygulama programını ve BootLoader programını indirebiliriz.
Özet
Bu makalede, basit bir BootLoader programı geliştirdik. Hedef MCU’ya indirildikten sonra atlama işlemi gerçekleştirildi ve uygulama programı da normal şekilde çalışıyor; bu durum, tasarımımızın doğru olduğunu gösteriyor. Bu temel üzerine çeşitli işlevler eklenerek ilgili IAP uygulaması hayata geçirilebilir.
BootLoader programında global kesmeyi devre dışı bıraktığımızı unutmayın ve uygulama sistem saatini başlatmadan önce global kesmeyi etkinleştirmeyi unutmayın, aksi takdirde SystemTick çalışamaz ve bir donanım hatası (hardfault) meydana gelir. Ancak, uygulama RTOS üzerinde çalışıyorsa, kesmeyi açmak yanlış olabilir, bu konuya dikkat edilmesi gerekir.




