Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Aby użyć niektórych możliwości sprzętowych połączonego urządzenia peryferyjnego SPB, klient kontrolera SPB (czyli sterownik peryferyjny) może wymagać wykonania sekwencji transferów danych do i z urządzenia jako operacji magistrali atomowej. Sekwencja transferu jest niepodzielna, ponieważ żaden inny klient nie może przesyłać danych do lub z urządzenia w magistrali do momentu zakończenia sekwencji.
Zwyczajnym sposobem wykonania sekwencji transferu przez klienta jako niepodzielnej operacji magistrali jest wysłanie żądania IOCTL_SPB_EXECUTE_SEQUENCE do urządzenia docelowego. W tym żądaniu klient określa sekwencję jako listę prostych transferów odczytu i zapisu. Lista może mieć dowolną długość. Odczyty i zapisy są wykonywane w kolejności, w której są wymienione, a każdy odczyt lub zapis może przenieść dowolną liczbę bajtów. Większość kontrolerów SPB obsługuje żądania IOCTL_SPB_EXECUTE_SEQUENCE .
Zabezpieczenia kontrolera SPB
Rzadziej używanym sposobem wykonywania sekwencji transferu niepodzielnego jest użycie blokady kontrolera SPB. Klient wysyła żądanie IOCTL_SPB_LOCK_CONTROLLER w celu uzyskania blokady, a żądanie IOCTL_SPB_UNLOCK_CONTROLLER zwolnienia blokady. Gdy klient przechowuje blokadę sterownika, każda sekwencja prostego odczytu i zapisu (IRP_MJ_READ i IRP_MJ_WRITE), które klient wysyła do urządzenia, są wykonywane jako operacja niepodzielna na magistrali.
Większość urządzeń peryferyjnych połączonych z SPB nie wymaga blokad kontrolera, a większość sterowników kontrolera SPB nie implementuje wsparcia dla tych blokad. Jednak kilku klientów może wymagać użycia blokad kontrolera w celu uzyskania dostępu do urządzeń, które mają nietypowe funkcje.
Na przykład urządzenie może implementować funkcje urządzenia, do których można uzyskiwać dostęp tylko za pomocą operacji odczytu-modyfikacji-zapisu, które są atomowe na magistrali. Aby wykonać taką operację, klient wysyła następujące cztery żądania we/wy (w podanej kolejności):
- IOCTL_SPB_LOCK_CONTROLLER — uzyskaj blokadę kontrolera.
- IRP_MJ_READ — odczyt bloku danych z urządzenia docelowego.
- IRP_MJ_WRITE — zapisz zmodyfikowane dane z powrotem na urządzeniu.
- IOCTL_SPB_UNLOCK_CONTROLLER — zwolnij blokadę kontrolera.
Po operacji odczytu na powyższej liście klient interpretuje dane odczytane z urządzenia i modyfikuje dane przed zapisaniem ich z powrotem na urządzeniu.
Jednak niewiele urządzeń połączonych z SPB ma funkcje wymagające blokad kontrolera. W przypadku większości urządzeń, które wymagają wykonywania operacji magistrali atomowej, żądania IOCTL_SPB_EXECUTE_SEQUENCE są wystarczające.
Nie należy mylić blokad kontrolera SPB z blokadami połączenia SPB. W nietypowym przypadku, w którym dwóch klientów współużytkuje dostęp do tego samego urządzenia peryferyjnego połączonego z usługą SPB, klient może użyć blokady połączenia, aby tymczasowo uzyskać wyłączny dostęp do urządzenia. Aby uzyskać więcej informacji, zobacz Blokady połączeń SPB.
Sygnały magistrali sprzętowej
Aby obsłużyć żądanie IOCTL_SPB_EXECUTE_SEQUENCE , sterownik kontrolera SPB konfiguruje sprzęt kontrolera w celu wygenerowania odpowiednich sygnałów w magistrali podczas sekwencji transferu. Urządzenia peryferyjne dołączone do magistrali mogą polegać na tych sygnałach w celu wykrycia, kiedy trwa operacja magistrali atomowej. Zestaw sygnałów sprzętowych używanych przez kontroler SPB do wykonywania sekwencji transferu jako operacja magistrali niepodzielnej zależy od typu magistrali.
W przypadku magistrali I2C kontroler uruchamia sekwencję, przesyłając bit startowy w magistrali i kończy sekwencję przez przesyłanie bitu zatrzymania. Między bitami uruchamiania i zatrzymywania sekwencja transferów danych do i z urządzenia jest wykonywana jako pojedyncza operacja magistrali atomowej. Z wyjątkiem końcowego transferu w sekwencji, po każdym transferze następuje operacja restartu I2C (powtórzony bit rozpoczynający, który nie jest poprzedzony bitem zatrzymania).
W przypadku magistrali SPI kontroler uruchamia sekwencję, aktywując linię wyboru mikroukładu do urządzenia docelowego i kończy sekwencję, dezaktywując linię wyboru mikroukładu. Utrzymując linię wyboru mikroukładu w sposób ciągły w trakcie sekwencji transferów danych przez magistralę, transfery są wykonywane jako pojedyncza, niepodzielna operacja magistrali.
Przykładowe urządzenie I2C
Typowe urządzenie peryferyjne w magistrali I2C może implementować kilka funkcji urządzenia wewnętrznego. Aby uzyskać dostęp do niektórych z tych funkcji, klient może używać IOCTL_SPB_EXECUTE_SEQUENCE żądań.
Na przykład urządzenie peryferyjne I2C może zawierać następujące dwa rejestry wewnętrzne:
- Rejestr funkcji, do którego klient zapisuje wewnętrzny adres funkcji urządzenia w celu uzyskania dostępu.
- Rejestr danych, za pomocą którego klient odczytuje dane z lub zapisuje dane na określony adres funkcji.
Urządzenie peryferyjne I2C w tym przykładzie interpretuje pierwszy bajt zapisany na urządzeniu po bitzie startowym jako adres funkcji do załadowania do rejestru funkcji. Wszelkie dodatkowe bajty przesyłane do lub z urządzenia przed zakończeniem sekwencji (wskazane przez bit zatrzymania) są traktowane przez urządzenie jako dane przesyłane za pośrednictwem rejestru danych.
Aby wykonać operację zapisu, klient wysyła żądanie zapisu (IRP_MJ_WRITE), w którym pierwszy bajt w buforze zapisu jest adresem funkcji, a pozostałe bajty w buforze są danymi, które mają być zapisywane w adresie funkcji.
Odczytywanie z urządzenia jest bardziej skomplikowane. Załóżmy, że urządzenie I2C w tym przykładzie obsługuje funkcję "szybkiego odczytu", która automatycznie resetuje rejestr adresu funkcji do wartości domyślnej, 0, po wykryciu bitu zatrzymania w magistrali. Dzięki tej funkcji klient może odczytać dane z adresu funkcji 0 bez konieczności wcześniejszego zapisywania w rejestrze adresów funkcji. Ta funkcja może zwiększyć szybkość operacji odczytu urządzenia, zwłaszcza jeśli większość operacji odczytu pochodzi z adresu funkcji 0 i jest stosunkowo krótka.
Jednak aby odczytać blok danych z adresu funkcji innego niż zero, klient nadal musi zapisać bajt w rejestrze adresów funkcji przed odczytaniem bloku danych z rejestru danych. Klient musi wykonać te transfery zapisu i odczytu jako operację magistrali atomowej, aby uniemożliwić kontrolerowi magistrali przesyłanie bitu zatrzymania po zapisie do rejestru funkcji i przed odczytem z rejestru danych. W przeciwnym razie bit zatrzymania spowoduje, że dane będą odczytywane z adresu funkcji 0 zamiast z adresu funkcji niezerowej.
Poniższa lista zawiera opis serii żądań wejścia/wyjścia wysyłanych przez klienta do urządzenia I2C w tym przykładzie w celu wykonania operacji typu odczytu modyfikuj-zapisu na danych znajdujących się pod niezerowym adresem funkcji w urządzeniu.
- IOCTL_SPB_EXECUTE_SEQUENCE — przeprowadź sekwencję transferu I/O, aby odczytać dane z urządzenia. Pierwszy transfer w tej sekwencji to zapis bajtowy w rejestrze adresów funkcji. Drugi transfer w sekwencji to odczyt pewnej liczby bajtów z wybranego adresu funkcji. Te dwa transfery są wykonywane niepodziealnie w autobusie.
- IRP_MJ_WRITE — zapisywanie danych na urządzeniu. Pierwszy bajt w buforze zapisu dla tego żądania jest wartością, którą należy zapisać w rejestrze adresów funkcji. Pozostałe bajty w buforze to dane do zapisu na wybranym adresie funkcji.
Zamiast tego można użyć innych wzorców żądań do wykonania tej operacji odczytu-modyfikowania-zapisu. Na przykład żądanie IRP_MJ_WRITE w kroku 2 można zastąpić żądaniem IOCTL_SPB_EXECUTE_SEQUENCE określającym dwa transfery danych, z których oba są zapisami. Pierwszy transfer w sekwencji ładuje bajt do rejestru adresów funkcji. Drugi transfer zapisuje bajty danych na wybrany adres funkcji. To żądanie, w przeciwieństwie do żądania IRP_MJ_WRITE w kroku 2, nie wymaga od klienta połączenia bajtów adresu funkcji i bajtów danych w tym samym buforze zapisu.
Aby wykonać operację odczyt-modyfikacja-zapis na adresie funkcji 0 tego urządzenia, w kroku 1 poprzedniej listy żądanie IOCTL_SPB_EXECUTE_SEQUENCE można zastąpić prostym żądaniem odczytu (IRP_MJ_READ).