Przykłady do ZL28ARM ze strony kamami.plZauważyłem pewien problem związany z przykładowym kodem dołączonym do książki „Mikrokontrolery AT91SAM7 w przykładach” (Robert Brzoza-Woch). Jeżeli zostanie włączona optymalizacja linkera -Xlinker –gc-sections linker usuwa cały kod programu i wynikiem jest plik o długości 0x0 bajtów. Powodem jest źle skonstruowany skrypt linkera/plik startowy.
W oryginalnym pliku tablica wektorów wyjątków jest umieszczona w sekcji .text. Wygląda ona tak (fragment):
.text : { /* Startup code */ KEEP(*(.vectrom)) /* added by mthomas */ KEEP(*(.init)) *(.text .text.*) *(.gnu.linkonce.t.*) *(.glue_7t .glue_7) KEEP(*(.fini)) *(.gcc_except_table) } >FLASH =0
KEEP() oznacza, że symbole (sekcje) mają pozostać bez względu na optymalizację. Problem w tym, że żaden kod nie jest umieszczony w sekcji .vectrom, .init czy .fini. Nie jestem specjalistą od linkera, ale najprawdopodobniej zachodzi coś takiego, że wykonanie sekcji .text nie zależy od wykonania kodu w sekcji .vectrom, oznacza że kod w sekcji .text jest zbędny.
Aby pozbyć się tego problemu, tablicę wektorów wyjątków należy umieścić na początku sekcji .text i „oznaczyć” ją jako nieusuwalną (KEEP).
Oto fragment pliku startowego:
.section .vectors .arm _vectors: b Reset_Handler b Undefined_Handler b SWI_Handler b Prefetch_Handler b DataAbort_Handler b Reserved_Handler b IRQ_Handler b FIQ_Handler
Poprawiona sekcja .text:
.text : { KEEP(*(.vectors)) *(.text .text.*) *(.gnu.linkonce.t.*) *(.glue_7t .glue_7) KEEP(*(.fini)) *(.gcc_except_table) } >FLASH =0
Resztę kodu umieszczamy w sekcji .text. Teraz przy uruchomieniu optymalizacji linkera, linker usunie rzeczywiście nieużywany kod, a nie wszystko.