wtorek, 24 maja 2011

Przykłady do ZL28ARM ze strony kamami.pl

Zauważ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.