piątek, 19 grudnia 2014

STM32 prosty skrypt linkera

Skrypt jest rzeczywiście prosty. Zaprezentuję go w całej okazałości, żeby był bardziej zrozumiały. Jest to generalnie kompilacja działających i niedziałających przykładów z internetu. Minimum jest bardzo proste. Na początku w pamięci flash musi znaleźć się tablica wektorów przerwań (tablica wskaźników do funkcji obsługujących przerwania). Opisuje go sekcja oznaczona jako isr_vectors. KEEP jest konieczny, gdyż inaczej linker może chcieć wyrzucić coś, co jest nieużywane. Następnie w sekcji .text (chociaż można ją nazwać dowolnie) umieszczamy kod wykonywalny, który kompilator oznacza jako .text lub .text.* (* oznacza dowolny ciąg znaków). Po kodzie wykonywalnym umieszczamy stałe, które kompilator oznacza jako .rodata*. Teraz występuje kolejna sekcja. Zmienne zainicjowane. Musimy na nie utworzyć nową sekcję, gdyż wartości inicjujące muszą być zapisane w pamięci flash ( AT (_flash_data_start) umieszczamy sekcję po stałych), a adresy będą mapowane w pamięci RAM ( >RAM) .
Tutaj dorzuciłem małą ciekawostkę pod tytułem .ramsection. Gdy jakiejś funkcji dodamy atrybut .ramsection, np tak:

__attribute__ ((long_call, section (".ramsection")))

wtedy funkcja zostanie zmapowana do pamięci ram. Oczywiście kod startowy musi zadbać o to, aby została kod takiej funkcji został przekopiowany do pamięci RAM na starcie. Dlatego .ramsection jest w sekcji data. Podczas startu kopiujemy całą sekcję data od _data_start do _data_end na początek pamięci RAM.
Ostatnia sekcja to zmienne niezainicjowane. Są one mapowane do pamięci RAM. Dobra praktyka inżynierska nakazuje w kodzie startowym przejechać się zerami po obszarze pamięci od _bss_start do _bss_end. Oczywiście dobra praktyka inżynierska sobie, a realia sobie. Nie trzeba inicjować tego obszaru, ale podczas używania tych zmiennych należy pamiętać, że ich pierwsza wartość będzie w sumie losowa.

MEMORY
{
    RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
    FLASH (rx)  : ORIGIN = 0x08000000, LENGTH = 128K
}

SECTIONS
{
    .  = 0x0;        
    .isr_vectors : 
    {
     . = ALIGN(4);
     KEEP(*(.isr_vectors))
     . = ALIGN(4);
    } >FLASH
    
    .text :
    {
        *(.text)   
 *(.text.*) 
        *(.rodata)
        *(.rodata*)   
        . = ALIGN(4);
        _flash_data_start = .;
    } >FLASH
    
    .data : AT (_flash_data_start)
    {
     . = ALIGN(4);
     _data_start = .;
        *(.data)
        *(.data.*)
        *(.ramsection)
        _data_end = .;
    } >RAM

    .bss :
    {
     . = ALIGN(4);
     _bss_start = .;
        *(.bss)       
        _bss_end = .;
    } >RAM
    
}
 
Na koniec dorzucę:
Mój skrypt linkera - GitHub
Mój kod startowy - GitHub 

niedziela, 2 grudnia 2012

Boundary scan

Darmowe narzędzie do testowania układów elektronicznych poprzez interface jtag: http://www.urjtag.org/ Wystarczy dowolny programator jtag wspierany przez oprogramowanie. Chip musi wspierać skanowanie brzegowe: http://grouper.ieee.org/groups/1149/1/

 Jedyną przeszkodą jest fakt, że trzeba skądś zdobyć plik BSDL, który opisuje interfac'e jtag'owy do badanego układu. W pakiecie urjtag znajduje się narzędzie do konwersji plików bsdl na listę komend programu. Niestety miałem problem z tym narzędziem i plikami bsdl do procesorów freescale. Mimo że składnia pliku jest zgodna ze standardem, konwerter "wywracał" się na linii definiującej długość rejestru BSR. Zakomentowanie linii spowodowało, że konwerter zadziałał. Trzeba było jeszcze dodać definicję długości rejestru BSR, bo bez tego program przyjmuje jakąś basurdalną wartość (max int) i otrzymujemy "out of memory" i "segmentation fault".

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.

poniedziałek, 9 maja 2011

Kompilacja OpenOCD z D2XX

Używam systemu Ubuntu (na maszynie wirtualnej). Można pod nim dokonać cross-kompilacji OpenOCD z obsługą sterowników D2XX.

W systemie Ubuntu muszą być zainstalowane następujące rzeczy:

# apt-get install gcc-mingw32
# apt-get install mingw32
# apt-get install libconfig8
# apt-get install libtool
# apt-get install autoconf
# apt-get install automake
# apt-get install cmake
# apt-get install texinfo

Ze strony producenta układu FTDI należy pobrać aktualne sterowniki D2XX (dla Windows) i rozpakować zawartość archiwum do jakiegoś folderu, np: libftd2xx-win32
$ mkdir libftd2xx-win32
$ cd libftd2xx-win32
$ unzip ../CDM20602.zip
$ cd ..

