Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

stm32l1_bootloader

simple bootloader for stm32l1

image
bootloader.mp4

how it works

Linker’da bellek yerleşimi (BOOT)

FLASH (32 KB)
0x0800_0000                  +-----------------------------+  BOOT vektör tablosu (.isr_vector)
                             |    BOOT .text / .rodata    |  (BOOT kod/sabitler)
MY_MEMORY (32KB)             +-----------------------------+
                             |    (BOOT kalan FLASH)      |
                             +-----------------------------+  ← API_SHARED 0x8018000
                             |   APP alanı (ayrı proje)   |  (APP vektör tablosu + APP kodu)
                             +-----------------------------+
                
                RAM (32 KB)
                0x2000_8000  +-----------------------------+  _estack  (MSP başlangıcı)
                             |           STACK             |  (aşağı büyür)
                             +-----------------------------+
                             |       serbest/tampon        |  (özel section ayırılabilir)
                             +-----------------------------+
                             |            HEAP             |  (yukarı büyür)
                             +-----------------------------+
                             | .bss / .data (BOOT)         |
                0x2000_0000  +-----------------------------+
  • Linker script: FLASH/RAM sınırları, vektör tablosu konumu ve minimum stack/heap’i tanımlar.
  • APP için kullanılacak FLASH bölgesi, BOOT alanından sonra başlar (sembolik: FLASH_APP_ADDR).

go2APP() fonksiyonu

[BOOT çalışıyor] → go2APP()
   1) FLASH_APP_ADDR’deki ilk word = APP’in init MSP değeri
      → RAM aralığına düşüyor mu (maske kontrolü)?
   2) Evetse:
      - jump_address = *(FLASH_APP_ADDR + 4)   // Reset_Handler adresi
      - __set_MSP(*(FLASH_APP_ADDR))           // APP’in MSP’sini yükle
      - jump_to_app()                          // Reset_Handler’a zıpla
   3) Hayırsa:
      - "APP NOT FOUND" → BOOT modunda kal
        +-------------------------+
Reset → |   BOOT vektör tablosu   |
        +-----------+-------------+
                    |
                    v
              BOOT main()
                    |
                    v
                 go2APP()
       +-----------+-----------+
       |  MSP kontrol OK ?     |
       +-----------+-----------+
                   | Evet
                   v
   Set MSP → Read Reset_Handler → Jump (APP)
                   |
                  Hayır
                   v
           BOOT modunda devam et

  • Bu akışta BOOT, APP’in vektör tablosunu kullanarak “gerçek başlangıç” olan Reset_Handler’a dallanır. (APP kendi .data/.bss hazırlığını yapar ve main()’ine geçer.)

Linker’da sabit adresli API tablosu bölgesi

  • BOOT linker script’inde, BOOT’un yayınlayacağı API tablosu için sabit bir FLASH adresi belirlenir:
/* Örn: 0x0801_8000 adresi API tablosunun başlangıcı */
MEMORY { /* ... */ MY_MEMORY (rx) : ORIGIN = 0x08018000, LENGTH = 32K }

.API_SHARED 0x08018000 :
{
  KEEP(*(.API_SHARED))
} > MY_MEMORY

FLASH (BOOT)
0x0801_8000  +-----------------------------+
             |  .API_SHARED (sabit adres)  | → [fonksiyon adresleri tablosu]
             +-----------------------------+
             |  (MY_MEMORY’nin kalanı)     |
             +-----------------------------+

API header

  • Her iki proje de aynı struct’ı bilir:
struct BootloaderSharedAPI {
  void (*Blink)(uint32_t dlyTicks);
  void (*TurnOn)(void);
  void (*TurnOff)(void);
};

  • Bu yapı: fonksiyon işaretçileri tablosunun tipi (sıra ve imzalar = sözleşme).

Tabloyu doldurma

  • BOOT, fonksiyon adreslerini bu tabloya link zamanında yazar ve tabloyu sabit adrese koyar:
__attribute__((section(".API_SHARED"), used, aligned(4)))
const struct BootloaderSharedAPI g_BootApi = {
  .Blink  = Blink,
  .TurnOn = TurnOn,
  .TurnOff= TurnOff
};
0x0801_8000  +-------------------------------+
             | g_BootApi (const tablo)       |
             |  ├─ &Blink    (adres)         |
             |  ├─ &TurnOn    (adres)        |
             |  └─ &TurnOff   (adres)        |
             +-------------------------------+

  • BOOT çalışırken ekstra bir “kurulum” yapmaz; tablo zaten FLASH’ta hazırdır.

Tabloyu kullanma (APP tarafı)

  • APP, sabit adrese pointer cast yapar ve fonksiyonları çağırır:
const struct BootloaderSharedAPI *api =
   (const struct BootloaderSharedAPI*)0x08018000;  // sabit tablo adresi

api->Blink(200);
api->TurnOn();
api->TurnOff();

APP main()
   |
   v
api = (BootloaderSharedAPI*) 0x0801_8000  (sabit adres)
   |
   v
api->Blink(...)  →  tabloda kayıtlı adrese dal → BOOT’taki Blink()

GENEL ŞEMA

[FLASH]                                [RAM]
+----------------------+               +----------------------+
| BOOT vektör tablosu  |               |  .data/.bss (BOOT)   |
| BOOT .text/.rodata   |               |  Heap / Stack        |
|                      |               +----------------------+
| 0x08018000           |
| +------------------+ |   APP: api = (BootloaderSharedAPI*)0x08018000
| | .API_SHARED      | |   api->Blink() → &Blink (BOOT kodu)
| |  &Blink          | |
| |  &TurnOn         | |
| |  &TurnOff        | |
| +------------------+ |
|                      |
| ...                  |
+----------+-----------+
           |
           v  (FLASH_APP_ADDR)
+----------------------+   APP vektör tablosu + APP kodu
|        APP            |
+----------------------+

tutorial

image image image image image image

References

Acknowledgment:
This repository reimplements ideas demonstrated in the STMicroelectronics videos linked above. All credits for the original tutorial content belong to STMicroelectronics.

About

simple bootloader for stm32l1

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages