36PZ - USB (úloha D)

Jindřich Gottwald (j.gottwald@sh.cvut.cz)
Jan Karabina (karabij@feld.cvut.cz)

1 Zadání

Cílem této úlohy je prostudovat mechanismus práce USB a napsat program, který bude přijímat data z této sběrnice.Práce bude probíhat pod OS GNU/Linux.

  1. zprovoznit SW pro přístup na sběrnici
  2. přečíst údaje o jednotlivých zařízeních
  3. identifikovat obsah přijímaných datových paketů
Zadání:

V operaním systému Linux existuje subsystém jádra pro práci s USB, který má usnadnit psaní ovlada zaízení. Nám vsak bude pro seznámení s USB slouzit knihovna libusb, která nám umozní snadno dlat základní funkce, jako je inicializace sbrnice, vyhledávání zaízení a odesílaní a píjem dat. Zdrojové kódy knihovny najdeme na adrese [1]. Podle pilozených instrukcí knihovnu zkompilujeme a nainstalujeme do systému. Peliv si prostudujeme ukázkový program testlibusb.c v adresái tests. Ve specifikaci USB (na adrese [2]) vyhledáme oddíl o popisovaích a seznámíme se s polozkami popisovae zaízení, sestavení, rozhraní a s vlastnostmi koncového bodu. Spustíme program testlibusb, který nám vypíse USB zaízení v systému. Podle specifikace zjistíme vlastnosti jednotlivých zaízení a v tabulce výrobc a zaízení [3] si najdeme, jaká zaízení v systému máme. Zapíseme si kolik má které zaízení mozných sestavení, rozhraní a koncových bod. Na adrese [4] mzeme vyhledat, jaké jsou tídy jednotlivých rozhraní. Najdeme si jedno zaízení, které nám poskytne data v rezimu interrupt a napíseme program, který bude tato data píjmat.

Teorie k měření viz [2].

2 postup měření

pří psaní testovacího programu vyjdeme z testlibusb.c z balíku libusb viz libusb.sf.net

Dokumentaci k funkcím nalezneme bu na adrese [5], nebo v podadresái doc balíku libusb. Pro zápis na zaízení je teba superuzivatelská práva. Rozhraní je ped tením nutno vybrat pomocí funkce usb_claim_interface. Pokud se se zaízením nepracuje, vrací pokus o tení chybu. Bereme v úvahu kolik dat zaízení produkuje a jak asto. Data vypisujeme pehledn na obrazovku. K zjistní jaká chyba nastala pi posledním volání njaké funkce slouzí funkce perror("..").

2.1 Osnova programu:

2.2 Úkoly:

2.3 Poznámka:

Vzhledem k autokonfiguraci a hotplugu se prbzn zavádí ovladae mousedev a hid. Jejich zavedení lze kontrolovat pomocí píkazu lsmod a odstranit pomocí píkazu rmmodu. Zárove je teba bootovat bez USB mysi a tu zapojit az po startu, aby její ovlada nevyuzil X server. Vtsina operací vyzaduje administrátorská práva. Muzete je získat píkazem su. Pípadn je nakonfigurováno i sudo.

/*

 * testlibusb.c

 *

 *  Test suite program

 */

#include <stdio.h>

#include <string.h>

#include <usb.h>

int verbose = 0;

void print_endpoint(struct usb_endpoint_descriptor *endpoint)

{

  printf("      bEndpointAddress: %02xh\n", endpoint->bEndpointAddress);

  printf("      bmAttributes:     %02xh\n", endpoint->bmAttributes);

  printf("      wMaxPacketSize:   %d\n", endpoint->wMaxPacketSize);

  printf("      bInterval:        %d\n", endpoint->bInterval);

  printf("      bRefresh:         %d\n", endpoint->bRefresh);

  printf("      bSynchAddress:    %d\n", endpoint->bSynchAddress);

}

void print_altsetting(struct usb_interface_descriptor *interface)

{

  int i;

  printf("    bInterfaceNumber:   %d\n", interface->bInterfaceNumber);

  printf("    bAlternateSetting:  %d\n", interface->bAlternateSetting);

  printf("    bNumEndpoints:      %d\n", interface->bNumEndpoints);

  printf("    bInterfaceClass:    %d\n", interface->bInterfaceClass);

  printf("    bInterfaceSubClass: %d\n", interface->bInterfaceSubClass);

  printf("    bInterfaceProtocol: %d\n", interface->bInterfaceProtocol);

  printf("    iInterface:         %d\n", interface->iInterface);

  for (i = 0; i < interface->bNumEndpoints; i++)

    print_endpoint(&interface->endpoint[i]);

}