Konfigurujemy kompilację:
$ ./configure --build=i686-pc-linux-gnu \
--host=i586-mingw32msvc \
--enable-ft2232_ftd2xx \
--with-ftd2xx-win32-zipdir=../libftd2xx-win32

Kompilujemy:
$ make

W strukturze katalogów pojawi się plik openocd.exe. Należy go przekopiować do instalacji openocd w systemie Windows i już... :) Oprócz sterowników D2XX do interface'u (np. KT-Link) żadne dodatkowe biblioteki nie są potrzebne.

Źródło: http://hp.vector.co.jp/authors/VA000177/html/openocd-build.html

sobota, 7 maja 2011

Eclipse Helios + STM32 + J-LINK

Ostatnio bardzo popularnym narzędziem do programowania stał się interface J-LINK, a raczej jego podróbka (czy też jak niektórzy mówią "odpowiednik"). Korzystanie z podróbek zakupionych oraz korzystanie z dołączonego do nich oprogramowania jest nielegalne.

Oryginalny J-Link jest dość drogi, kosztuje około 1500 PLN. Na rynku dostępna jest wersja edukacyjna, dzięki której można tworzyć niekomercyjne projekty i kosztuje ona niecałe 300 PLN (co już jest uczciwą ceną w stosunku do jakości i możliwości).

Na dzień pisania tej "dokumentacji dla potomności" aktualne wersje to:


Podłączamy i uruchamiamy hardware. Uruchamiamy program J-Link GDB Server.
Free Image Hosting at www.ImageShack.us


Zmieniamy ustawienia Debug Luncher'a. Musi być ustawiony "Standard GDB Hardware Debugging Luncher" domyślnie ustawiany jest inny.
Free Image Hosting at www.ImageShack.us



Konfiguracja zakładki "debuger".
Free Image Hosting at www.ImageShack.us



Konfiguracja zakładki "startup".
Free Image Hosting at www.ImageShack.us



I jeżeli wszystko jest w porządku możemy się cieszyć szybkim interface'em bez potrzeby własnoręcznej kompilacji (tak jak to jest w przypadku OpenOCD i sterowników D2XX do JTAG'ów bazowanych na FTDI).

wtorek, 3 maja 2011

Eclipse Helios + STM32 + OpenOCD + jtagkey

Po sieci krąży wiele tutoriali jak skonfigurować Eclipse Helios i OpenOCD. Niestety mi zajęło sporo czasu aby przebić się i dość o co chodzi, gdyż większość opisów dotyczy Eclipse Galileo (czyli starej wersji).

Na dzień pisania tej "dokumentacji dla potomności" aktualne wersje to:
Do tego wszystkiego potrzebujemy jakiś interface JTAG. OpenOCD wspiera m.in.:

  • Najtańszy JTAG jaki można sobie wyobrazić to Wiggler. Niestety wymaga portu równoległego, co w obecnych komputerach jest już rzadkością (o ile w ogóle jeszcze występuje). Jeżeli ktoś posiada port równoległy, Wigglera można kupić już nawet za 30 PLN lub złożyć samemu - google dostarczają wielu schematów.
  • Inteface'y z interface'em USB bazowane na układzie FT2232. Osobiście mam pewne "ALE" dotyczące tych interface'ów i ich sterowników. Ze względu na ograniczenia licencyjne binarki OpenOCD nie mogą być dystrybuowane ze skompilowaną biblioteką D2XX. Aby użyć sterowników D2XX należy OpenOCD skompilować własnoręcznie, co nie jest takie oczywiste i proste dla osób, które nie mają doświadczenia. Nie jest to jednak duży problem. OpenOCD domyślnie skompilowany jest z użyciem biblioteki libftdi, która działa nieco wolniej niż sterowniki producenta (ale też bardzo dobrze) - pod warunkiem że producent dostarcza sterowniki dla libftdi. Na aukcjach i polskich sklepach internetowych można nabyć wiele różnych rozwiązań sprzętowych, w tym: Olimex (kilka wersji), JTAG-lock-pick (Freddie Chopin, dobre wsparcie klienta/użytkownika), KT-Link (Kristech)
  • Interface'y bazowane na mikrokontrolerach, takie jak: J-Link. Teoretycznie J-Link jest wspierany przez OpenOCD, ale chyba od niedawna.
  • Inne... Wystarczy przejrzeć katalog "interface" w katalogu OpenOCD, gdzie są wyszczególnione pliki konfiguracyjne do różnych typów intarface'ów.



Po instalacji wszystkich narzędzi trzeba skonfigurować komendę uruchamiającą daemona OpenOCD
Free Image Hosting at www.ImageShack.us


Następnie trzeba stworzyć konfigurację do Debug.
Free Image Hosting at www.ImageShack.us


I na znalezieniu informacji, że trzeba przestawić Debug Luncher'a spędziłem pół dnia. Musi być ustawiony "Standard GDB Hardware Debugging Luncher" domyślnie ustawiany jest inny.
Free Image Hosting at www.ImageShack.us


Konfiguracja zakładki Debug
Free Image Hosting at www.ImageShack.us


Konfiguracja zakładki Startup
Free Image Hosting at www.ImageShack.us


Jeżeli wszystko jest ok, za każdym kliknięciem "robaczka" do procka zostanie załadowany aktualny plik elf i rozpocznie się debug.

Inne opisy konfiguracji: