www.eprace.edu.pl » rejestrowanie-multimediow » Program wykonywany przez mikroprocesor sygnałowy » Procedury obsługi interfejsu sieciowego

Procedury obsługi interfejsu sieciowego

Fragmenty programu odpowiedzialne za obsługę układu W3100A zostały napisane w oparciu o zestaw funkcji Socket API napisanych w języku C, dostarczony przez producenta tego układu.

Inicjalizacja układu W3100A

Pierwszą procedurą dotyczącą układu interfejsu sieciowego wykonywaną po uruchomieniu rejestratora jest inicjalizacja tego układu. Nie jest ona wykonywana przez główny program dla procesora DSP, ale przez program boot_4.asm odpowiedzialny za ładowanie programu głównego, opisany w podrozdziale 7.5. Inicjalizacja składa się z ustawienia następujących rejestrów układu W3100A:

Ponieważ wykorzystywany będzie tylko kanał 0, rejestry RMSR i TMSR zostają ustawione w sposób oznaczający przydzielenie całej dostępnej pamięci (po 8kB dla odbioru i nadawania) dla kanału 0. Po ustawieniu w/w rejestrów procesor wydaje polecenie SYS_INIT, korzystając z rejestru poleceń kanału 0 (C0_CR). Następnie procesor czeka na potwierdzenie wykonania inicjalizacji przez układ W3100A, polegające na ustawieniu odpowiedniego bitu w rejestrze przerwań (IR) oraz w rejestrze statusowym kanału 0 (C0_ISR). Nie zostały tu wykorzystane przerwania, ale odpytywanie (ang. polling). Po stwierdzeniu właściwych wartości w w/w rejestrach procesor zapisuje do rejestru IR bajt, w którym bit odpowiadający danemu przerwaniu jest równy 1. Jest to sygnałem dla układu W3100A, że przerwanie zostało obsłużone.

Otwarcie gniazda

Przed wykonaniem transmisji danych wymagane jest otwarcie tzw. gniazda (ang. socket). Podobnie jak inicjalizacja układu W3100A, jest to wykonywane w programie boot_4.asm. Do tego celu konieczne jest ustawienie następujących rejestrów:

Po ustawieniu tych rejestrów procesor wydaje polecenie SOCK_INIT, czeka na jego potwierdzenie i sygnalizuje obsłużenie przerwania w sposób analogiczny jak to miało miejsce przy poleceniu SYS_INIT. Otwierane jest gniazdo w kanale 0. Pozostałe kanały nie są wykorzystywane przez rejestrator.

Na powyższej liście nie znalazły się rejestry odpowiedzialne za adres i port docelowy (czyli po stronie komputera), ponieważ nie są one znane w momencie włączania urządzenia. Dane te otrzymuje urządzenie wraz z odebraniem pierwszego pakietu. W związku z tym, po jego odbiorze następuje zamknięcie gniazda (poleceniem CLOSE), po czym ustawiane są rejestry C0_DIR i C0_DPR – odpowiednio docelowy adres IP i port. Następnie procesor powtórnie wydaje polecenie SOCK_INIT.

Nadawanie danych

Pierwszą czynnością wykonywaną przed nadaniem danych przez układ W3100A jest sprawdzenie, czy poprzednia operacja nadawania została zakończona i ewentualne oczekiwanie na jej zakończenie. W tym celu sprawdzany jest odpowiedni bit w rejestrze poleceń kanału 0 (C0_CR). Następnie program dokonuje sprawdzenia, czy w buforze nadawczym układu W3100A jest wystarczająca ilość wolnej pamięci. Wymaga to odczytania wskaźnika zapisu (C0_TW_PR) oraz odczytu (C0_TR_PR) bufora nadawczego.

Ponieważ wskaźniki te są 32-bitowe, ich odczyt przez 8-bitową szynę wymaga czterech oddzielnych transferów, co stwarza potencjalny problem w przypadku, gdy zawartość rejestru zmieni się pomiędzy odczytami kolejnych jego bajtów. Z tego względu stosuje się specjalny mechanizm odczytu 32-bitowych wskaźników. Polega on na tym, że przed odczytaniem danego wskaźnika należy odczytać odpowiadający mu tzw. rejestr cienia. Zawartość tego rejestru jest nieistotna, a jego odczyt służy jedynie do poinformowania układu W3100A, że dany wskaźnik będzie odczytywany. Po odczytaniu rejestru cienia wskaźnik zostaje skopiowany do pomocniczego rejestru, z którego może być bezpiecznie odczytany. Pomiędzy odczytem rejestru cienia, a odczytem wskaźnika wymagany jest odstęp 1,6µs, co zapewnia podprogram Wait1_6us. Taki sposób postępowania dotyczy zarówno wskaźników do bufora nadawczego, jak i odbiorczego.

Po odczytaniu wskaźnika zapisu i odczytu są one odejmowane, aby wyliczyć ilość zajętego miejsca w buforze. Oczywistym jest, że ilość wolnego miejsca jest różnicą pomiędzy wielkością bufora (8kB) i ilością miejsca zajętego. Jeżeli program stwierdzi, że w buforze nie ma wystarczającej ilości miejsca, powtarza on odczyty wskaźników aż do uzyskania pozytywnego rezultatu.

Wskaźnik zapisu nie zawiera bezpośredniej informacji o adresie, pod który należy zapisywać dane. Aby ten adres uzyskać, program oblicza resztę z dzielenia tego wskaźnika przez długość bufora (8kB) i dodaje do niej adres początkowy bufora (stała W_TX_BUF).

Następnie wpisywane są dane do wysłania, poczynając od obliczonego w ten sposób adresu i inkrementując go za każdym zapisanym bajtem. Bufor nadawczy ma organizację bufora cyklicznego, co nie stanowi utrudnienia, ponieważ DSP został wyposażony w tryb adresowania modulo. Ze względu na podłączenie szyny danych układu W3100A do linii D7-D0 procesora wymagane jest zapisywanie danych w takiej postaci, aby istotny bajt zawarty był w 8 najmłodszych bitach słowa. Pociąga to za sobą konieczność przesuwania bitowego danych przechowywanych w innym formacie.

Po zapisaniu całego datagramu do bufora nadawczego ustawiana jest nowa wartość wskaźnika zapisu (C0_TW_PR), równa jego poprzedniej wartości zwiększonej o liczbę zapisanych bajtów. Zapisywanie wskaźnika nie wymaga wykorzystania rejestru cienia.

Procedurę nadawania kończy wydanie polecenia SEND poprzez ustawienie odpowiedniego bitu w rejestrze C0_CR.

Odbiór danych

Odbiór danych w zasadniczym programie odbywa się w przerwaniu IRQ A, obsługiwanym przez podprogram recv_i. Odbiór w programie boot_4.asm odbywa się bez wykorzystania przerwań, poprzez ciągłe sprawdzanie stanu rejestru IR. Pierwszą czynnością po wejściu do przerwania lub po stwierdzeniu ustawienia odpowiedniego bitu rejestru IR jest wpisanie do tego rejestru bajtu z odpowiednim bitem równym 1, co spowoduje wyzerowanie tego rejestru i wycofanie sygnału przerwania. Umożliwi to ponowną sygnalizację gotowości danych do odbioru przez układ W3100A.

W następnej kolejności odczytywany jest 32-bitowy wskaźnik odczytu bufora odbiorczego kanału 0 (C0_RR_PR). Wymaga to uprzedniego odczytu odpowiedniego rejestru cienia (zastosowanie rejestrów cieni zostało opisane w podrozdziale 7.3.3). W celu określenia adresu, z którego należy odczytać odebrane dane, wyznaczana jest reszta z dzielenia tego wskaźnika przez długość bufora odbiorczego (8kB), a następnie jest ona dodawana do adresu początkowego bufora W_RX_BUF.

Pod znalezionym adresem znajdują się dane opatrzone 8-bajtowym nagłówkiem, składającym się z następujących pól:

Program w pierwszej kolejności odbiera dwa początkowe bajty określające długość danych i dodaje je do wskaźnika odczytu. Suma ta, wskazująca koniec pakietu, zostaje przechowana tymczasowo pod adresem x:wiz_ptr (dwa słowa w pamięci, ponieważ jest to wartość 32-bitowa). Następnie odczytana zostaje wartość wskaźnika zapisu do bufora odbiorczego (C0_RW_PR) i jest ona porównywana z wyznaczonym poprzednio wskaźnikiem końca pakietu. Jeżeli wskaźnik zapisu ma wartość mniejszą niż wskaźnik końca pakietu, znaczy to, że cały pakiet nie został jeszcze odebrany, wobec czego procedura odbioru zostaje porzucona i następuje powrót z przerwania. W przeciwnym wypadku dane są gotowe do odbioru.

