====== 10. Semestrální úloha - display a klávesnice na PCIe ====== /* * [[courses:a0b36apo:solutions:10:start]]*/ ===== Zadání úlohy ===== Pomocí PCIe karty EVB/Altera DB4CGX15 a přípravku s LCD a klávesnicí realizujte systém pro zaslání jednoduché číselné zprávy/kódu (pager, předchůdce SMS). Předpokládejte, že každá jednotka bude mít přiřazené unikátní číslo ID pod kterým se přihlašuje k centrálnímu serveru služby. Číslo ID a IP adresa centrálního serveru budou programu předané na příkazovém řádku při spuštění. Po spuštění bude jednotka v základním režimu. Při stisku libovolné číselné klávesy přejde jednotka do režimu zadání zprávy. Na klávesnici pak bude dokončené zadání ID čísla cílové jednotky a poté maximálně šest číslic kódu, který má být doručený na cílovou jednotku. Na každý stisk klávesy jednotka reaguje krátkou akustickou odezvou. Pokud uživatel po 30 sekund nestiskne klávesu, dojde automaticky k přechodu jednotky do základního režimu. V základním režimu se jednotka centrálního serveru každých pět sekund dotáže, jestli se na něm nenachází zpráva určená pro danou jednotku. Pokud ano, tak jednotka provede akustickou signalizaci a zobrazí zprávu na displeji tak dlouho, dokud nebude potvrzená k tomu určeným tlačítkem. Poté oznámí serveru přečtení zprávy. Nedílnou součástí řešení bude uživatelský manuál a technická zpráva (včetně zdrojových kódů). Protokol pro dotazování serveru bude realizován s využitím TCP/IP. Jednoduchý server a popis jeho protokolu bude k dispozici. Po dohodě se cvičícím je možné navrhnout protokol i server vlastní, požadavkem je podpora alespoň 10 účastníků sítě a fronty alespoň 10 čekajících zpráv pro každého účastníka. Rozšířené řešení také může obsahovat podporu zpětnou informaci o doručení zprávy případně informaci o aktuálně aktivních uživatelích nebo rozšíření o editaci textových zpráv na mobilní klávesnici. Při odevzdání se kontroluje funkčnost řešení, porozumění problematice a dokumentace. Dokumentace je vždy povinná, boduje se ale pouze v případě finálního a funkčního řešení. Hodnocení plným počtem bodů je možné při odevzdání nejpozději na cvičení v zápočtovém týdnu. Každý další týden se hodnocení snižuje o 5 bodů. ==== Doporučený postup řešení a hodnocení ==== * algoritmus pro nalezení karty v systému - ekvivalent ''lspci -nn -v -d 1172:1f32'' (přes ''/proc/bus/pci'') [2b] * namapování registrů PCIe karty do paměti procesu a zapnutí napájení přípravku [1b] * simulace sběrnicového cyklu a zápis na LED na přípravku [2b] * inicializace LCD a zobrazení textového řetězce [2b] * vyhodnocení stisknuté klávesy a výpis jejího kódu na terminál PC * scanování klávesnice [2b] * ošetření zákmitů [1b] * akustická odezva stisku kláves (pomocí vestavěného piezoelementu) [1b] * načtení ID cílové jednotky a obsahu zprávy (se zobrazováním při editaci) [2b] * kompletace - propojení algoritmu s přípravkem (rozhraní na LCD a ovládání klávesnicí přípravku) a serverem [max 3b] * dokumentace (ve formátu pdf) [pouze v případě finálního funkčního řešení, max 2b za uživatelskou příručku a max 2b za technickou zprávu] ===== Server pro uchování a předání zpráv ===== K dispozici je následující minimalistická implementace serveru pro ukládání a výběr zpráv {{:courses:a0b36apo:tutorials:10:apo-pagercentral-2015-1.tar.gz|}} Zdrojové kódy se zkompilují příkazem ''make''. Program je možné spustit s parametrem -v, kdy vypisuje diagnostické hlášky na chybový výstup. ./pagercentral -v Server se základním nastavením pak naslouchá na portu 55556. Server lze otestovat programem ''telnet'' nebo ''nc'' telnet localhost 55556 Dotaz na přítomnost zprávy ve frontě zpráv určených pro danou jednotku querrymessage 42 Odpověď obsahuje klíčový token ''querrymessage_r'', ''pager_id'' , a dále pokud je fronta prázdná, tak text ''none''. Pokud není fronta prázdná tak bude následovat číselný identifikátor zprávy v systému, poté číslo ID jednotky odesílatele a nakonec vlastní text/kód zprávy. Server se snaží vysvětlit v odpovědi i případné chyby v poslaných datech. Při spuštění s přepínačem ''-v'' je i značné množství diagnostických hlášek vypisované přímo na konzoli serverem. Příjem a přečtení zprávy se potvrdí příkazem confirmmessage 42 123456 Server odešle odpověď ''confirmmessage_r'' a zopakuje číslo pageru a zprávy. Nová zpráva je centrálnímu systému vyslaná příkazem sendmessage 42 53 1337 Odpověď bude místo textu zprávy obsahovat přiřazené unikátní číslo v rámci systému sendmessage_r 42 53 123456 Pro popis jednotlivých volání použijte příkaz ''man'' nebo prostudujte [[http://beej.us/guide/bgnet/|Beej's Guide to Network Programming]]. ===== Popis hardware ===== Hardware se skládá z vstupně výstupní karty realizující vstupně výstupní brány a registry mapované do paměťového adresního prostoru PCI sběrnice a externího kytu obsahujícího jednoduchou maticovou klávesnici, řadič znakového displeje 2x16 znaků a 8 LED diod. Karta s obvodem FPGA, umožňuje nastavovat řídit signály na 8-bit paralelním portu, který slouží pro generování řídicích signálů na softwarově řízené 8-bit paralelní sběrnici. Dále obsahuje 8-bit registr, který slouží pro přípravu dat vybavených na datové vodiče (D0 až D7) a 8-bit bránu pro čtení dat z datových vodičů, když je periferie naadresovaná v režimu čtení. Registry mapované na softwarově řízenou 8-bit sběrnici ^ Adresa na 8-bit sběrnici ^ Směr ^ Označení ^ Popis ^ | 0 | WR | LCD_INST | Zápis instrukce do řadiče LCD | | 1 | RD | LCD_STAT | Stavový registr LCD řadiče | | 2 | WR | LCD_WDATA | Zápis dat do zobrazovací paměti \\ nebo generátoru znaků | | 3 | RD | LCD_RDATA | Čtení dat z paměti LCD řadiče | | 1 | WR | LED_WR | Zápis LED | | 3 | WR | KBD_WR | Zápis do scanovacího registru klávesnice a sirénky | | 0 | RD | KBD_RD | Čtení vrácených hodnot při testování klávesové matice | Registry naprogramované na kartě EVB/Altera [[http://www.ebv.com/en/products/categories/details/product/ebv-cyclone-iv-gx-development-kit.html|DB4CGX15]]. V případě naprogramování karty za běhu počítače je nutné vyvolat novou enumeraci karty. sudo -i echo 1 > /sys/bus/pci/rescan lspci -nn -v -d 1172:1f32 echo 1 >/sys/bus/pci/devices/0000\:bb\:dd.f/enable V případě přítomnosti karty během startu systému není tato inicializace potřeba. V prosředí laboratoře KN:E-328 je však nutné pro přihlášeného studenta povolit přístup paměti pro čtení a zápis. Pro tyto účely je k dispozici nástroj devmemrw který je potřeba před začástkem experimentování spustit. ^ Adresa na PCIe sběrnici ^ Směr ^ Označení ^ Popis ^ | BAR0+0x0000 | RD/WR | RAM | Lokální paměť 32kB RAM v obvodu FPGA | | BAR0+0x8000 | RD/WR | timer_0 | Časovač na kartě s možností generování IRQ | | BAR0+0x8020 | WR | **emul_bus_data_out** | **Datové signály - výstupní hodnoty** | | BAR0+0x8040 | RD | **emul_bus_data_in** | **Datové signály - čtení aktuální hodnoty** | | BAR0+0x8060 | WR | **emul_bus_addr** | **Hodnota na adresové vodiče emulované sběrnice** | | BAR0+0x8080 | WR | **emul_bus_ctrl** | **Řídicí signály emulované sběrnice** | | BAR0+0x80A0 | WR | Led_Pio | Zápis na LED přímo na kartě | 8-bitový výstupní registr s řídícími signály emulované sběrnice (**emul_bus_ctrl**) ^ Bit ^ Označení \\ signálu ^ Pin IO \\ Modulu ^ Pin FPGA ^ Popis ^ | 0 | RD | IO13 | L9 | Řízení čtení (aktivní v L) | | 1 | WR | IO14 | K9 | Řízení zápisu (aktivní v L) | | 2 | | | | | | 3 | | | | | | 4 | | | | | | 5 | | | | | | 6 | CS0 | IO15 | N10 | Potvrzení výběru periferie (aktivní v L) | | 7 | PWR | IO18 | L11 | Povolení napájení periferie | 8-bitový výstupní registr pro nastavení adresy na emulované sběrnici (**emul_bus_addr**) ^ Bit ^ Označení \\ signálu ^ Pin IO \\ Modulu ^ Pin FPGA ^ Popis ^ | 0 | A0 | IO11 | K8 | Adresový bit 0 (LSB) | | 1 | A1 | IO12 | N9 | Adresový bit 1 | | 2 | | | | | | 3 | | | | | | 4 | | | | | | 5 | | | | | | 6 | | | | | | 7 | | | | | 8-bitový výstupní registr (**emul_bus_data_out**) definuje data, která jsou přivedena na simulovanou datovou sběrnici v době zápisu. Stejné je i mapování bitů ve vstupním registru (**emul_bus_data_in**), který slouží ke čtení aktuálních hodnot datových vodičů především pro cyklus čtení. ^ Bit ^ Označení \\ signálu ^ Pin IO \\ Modulu ^ Pin FPGA ^ Popis ^ | 0 | D0 | IO1 | L4 | Bit 0 datové sběrnice (LSB) | | 1 | D1 | IO2 | M4 | Bit 1 datové sběrnice | | 2 | D2 | IO3 | N4 | Bit 2 datové sběrnice | | 3 | D3 | IO4 | N5 | Bit 3 datové sběrnice | | 4 | D4 | IO5 | L5 | Bit 4 datové sběrnice | | 5 | D5 | IO6 | N6 | Bit 5 datové sběrnice | | 6 | D6 | IO7 | M6 | Bit 6 datové sběrnice | | 7 | D7 | IO8 | L7 | Bit 7 datové sběrnice (MSB) | Další řídicí signály (z pohledu programátora nejsou důležité) IO10 (M9) = not WR and RD = not IO14 and IO13 IO9 (N9) = (WR and RD and CS0) or not (WR or RD) = (IO14 and IO13 and IO15) or not (IO14 or IO13) Přepínání směru emulované sběrnice je řízené signály RD, WR a CS0. Směr je přepnutý na výstup z FPGA při (not WR and RD to je not IO14 and IO13) Další signály jsou pro toto cvičení konstantní IO19 (N12) = 0 IO20 (K10) = 1 ===== Maticová klávesnice ===== [[http://www.dribin.org/dave/keyboard/one_html/|Popis vyhodnocení stisku kláves na maticové klávesnici]] ===== Řadič LCD displeje ===== Přípravek používá standardní HD44780 řadič. Pro inicializaci * Zapsat konstantu CHMOD_LCD_MOD na adresu BUS_LCD_INST_o emulované sběrnice * Počkat alespoň 10 ms * Opakovat zápis CHMOD_LCD_MOD na adresu BUS_LCD_INST_o emulované sběrnice * Počkat alespoň 10 ms * Smazat vnitřní pamět zobrazované informace zápisem CHMOD_LCD_CLR na adresu BUS_LCD_INST_o emulované sběrnice * Počkat alespoň 10 ms * Zapnout vlastní zobrazení textu v paměti kontroléru displje zápisem CHMOD_LCD_DON na adresu BUS_LCD_INST_o emulované sběrnice Zápis znaku * Dokud je nastavený příznak CHMOD_LCD_BF v hodnotě čtené z adresy BUS_LCD_STAT_o tak čekat * Zápis hodnoty znaku ('A') an adresu BUS_LCD_WDATA_o Posun na danou pozici pro zápis dalšího znaku * Na instrukční adresu displeje (BUS_LCD_INST_o) zapsat CHMOD_LCD_POS+//// , pro druhou řádku přičíst k pozici hodnotu 0x40 (Upraveno 4.5. na základě upozornění na nedostatky panem Tomášem Krupkou) ===== Nápověda k řešení ===== === Otestování připojení a funkčnosti přípravku === {{courses:A0B36APO:tutorials:10:mmaped_8bit_bus_kbd-test-2014.tar.gz|}} === Vlastní programování === V následujícím archivu jsou uložené hlavičkové soubory s adresami registů displeje a klávesnice na emulované sběrnici. {{courses:A0B36APO:tutorials:10:mmaped_8bit_bus_kbd-headers-2014.tar.gz|}} === Procházení adresářů ''/proc/bus/pci'' === [[http://www.gnu.org/software/libc/manual/html_node/Opening-a-Directory.html#index-opendir-1413|opendir]] [[http://www.gnu.org/software/libc/manual/html_node/Reading_002fClosing-Directory.html#index-readdir-1417|readdir]] [[http://www.gnu.org/software/libc/manual/html_node/Reading_002fClosing-Directory.html#index-closedir-1421|closedir]] === Načtení PCI hlavičky === Jednotlivé soubory ''/proc/bus/pci/''//bb//''/''//dd//''.''//f// obsahují data PCI hlaviček (kopii PCI configuration space) v systému nalezených zařízení [[http://www.gnu.org/software/libc/manual/html_node/Opening-Streams.html|fopen]] [[http://www.gnu.org/software/libc/manual/html_node/Block-Input_002fOutput.html|fread]] [[http://www.gnu.org/software/libc/manual/html_node/Closing-Streams.html|fclose]] Formát hlavičky PCI zařízení je popsaný například na [[http://en.wikipedia.org/wiki/PCI_Configuration_Space|Wikipedii]] Podrobnější popis architektury sběrnice PCI a PCIe byl probíraný i v rámci přednášek [[..:..:lectures:05:start|5. I/O podsystém 1]] a [[..:..:lectures:06:start|6. I/O podsystém 2]]. Hierarchii PCI/PCIe popisuje především prezentace {{courses:A0B36APO:lectures:06:pci-bus-and-control-space.pdf|PCI a PCI Express sběrnice a PCIe}}. V prvních čtyřech byte je zakódovaná identifikace výrobce a zařízení - pro použitý FPGA design/kartu je kód výrobce 0x1172 a kód zařízení 0x1f32. Fyzická adresa paměťového okna karty je uložena registru BAR0. Spodní bity registru je potřeba odmaskovat - viz tabulka PCI BAR Bits. Zařízení by mělo být před prvním přístupem povoleno zápisem hodnoty "1" do souboru ''/sys/bus/pci/devices/0000:''//bb//'':''//dd//''.''//f///enable \\ Misto hodnot bb, dd a f pouzijte konkretni hodnoty bus, device a function zjistene pomoci prikazu lspci. === Otevření a mapování ''/dev/mem'' === [[http://www.gnu.org/software/libc/manual/html_node/Opening-and-Closing-Files.html|open]] použít [[http://www.gnu.org/software/libc/manual/html_node/Operating-Modes.html#index-O_005fFSYNC-1359|O_FSYNC]] , aby byl přístup přímý bez průchodu vyrovnávací pamětí. Fyzická adresa reprezentovaná ''/dev/mem'' se namapuje do adresního prostory procesu funkcí [[http://www.gnu.org/software/libc/manual/html_node/Memory_002dmapped-I_002fO.html#index-mmap-1255|mmap]] Aby nedošlo při zápisu do stránek k spuštění mechanizmu Copy on Write (COW), je třeba použít volbu MAP_SHARED === Přístup k registrům na kartě === K vlastním registrům pak přistupovat přes ukazatele typu (volatile uint32_t *) Nejdříve si vyzkoušet zápis a čtení paměti mapované na FPGA, pak pokročit k zapnutí přípravku a simulaci sběrnicových cyklů. Prográmek pro přímé čtení, zápis a vyplňování oblastí a registrů mapovaných nejen do fyzické paměti (''/dev/mem'') {{courses:A0B36APO:tutorials:10:rdwrmem.tar.gz|}} Po skompilování příkazem ''make'' si lze vypsat nápovědu zadáním parametru ''-h'' ./rdwrmem -h Počáteční adresa zápisu se specifikuje parametrem ''-s''. Pro začátek práce s předloženým HW je pro první test nejsnažší specifikovat adresu řídicího registru **emul_bus_ctrl** . Ten se nalézá na adrese BAR0 + 0x8080. Při zápisu hodnoty s nastaveným bitem č. 7 (''-F 0xFF'') dojde k zapnutí napájení přípravku. Píklad přístupu k registru **KBD_WR** a vypnutí piezoměniče. Poznamka: Zustante prihlihlaseni pod spravcem (prikaz: sudo -i). # zapnutí napájení ./rdwrmem -s -F 0xFF # příprava adresy pro zápis (budeme posilat 03) ./rdwrmem -s -F 0x03 # příprava dat pro zápis (budeme posilat 00) ./rdwrmem -s -F 0x00 # aktivace signálu WR ./rdwrmem -s -F 0xFD # signály WR a CS0 aktivní ./rdwrmem -s -F 0xBD # prodleva - alespoň 10 mikrosekund sleep 1 # deaktivace CS0 ./rdwrmem -s -F 0xFD # deaktivace WR ./rdwrmem -s -F 0xFF === Dotaz serveru na povolení přístupu === * Vytvořit socket ''int client_socket = socket(AF_INET,SOCK_STREAM,0);'' ... [[http://www.gnu.org/software/libc/manual/html_node/Creating-a-Socket.html|více o volání]] * sestavit adresu ''struct sockaddr_in address;'' voláním [[http://www.gnu.org/software/libc/manual/html_node/Host-Address-Functions.html|inet_aton nebo inet_addr]] * připojit se na server voláním [[http://www.gnu.org/software/libc/manual/html_node/Connecting.html|connect]] * použít [[http://www.gnu.org/software/libc/manual/html_node/Descriptors-and-Streams.html|fdopen]] pro komfortní práci se vstupem/výstupem nebo se spokojit se [[http://www.gnu.org/software/libc/manual/html_node/Sending-Data.html|send]] a [[http://www.gnu.org/software/libc/manual/html_node/Receiving-Data.html|receive]] * Pro obousměrnou komunikaci se pro sockety se obvykle používá režim fdopen "r+". * pokud je použito ''fdopen'' lze přímo na vytvořený stream použít [[http://www.gnu.org/software/libc/manual/html_node/Formatted-Output-Functions.html#index-fprintf-1069|fprintf]]. * pro synchronizaci streamu, odeslání všech bufferů použít [[http://www.gnu.org/software/libc/manual/html_node/Flushing-Buffers.html|fflush]] * odpověď lze získat přes [[http://www.gnu.org/software/libc/manual/html_node/Formatted-Input-Functions.html|fscanf]] int res, gate_id, user_id; char *s; res = fscanf(client_file, "checkaccess %d %d %as", &gate_id, &user_id, &s); * pokud se přechází mezi režimem zápisu (fwrite, fprintf) a čtení (fread, fgets, fscanf) tak je potřeba buffery streamu synchronizovat voláním [[http://www.gnu.org/software/libc/manual/html_node/File-Positioning.html#index-fseek|fseek]] fseek(client_file, SEEK_CUR, 0) * stream se ukončí přes [[http://www.gnu.org/software/libc/manual/html_node/Closing-Streams.html|fclose]], které uzavře i vlastní nízkoúrovňový socket. ===== Výchozí C program pro semestrální práci ===== Pokud někdo pořád ještě neví jak začít, může využít následující výchozí program v jazyce C, který dovede zapnout a vypnout přípravek. Kód obsahuje řadu TODO odkazů s náměty pro pokračování. Archiv obsahuje i Makefile, takže může vše přeložit zadáním ''make'' , případně pro build, tj. nové sestavení všeho, zadejte napřed ''make clean'' a poté příkaz ''make''. {{:courses:a0b36apo:tutorials:10:zaklad.tar.gz|}} #define DEV_ENABLE "/sys/bus/pci/devices/0000:03:00.0/enable" #define DEV_ADDRESS 0xfe8f0000 #define CTRL 0x8020 #include #include #include #include /* Rutina pro aktivaci PCI zarizeni, pokud nebylo konfigurovane pri startu pocitace (BIOS) */ /* Pro zapis je nutne opravneni superuzivatele */ int pciEnable(int isEnable) { char cen = isEnable!=0 ? '1' : '0'; int enable = open(DEV_ENABLE,O_WRONLY); //TODO: cestu DEV_ENABLE nutno nacist prohledanim PCI seznamu if(enable==-1) return 0; // TODO: Doplnit poradne chybove hlaseni write(enable,&cen,1); close(enable); return 1; } int main() { int soubor= open("/dev/mem",O_RDWR | O_SYNC); if(soubor==-1) return 1; // TODO: Doplnit poradne chybove hlaseni // TODO: konstantu DEV_ADDRESS a delku 0x10000 musite najit prohledanim seznamu PCI zarizeni unsigned char * base = mmap(NULL,0x10000,PROT_WRITE | PROT_READ, MAP_SHARED, soubor, DEV_ADDRESS); if(base==MAP_FAILED) return 2; // TODO: Doplnit poradne chybove hlaseni /* Aktivace dekoderu PCI karty - bezne se o ni pastara BIOS * pritom vyzaduje opravneni superuzivatele - spravce * if(!pciEnable(1)) * exit(1); * / *(base+CTRL)=0xF0; // zapni napajeni sleep(1); // cekej 1 vterinu - kratsi doba cekani-hledejte: usleep, nanosleep // TODO: Vase semestralni prace *(base+CTRL)=0x00; // vypni napajeni /* pciEnable(0); */ return 0; } //TODO: Podprogram pro zapis/cteni bytu na emulovane PCI sbernici //+TODO: cteni klavesnice, //+TODO zapis na LCD //+TODO: program automatu na jizdenky Nejvhodnějším mechanizmem pro vložení prodlevy je volání /* Protože clock_nanosleep timespec je definované až v novějším standardu IEEE Std. 1003.1j-2000 je potřeba buď kompilovat s CFLAGS+=-std=gnu99 nebo nastavit */ #define _GNU_SOURCE /* případně podle standardu */ #if !defined(_POSIX_C_SOURCE) || (_POSIX_C_SOURCE < 200112L) #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200112L #endif #include void v_tele_funkce(void) { struct timespec wait_time = { .tv_sec = 0, /* seconds */ .tv_nsec = 12000 /* nanoseconds [0 .. 999999999] */ }; clock_nanosleep(CLOCK_MONOTONIC, 0, &wait_time, NULL); } Při linkování je pak vyžadovaná knihovna ''rt''. Lze přidat přepínačem ''-lrt'' nebo v ''Makefile'' LDFLAGS+=-lrt ===== Technická dokumentace k použitému hardware ===== ==== Dokumentace k přípravku/desce maticové klávasnice MO_KBD3 ==== {{courses:A0B36APO:tutorials:10:mo_kbd3-minimal-sch.pdf|mo_kbd3-minimal-sch.pdf - Zjednodušené schéma kytu klávesnice MO_KBD3}} {{courses:A0B36APO:tutorials:10:mo_kbd3-sch.pdf|mo_kbd3-sch.pdf - Úplné schéma MO_KBD3 včetně možnosti osazení MCU pro přístup přes sběrnici CAN}} {{courses:A0B36APO:tutorials:10:mo_kbd3-top.pdf|mo_kbd3-top.pdf - Osazovací výkres - horní strana}} {{courses:A0B36APO:tutorials:10:mo_kbd3-bot.pdf|mo_kbd3-bot.pdf - Osazovací výkres - spodní strana}} ==== Dokumentace k desce napěťového přispůzobení a nosiče konektorů CON-DB4CGX15 ==== {{courses:A0B36APO:tutorials:10:con-db4cgx15-sch.pdf|con-db4cgx15-sch.pdf - Schéma propojovací desky CON-DB4CGX15}} {{courses:A0B36APO:tutorials:10:con-db4cgx15-top.pdf|con-db4cgx15-top.pdf - Osazovací výkres - horní strana}} {{courses:A0B36APO:tutorials:10:con-db4cgx15-bot.pdf|con-db4cgx15-bot.pdf - Osazovací výkres - spodní strana}} ===== Dokumentace k FPGA návrhu pro softwarovou simulaci 8-bit sběrnice (mmaped_8bit_bus) ===== {{courses:A0B36APO:tutorials:10:mmaped_8bit_bus-toplevel.pdf|mmaped_8bit_bus-toplevel.pdf - Nejvyšší úroveň návrhu propojení PCIe subsytému, registrů a pinů FPGA}} {{courses:A0B36APO:tutorials:10:mmaped_8bit_bus-sopc-avalon.pdf|mmaped_8bit_bus-sopc-avalon.pdf - Propojení registrů a PCIe na sběrnici Avalon v SW Altera SOPC Builder}} [[courses:A0B36APO:tutorials:10:sopc_builder_pcie:start|Konfigurace generátoru PCIe bloku v SW Altera SOPC Builder PCI Compiler]] ====== Virtuální hardware klávesnice (APOHW) pro emulátor QEMU ====== Na úloze je možné pracovat i bez přístupu k vlastnímu HW. Virtuální hardware pro předmět APO byl implementovaný Rostislavem Lisovým na základě jeho předchozí diplomové práce [[http://rtime.felk.cvut.cz/hw/index.php/Humusoft_MF6xx|Prostředí pro výuku vývoje PCI ovladačů do operačního systému GNU/Linux]]. Podrobné informace k projektu APOHW se nacházejí na stránce [[http://rtime.felk.cvut.cz/hw/index.php/A0B36APO_Virtual_Hardware|Virtuální hardware APOHW v QEMU]] Aktuální verze implementuje zápis na LED diody, výpis na display a zjednodušené zpracování klávesnice. Klávesa stlačená a odeslaná programem TELNET nastaví propojení křížení sloupce a řádku pro odpovídající klávesu '0' až '9', '*' a '.'. Veškeré propoje v matici jsou pak smazané po přijetí znaku/klávesy mezera (' '). Stav klávesnice a displeje je uživateli zprostředkovaný přes jednoduchý telnet server, který naslouchá na portu 55555. Připojit se lze příkazem ''telnet localhost 55555'' Upozornění: Projekt musí být při odevzdání funkční i na fyzickém hardware. Virtuální HW slouží především k testování základního návrhu a SW s tím, že požadavky na časování i některé funkce neimplementuje zcela přesně. Kompletní virtuální systém s implementovaným hardwarem APOHW. {{courses:A0B36APO:tutorials:10:qemu-run-apohw-32.tar.gz|qemu-run-apohw-32.tar.gz}} (32-bit GNU/Linux verze) {{courses:A0B36APO:tutorials:10:qemu-run-apohw-64.tar.gz|qemu-run-apohw-64.tar.gz}} (64-bit GNU/Linux verze) Základem je QEMU s rozšířením o HW, jádro systému Linux, BusyBox a další výbava pro spuštění. Spustitelný soubor QEMU je zkompilovaný pro 32-bitovou verzi systému Linux. K běhu programu sestavení emulátoru "qemu-system-i386-apohw" jsou potřeba ROM obrazy základního a grafického BIOSu pro počítačový systém PC. V distribuci Debian a Ubuntu se instalují s balíčekem "qemu-system" jako jeho závislosti. Pro zjednodušení instalace byly obrazy ROM přibaleny i do archivu. Cesta k lokální kopii je ve skriptu "qemu-run-apohw" specifikovaná parametrem přepínače "-L". Po spuštění příkazu "qemu-run-apohw" dojde k vytvoření virtuálního stroje s architekturou PC. Přepínač "-device apohw" specifikuje, že má být doplněný o jednu instanci emulace PCIe karty odpovídající APO hardware. Přepínač "-kernel vmlinuz-3.2.0-2-686-pae" zajistí přímé natažení jádra systému Linux (k tomu je využit option ROM "linuxboot.bin"). Přepínač "-initrd ramdisk.cpio" specifikuje, že po startu systému je do dočasného/RAM filesystému tmpfs rozbalený obsah GZIP komprimovaného CPIO archivu "ramdisk.cpio". Tento archiv je ze souborů v adresáři "rootfs" a popisu zařízení vytvořen příkazem "mkramdisk-apohw". Potřebné nástroje k úpravám jsou součástí archivu. Po rozbalení archivu jádrem Linux do paměti je předáno řízení programu "linuxrc", případně "/bin/init". Tento program interpretuje shellový skript "/etc/init.d/rcS". Součástí skriptu je vytvoření spojení jádra OS Linux s hypervisorem QEMU na úrovni protokolu [[http://en.wikipedia.org/wiki/9P|9P]]. Přes tento protokol je pak do virtuálního systému do adresáře "/mnt/shareddir" připojen vnější adresář "shareddir" z hostitelského systému. V něm jsou předpřipravené nástroje "rdwrmem" a "apohw/mmaped_8bit_bus_kbd". Alternativou je připojit do QEMU CDROM některé z distribucí GNU/Linuxu a na připojený obraz disku nainstalovat celý systém. ''./qemu-system-i386-apohw -L pc-bios -boot c -hda file-to-emulate-hd -cdrom install.iso'' Emulátor je nainstalovaný i na virtuální stanici/serveru ''postel''. Zde je sdílený adresář mapovaný do domovského adresáře uživatele na ~/apo/shareddir . Emulátor je možné pustit vzdáleně v grafickém režimu po protunelování X protokolu přes ssh ssh -X qemu-run-apohw Alternativou je spuštění emulátoru v textovém režimu, kdy textový režim grafické karty překládá na ncurses příkazy textové konsole qemu-run-apohw -curses Další možnost je grafický výstup zcela vypnout a přesměrovat výstup Linuxového jádra a shellu na virtuální sériový port qemu-run-apohw -nographic -append "console=ttyS0" Emulátor se pak ovládá příkazy pře ''CTRL+A''. Seznam příkazů ''CTRL+A h''. Vypnutí ''CTRL+A x''. Při spuštění více instancí emulátoru na serveru postel nastane kolize v telnet portu pro přístup k displeji. Lze to řešit nastavením vlastního portu v parametrech emulátoru. Další informace o možnostech práce s QEMU lze nalézt na mnoha místech. Z našich předmětů a projektů například v [[http://rtime.felk.cvut.cz/osp/cviceni/2/|A4M35OSP]], [[https://support.dce.felk.cvut.cz/mediawiki/index.php/Kategorie:QEMU|Stránky IT podpory K13135]], atd.