void print_interface(struct usb_interface *interface)

{

  int i;

  for (i = 0; i < interface->num_altsetting; i++)

    print_altsetting(&interface->altsetting[i]);

}

void print_configuration(struct usb_config_descriptor *config)

{

  int i;

  printf("  wTotalLength:         %d\n", config->wTotalLength);

  printf("  bNumInterfaces:       %d\n", config->bNumInterfaces);

  printf("  bConfigurationValue:  %d\n", config->bConfigurationValue);

  printf("  iConfiguration:       %d\n", config->iConfiguration);

  printf("  bmAttributes:         %02xh\n", config->bmAttributes);

  printf("  MaxPower:             %d\n", config->MaxPower);

  for (i = 0; i < config->bNumInterfaces; i++)

    print_interface(&config->interface[i]);

}

int print_device(struct usb_device *dev, int level)

{

  usb_dev_handle *udev;

  char description[256];

  char string[256];

  int ret, i;

  udev = usb_open(dev);

  if (udev) {

    if (dev->descriptor.iManufacturer) {

      ret = usb_get_string_simple(udev, dev->descriptor.iManufacturer, string, sizeof(string));

      if (ret > 0)

        snprintf(description, sizeof(description), "%s - ", string);

      else

        snprintf(description, sizeof(description), "%04X - ",

                 dev->descriptor.idVendor);

    } else

      snprintf(description, sizeof(description), "%04X - ",

               dev->descriptor.idVendor);

    if (dev->descriptor.iProduct) {

      ret = usb_get_string_simple(udev, dev->descriptor.iProduct, string, sizeof(string));

      if (ret > 0)

        snprintf(description + strlen(description), sizeof(description) -

                 strlen(description), "%s", string);

      else

        snprintf(description + strlen(description), sizeof(description) -

                 strlen(description), "%04X", dev->descriptor.idProduct);

    } else

      snprintf(description + strlen(description), sizeof(description) -

               strlen(description), "%04X", dev->descriptor.idProduct);

  } else

    snprintf(description, sizeof(description), "%04X - %04X",

             dev->descriptor.idVendor, dev->descriptor.idProduct);

  printf("%.*sDev #%d: %s\n", level * 2, "                    ", dev->devnum,

         description);

  if (udev && verbose) {

    if (dev->descriptor.iSerialNumber) {

      ret = usb_get_string_simple(udev, dev->descriptor.iSerialNumber, string, sizeof(string));

      if (ret > 0)

        printf("%.*s  - Serial Number: %s\n", level * 2,

               "                    ", string);

    }

  }

  if (udev)

    usb_close(udev);

  if (verbose) {

    if (!dev->config) {

      printf("  Couldn't retrieve descriptors\n");

      return 0;

    }

    for (i = 0; i < dev->descriptor.bNumConfigurations; i++)

      print_configuration(&dev->config[i]);

  } else {

    for (i = 0; i < dev->num_children; i++)

      print_device(dev->children[i], level + 1);

  }

  return 0;

}

int main(int argc, char *argv[])

{

  struct usb_bus *bus;

  if (argc > 1 && !strcmp(argv[1], "-v"))

    verbose = 1;

  usb_init();

  usb_find_busses();

  usb_find_devices();

  for (bus = usb_busses; bus; bus = bus->next) {

    if (bus->root_dev && !verbose)

      print_device(bus->root_dev, 0);

    else {

      struct usb_device *dev;

      for (dev = bus->devices; dev; dev = dev->next)

        print_device(dev, 0);

    }

  }

  return 0;

}

3 Výsledky

Bibliography

1
Miroslav Šnorek: Periferní zařízení, Vydavatelství ČVUT, Praha 2002

2
Webové stránky předmětu http://service.felk.cvut.cz/courses/36PZ/

3
MFM and RLL encoding http://www.wtysoft.com/ataref.htm

4
http://libusb.sourceforge.net/

5
http://www.usb.org/developers/docs/

6
http://www.linux-usb.org/usb.ids

7
http://www.xat.nl/en/riscos/sw/usb/class.htm

8
http://libusb.sourceforge.net/doc/



Jan Karabina (karabij@feld.cvut.cz)