Wówczas program zmniejsza odebraną długość pakietu o 2, uwzględniając w ten sposób fakt, że już zostały odebrane 2 bajty – właśnie pole zawierające tę długość, i dodaje ją do rejestru przechowującego adres następnego bajtu do odebrania, uzyskując w ten sposób adres końca pakietu.

W przypadku odbioru pierwszego pakietu po włączeniu urządzenia (w programie boot_4.asm opisanym w podrozdziale 7.5) następnym krokiem jest odczyt adresu IP oraz portu używanego przez komputer. Przy odbiorze kolejnych pakietów dane te są pomijane na podstawie założenia, że tylko dany komputer będzie wysyłał datagramy UDP do rejestratora.

Potem rozpoczyna się właściwy odbiór danych wykonywany w pętli. Kolejne trójki odbieranych bajtów składane są w słowa 24-bitowe w ten sposób, że pierwszy bajt z danej trójki staje się najmłodszym bajtem słowa. Wiąże się z tym format ramek przesyłanych z komputera do rejestratora, złożonych z bloków po 3 bajty przenoszących elementarne informacje. Do składania słów z bajtów wykorzystywane są zasadniczo 2 rejestry:


Rys. 7.3. Schemat blokowy pętli odbioru danych w procedurze recv_i


Poza tym procedura odbioru w programie głównym dsp.asm posługuje się rejestrem R2 jako wskaźnikiem do zapisu odebranych słów do pamięci, a w programie boot_4.asm jest to rejestr R1. Dane gromadzone są w buforze odbiorczym pod adresem y:rcv_in w przypadku programu głównego, a w pamięci P pod wskazanym w pierwszym pakiecie adresem początkowym w przypadku programu boot_4.asm. Działanie pętli odbioru danych w programie głównym wraz z warunkami jej zakończenia zostało przedstawione na rysunku 7.3. W programie boot_4.asm działanie pętli jest podobne, z tym że warunek zakończenia po odebraniu 4 lub 9 słów jest zastąpiony przez warunek odebrania liczby słów wskazanej w pierwszym pakiecie.

Jak widać, istnieją dwie możliwości zakończenia odbioru danych: gdy została odebrana pełna ramka informacji lub gdy skończył się datagram UDP. Druga sytuacja dotyczy przypadku segmentacji datagramu. Wówczas kolejny jego segment zostanie odebrany w następnym przerwaniu odbioru. Segmentacja może nastąpić w dowolnym miejscu datagramu, a więc w szczególności pomiędzy bajtami które należy poskładać w jedno słowo. Aby w tej sytuacji możliwe było prawidłowe poskładanie całej ramki danych, rejestry robocze pętli odbioru są po jej zakończeniu przechowywane w zarezerwowanych na ten cel komórkach pamięci x:rcv_byt, x:rcv_wor, x:rcv_ptr.

Po opuszczeniu pętli odbioru w którykolwiek ze sposobów następuje zapisanie nowej wartości wskaźnika odczytu, przechowywanej pod adresem x:wiz_ptr, do rejestru C0_RR_PR oraz wydanie polecenia RECV. Jeżeli została odebrana cała ramka danych, to w przypadku programu głównego dsp.asm zostaje ona obsłużona w sposób opisany w podrozdziale 7.2.2. W przypadku programu boot_4.asm moment ten jest końcem odbioru danych, po czym następuje uruchomienie załadowanego programu głównego.

W przypadku programu boot_4.asm moment wydania polecenia RECV kończy procedurę odbioru danych. Początkowa wersja zakładała również takie postępowanie w przypadku programu głównego, ale skutkiem tego było nieodbieranie ramek, które przychodziły do rejestratora w czasie wykonywania procedury odbioru. W związku z tym wprowadzono powtórzenie całej procedury, począwszy od sprawdzenia czy w buforze odbiorczym układu W3100A znajduje się cały pakiet, stosując zaktualizowaną wartość wskaźnika odczytu C0_RR_PR (skok do etykiety rcstart). Niespełnienie tego warunku powoduje zakończenie procedury obsługi przerwania recv_i.



komentarze

Copyright © 2008-2010 EPrace oraz autorzy prac.