Come si dialoga con il device USB?

So perfettamente che l’argomento non è direttamente inerente con Arduino, tuttavia nella forum internazionale c’è posto per discutere di questo argomento.

Non ho l’esperienza per dialogare direttamente con il device USB, ma qualcosa l’ho fatta.

Un device USB connesso al pc dovrebbe essere gestito da un modulo del kernel a cui un programma si collega tramite un device file messo a disposizione sotto la dir /dev. Tuttavia alcuni device usb non hanno un modulo del kernel es il programmatore USB AVRISP mkii, infatti questo viene gestito da avrdude tramite la libreria usblib ver 0.1, di questa c’è la versione ultima 1.0 da questa è stato fatto un fork chiamato openusb che astrae tutto e fornisce supporto alle diverse piattaforme tramite back-end.

Il progetto openusb è thread-safe, permette la gestione e il dialogo con il device in modo esteso, lavora su Mac, linux, bsd ed è stato annunciato lo sviluppo del back-end per windows.

Io sto usando openusb per connettermi al programmatore usb AVRISP mkii, solo che ancora non ho fatto transizione dati, perchè il protocollo usb è molto complesso.

L’accesso alla libreria si ottiene tramite l’unico header openusb.h

#include <openusb.h>

La prima cosa da fare è inizializzare la libreria con:

        openusb_handle_t libhandle;  // typedef uint64_t openusb_handle_t; /* every openusb instance has a lib handle */ 
        int ret;
	uint32_t flags = 0;
	ret = openusb_init(flags, &libhandle);
	if(ret < 0) {
		printf("error init: %s (%d)\n", openusb_strerror(ret), ret);
		exit(1);
	}

flasg non viene utilizzato per questo viene posto a 0.

Tutte le funzioni ritornano 0 su successo <0 in caso di errore, openusb_strerror(ret) ritorna un char * contenente la descrizione dell’errore.

Dopo si può impostare il timeout di default che dovrebbe essere utile sono nel caso di comunicazione con il device in polling.

ret = openusb_set_default_timeout(libhandle, USB_TYPE_CONTROL, 10);

Leggendo la documentazione usb originale mi pare di aver capito che il device deve essere aperto per prima cosa
per dialogare in modo USB_TYPE_CONTROLL.

Per aprire un device ci serve un numero per identificare il device, e anche libhandle. Il device number e quello attribuito dal
kernel durante la fase di enumerazione, questo ad esempio cambia ogni volta che estraiamo e reinseriamo un device.

Per prendere un device tra quelli disponibili possiamo usare:

openusb_devid_t *devids; // typedef uint64_t openusb_devid_t; /* every devices in the USB bus has a devid */
uint32_t devnum; // il numero totale di device connessi al pc

ret = openusb_get_devids_by_vendor(libhandle, 0x4b4, 0x8613, &devids, &devnum);

Questa funzione ritorna in “devids” un puntatore ad array di unsigned int, in ogni elemento viene conservato il valore
identificativo assegnato dal kernel durante la fase dell’enumerazione.

In “devnum” invece ritorna il numero totale di device.
“0x4b4” è il vendor id registrato dentro il device, questo numero viene assegnato dal consorzio usb, mentre “0x8613” è il product id e non è assegnato dal consorzio ma deciso dal costruttore del device.

Con questi dati possiamo aprire un device così:

openusb_dev_handle_t devh; // typedef uint64_t openusb_dev_handle_t;/* every OPENED USB device has a handle */

ret = openusb_open_device(libhandle, devids[0], USB_INIT_DEFAULT, &devh);

Il numero di enumeratore si trova nell’elemento 0 di devids, devh è il device handle, questa variabile la dobbiamo poi usare
alle altre funzioni per dialogare con il device.

Da qui in poi le cose sono molto complesse in quanto un device può o no avere degli endpoints che se ho capito li dobbiamo vedere
come delle pipe cui possiamo dialogare, ma c’è anche la possibilità di scegliere come dialogare es message o altro.

Bebe se da qui in poi c’è chi ha interesse circa usb e ne sa più di me gli sarei grato se intervenisse.
Ora la domanda che mi faccio è: come devo iniziare a dialogare con il avrisp mkii?

Ciao.

bella guida, già da sè merita un articoletto a parte. per avr non so aiutarti :grin: