Zadaniem jest implementacja
systemu wbudowanego wykorzystującego elementy składowe układu Virtex2Pro:
procesor PowerPC oraz logikę programowalną.
Na początku należy uruchomić
system projektowy EDK (Embedded Development Kit - ikona na pulpicie). Po
uruchomieniu wyświetli się następujące okno:
Należy wybrać opcję
domyślną: Base System Builder wizard
Następnie wyświetli się
okienko:
Należy wcisnąć przycisk Browse
...
oraz dodać nowy katalog
projektowy za pomocą klawisza:
W przykładzie nazwa katalogu
projektowego to edk.
Po dodaniu nowego katalogu
należy do niego wejść klikając w jego nazwę:
A następnie zaakceptować
domyślną nazwę pliku projektu system.xmp naciskając przycisk Save:
Teraz można ostatecznie
zaakceptować wybór naciskając przycisk OK:
Następnie wyświetli się
okienko:
Należy zaakceptować klikając
przycisk Next.
Wyświetli się kolejne
okienko:
W polu Board vendor wybieramy
Xilinx, a w polu Board name wybieramy nazwę płytki
laboratoryjnej: XUP Virtex-II Pro Development System.
Pozostałe pola pozostawiamy bez zmian i wciskamy Next. Wyświetli się
kolejne okienko:
Wciskamy Next niczego
nie zmieniając (wybieramy procesor PowerPC), wyświetli się kolejne okienko:
W polu Processor clock
frequency wybieramy 200.00 MHz,
w polu Cache setup zaznaczamy
Enable, naciskamy Next.
Wyświetli się kolejne
okienko:
W polu Baudrate (bits per
second): wybieramy 115200, we wszystkich polach włączamy przerwania
zaznaczając: Use interrupt. Następnie naciskamy Next.
Wyświetli się kolejne
okienko:
W tym okienku nic nie
zmieniamy i naciskamy Next.
Wyświetli się kolejne
okienko:
Jest to dodatkowa pamięć
BRAM (Block RAM) – wbudowana w FPGA, pozwalająca na diagnostykę pamięci głównej
DDR SDRAM oraz na „bootloop” czyli pętlę zatrzymującą procesor po resecie
(pamięć ta może być ładowana do układu FPGA razem ze sprzętem w pliku *.bit).
Za pomocą przycisku Add Peripheral można dodać do projektu dodatkowe
urządzenia takie jak timer, watchdog czy kolejna pamięć BRAM. W tym przypadku
jednak nic nie dodajemy.
W polu Memory size wybieramy 64 KB. Następnie naciskamy Next.
Wyświetli się kolejne
okienko:
W okienku tym aktywujemy
pamięć cache dla wybranych rodzajów pamięci kodu i danych:
Zaznaczamy pola ICache oraz Dcache dla pamięci DDR_SDRAM.
Następnie naciskamy Next.
Wyświetli się kolejne
okienko:
Okienko to pozwala na
ustawienie urządzenia wejścia/wyjścia używanego do obsługi konsoli (xil_printf
itp.) oraz urządzenia pamięci mapowanego w obszar startowy procesora.
W tym okienku nic nie
zmieniamy i naciskamy przycisk Next.
Wyświetli się kolejne
okienko:
Okienko to pozwala na
określenie rodzajów pamięci używanych do obsługi określonych sekcji programu
testowego MemoryTest. Program testowy mieści się w całości w pamięci BRAM więc
łatwo można przetestować całą pamięć DDR SDRAM. Pamięć BRAM może być
inicjalizowana razem ze sprzętem w pliku *.bit.
W tym okienku także nic nie
zmieniamy i naciskamy Next.
Wyświetli się kolejne
okienko:
Okienko to pozwala na
określenie rodzajów pamięci używanych do obsługi określonych sekcji pamięci
programu testowego PeripheralTest. Wybór DDR SDRAM oznacza konieczność
ładowania programu przez debugger.
W polu Interrupt Vec wybieramy
DDR_SDRAM, a następnie naciskamy Next.
Wyświetli się okienko
podsumowania:
Naciskamy przycisk Generate
w celu wygenerowania projektu.
Wyświetli się okienko
zakończenia:
Naciskamy przycisk Finish.
Po chwili wyświetli się
główne okno projektu:
Konieczne jest jeszcze
wykonanie niewielkiej modyfikacji modułu obsługującego warstwę MAC sieci
Ethernet. W tym celu klikamy podwójnie na Ethernet_MAC w okienku Bus
Interfaces (na liście urządzeń). Wyświetli się następujące
okienko konfiguracyjne:
W okienku tym zaznaczamy Include
Second Receiver Buffer oraz Include Second Transmitter Buffer.
Pozwoli to na zwiększenie wydajności obsługi warstwy MAC dzięki podwójnemu
buforowaniu. Następnie naciskamy OK.
Po powrocie do głównego okna
programu można uruchomić syntezę:
Wybieramy w głównym menu:
Hardware, a następnie: Generate Bitstream. Można także nacisnąć przycisk:
Powinien rozpocząć się
proces syntezy i implementacji projektu który trwa około 20 minut. Syntezy i
implementacji nie trzeba będzie już powtarzać ponieważ w sprzętowej części
ćwiczenia nic nie będzie już zmieniane.
Następne ćwiczenie będzie
także wykorzystywało rezultaty syntezy i implementacji otrzymane w tym
ćwiczeniu.
Po zakończeniu syntezy i
implementacji należy przygotować projekt do komunikacji z płytką Virtex2Pro
(także inne czynności jak kopiowanie drzewa urządzeń potrzebne do następnego
ćwiczenia będą w tym momencie wykonane). Należy w tym celu kliknąć na pulpicie
w ikonę USB config in EDK. Skrypt ten wyszuka wszystkie projekty EDK
przeznaczone na płytkę V2Pro w katalogu domowym i zmodyfikuje odpowiednio
parametry komunikacji z płytką (włączy USB).
Następnie można przystąpić
do wykonania zadań:
Zadanie 1:
Uruchomienie programu TestApp_Memory
w pamięci BRAM (wbudowanej w układ Virtex2Pro).
Klikamy w zakładkę Applications,
klikamy prawym przyciskiem myszy na nazwę projektu TestApp_Memory i
zaznaczamy pole Mark to Initialize BRAMs. Dzięki temu wybrany program
będzie załadowany do pamięci BRAM i wczytany do układu V2Pro razem ze sprzętem
(w pliku *.bit). Ponieważ pamięć BRAM jest ograniczona nie każdy projekt może
być do niej załadowany w całości. Zazwyczaj jest ona używana do przechowywania
małego programu bootloadera. Kiedy bootloader nie jest używany pamięć BRAM
zazwyczaj zawiera mały „bootloop” – pętlę pozwalającą odzyskać kontrolę
debuggera nad procesorem po resecie, następnie debugger może załadować
testowany program do dowolnego obszaru pamięci.
Program TestApp_Memory jest
przeznaczony do testowania pamięci DDR SDRAM i w związku z tym mieści się w
pamięci BRAM.
Można także obejrzeć skrypt
linkera w którym znajdziemy definicje obszarów pamięci używanych przez
poszczególne sekcje naszego programu. Plik ten jest tworzony automatycznie i w
tym przypadku nie ma potrzeby jego modyfikacji.
Można także przejrzeć pliki źródłowe projektu *.c oraz *.h.
Specjalny plik xparameters.h
zawiera ważne definicje związane z konfiguracją sprzętu i nie powinien być
zmieniany ręcznie.
Następnie należy skompilować
projekt – klikamy prawym przyciskiem myszy na nazwę projektu i wybieramy Build
Project (można ewentualnie przedtem wybrać Clean Project). W
sytuacji kiedy projekt nie był skompilowany, a zostanie naciśnięty klawisz
ładowania projektu do płytki: kompilacja
nastąpi automatycznie, następnie program zostanie dołączony do pliku *.bit i
załadowany do płytki.
Przed załadowaniem projektu
do płytki należy uruchomić program MINICOM (ikona na pulpicie) i ustawić
prędkość 115200 bps (CTRL-A Z P I
<Enter>).
Sprawdzamy czy przewód RS232
jest podłączony do płytki V2Pro (ewentualnie przełączamy go z płytki Spartan-3
do V2Pro).
Następnie klikamy na klawisz
i
obserwujemy czy program się uruchomił (komunikaty na konsoli MINICOM).
Proszę pokazać rezultaty
prowadzącemu laboratorium.
Zadanie 2:
Uruchomienie programu TestApp_Peripheral
w pamięci DDR SDRAM i zademonstrowanie działania debuggera.
W tym celu należy zaznaczyć
w projekcie domyślnym pętli bootloop pole Mark to Initialize BRAMs (klikamy
prawym przyciskiem myszy na nazwę projektu domyślnego: Default: ppc405_0_bootloop).
Jak możemy stwierdzić
zaglądając do skryptu linkera program uruchamiany jest w pamięci DDR SDRAM, zaś
w BRAMie znajduje się jedynie początek kodu pozwalający na skok do głównego
programu w pamięci DDR SDRAM. Dlatego konieczne jest początkowe umieszczenie w
pamięci BRAM bootloopa który zostanie zastąpiony skokiem do początku kodu
programu dopiero po załadowaniu pamięci DDR SDRAM przez debugger.
Projekt należy skompilować
analogicznie jak w poprzednim zadaniu.
Następnie należy wysłać
projekt sprzętowy (z bootloopem) do płytki V2Pro (klawisz:). Projekt
uruchomi się, procesor będzie czekał w pętli na przerwanie z debuggera.
Potem uruchamiamy debugger
XMD naciskając klawisz .
Na początku system zażąda
ustawienia opcji debuggera:
Należy potwierdzić
naciskając klawisz OK. Następnie wyświetlone zostanie okienko
konfiguracji debuggera XMD:
W polu JTAG Cable należy ustawić:
Type: USB
Frequency: 6000000
Następnie należy nacisnąć
klawisz OK. Spowoduje to uruchomienie się XMD. Należy pozostawić ten
program uruchomiony.
Kolejną czynnością będzie
uruchomienie debuggera aplikacji. Należy kliknąć w ikonę co spowoduje wyświetlenie menu wyboru
aplikacji:
Należy wybrać aplikację: TestApp_Peripheral i nacisnąć OK.
Następnie wyświetli się okienko
debuggera aplikacji:
Klikając na ikonę załadujemy do pamięci i uruchomimy nasz
program.
Program zatrzyma się na
widocznej powyżej w postaci czerwonego kwadratu pułapce (domyślny breakpoint na
początku programu). Aby kontynuować wykonywanie programu naciskamy: (continue)
spowoduje to wykonanie wszystkich testów układów peryferyjnych (należy
zaobserwować rezultaty na konsoli MINICOM).
Po wykonaniu testów program
ponownie zatrzyma się na domyślnej pułapce (breakpoint - exit).
Proszę pokazać rezultaty
prowadzącemu laboratorium.
Można poeksperymentować z
ustawianiem innych pułapek (klikając w małe minusy po lewej stronie linii
kodu), a także z innymi funkcjami debuggera aplikacji.
Ponowne uruchomienie
aplikacji (włącznie z ponownym załadowaniem) możemy uzyskać za pomocą klawisza:
Innym sposobem szybkiego
uruchomienia programu w pamięci DDR SDRAM bez uruchamiania debuggera aplikacji
jest korzystanie z linii komend debuggera XMD:
XMD% cd
TestApp_Peripheral
XMD% dow
executable.elf
..............................
..............................
..............................
XMD% run
Zadanie 3:
Uruchomienie własnego
programu.
Zadanie polega na utworzeniu
aplikacji serwera telnet sterującego za pomocą komend tekstowych diodami LED
oraz odczytującego stan przełączników DIP. Do realizacji projektu wykorzystamy
bibliotekę uIP (stos TCP/IP dla mikrokontrolerów: http://en.wikipedia.org/wiki/UIP_(micro_IP)).
Przed stworzeniem nowego
projektu zakładamy dla niego katalog w którym będziemy przechowywać pliki
źródłowe. W naszym przykładzie katalog ten to:
~/edk/uip:
mkdir ~/edk/uip
Do tego katalogu kopiujemy
pliki (proszę wykonać następujące komendy):
cp
/opt/uip-1.0/uip/* ~/edk/uip
cp /opt/uip-1.0/apps/telnetd/*
~/edk/uip
cp
/opt/uip-1.0/unix/clock-arch.* ~/edk/uip
cp
/opt/uip-1.0/unix/uip-conf.h ~/edk/uip
cp
/opt/uip-1.0/lib/* ~/edk/uip
rm
~/edk/uip/uip-split.*
Teraz można stworzyć nowy
projekt - klikamy w Add Software Application Project.
Otwiera się okienko:
Nadajemy nazwę projektowi
wpisując ją w polu Project Name (w naszym przykładzie jest to uip). Naciskamy przycisk OK.
Następnie w powstałej
zakładce nowego projektu klikamy prawym przyciskiem myszy na pole Sources
i wybieramy opcję Add Existing Files.
Następnie dopisujemy do
projektu wszystkie pliki *.c z katalogu projektu ~/edk/uip.
Analogicznie postępujemy w
polu Headers z plikami nagłówkowymi (*.h).
Modyfikujemy plik uip_conf.h
zawierający konfigurację stosu TCP/IP:
Zmieniamy w linii 107
parametr UIP_CONF_BUFFER_SIZE na 2000 (nie ma potrzeby
oszczędzania pamięci tak jak w implementacjach na mikrokontrolerach).
Zmieniamy w linii 114
parametr UIP_CONF_BYTE_ORDER na UIP_BIG_ENDIAN (mamy do czynienia
z takim właśnie procesorem).
Zmieniamy w linii 121
parametr UIP_CONF_LOGGING na 0.
Dodatkowo w liniach 148/149
należy zamiast webserver.h włączyć
telnetd.h.
Teraz pozostaje napisać plik
główny programu: main.c integrujący bibliotekę uIP z bibliotekami
Xilinxa służącymi do obsługi GPIO i Ethernet-MAC.
Szczegółowe działanie
programu powinno być następujące:
Adres MAC urządzenia – 00:01:02:03:04:05
Adres IP urządzenia – 192.168.1.2 (adres portu eth1 komputera
laboratoryjnego jest następujący: 192.168.1.1, netmaska: 255.255.255.0).
Zamiast nieaktywnych pozycji
menu serwera telnet:
stats
- show network statistics
conn
- show TCP connections
należy wstawić pozycje:
leds - set LEDs
dip
- show DIP switch setting
Komenda leds powinna
wymagać 4-znakowego parametru złożonego z zer i jedynek. Zero oznacza diodę
zgaszoną, jedynka zapaloną. Pozycja pierwsza z lewej steruje diodą pierwszą z
lewej, itd. Po uruchomieniu aplikacji wszystkie diody powinny być zgaszone.
Proszę pamiętać o aktualizacji helpa.
Przetestować aplikację (ma
działać ping i telnet).
Proszę pokazać rezultaty
prowadzącemu laboratorium.
Rady i zalecenia ułatwiające
wykonanie zadania: