Asesoría y Servicios Integrales en Cómputo
La Solución con Linux
Una biblioteca para usar el protocolo MDB (Multi-Drop Bus) con dispositivos USB.
Esta biblioteca de C implementa una API sencilla basada en libusb para encontrar, establecer comunicacion, enviar y recibir paquetes de información con dispositivos que utilizan el protocolo MDB.
El desarrollador solo requiere incluir el encabezado izmdb.h para tener acceso a las funciones necesarias.
También está incluida una implementación parcial de la API USBXpress para acceso de bajo nivel a la comunicación con el dispositivo y un paquete de Python que expone directamente la funcionalidad de la biblioteca de C y un juego de funciones de alto nivel para el envío y recepción de datos via MDB.
El proceso para enviar comandos y recibir la respuesta del dispositivo es simple. A continuación describimos los pasos generales para hacerlo desde C y Python.
💡 El paquete fuente izmdb incluye programas de demostración del uso de la API tanto en en C como en Python:
izmdb-demo.c
lowlevel-izmdb-demo.c
python/izmdb-demo.py
python/lowlevel-izmdb-demo.py
Incluir el encabezado izmdb.h
izmdb_open(): Inicializar la comunicacion con el dispositivo. Solo es necesario hacerlo una vez al inicio del programa.
izmdb_send(): Preparar el comando y argumentos como un arreglo de bytes y enviarlo al dispositivo.
izmdb_receive(): Leer la respuesta del dispositivo.
izmdb_close(): Finalizar la comunicacion con el dispositivo antes de terminar el programa.
Importar el módulo izmdb
izmdb.open(): Inicializar la comunicacion con el dispositivo. Solo es necesario hacerlo una vez al inicio del programa.
izmdb.send(): Preparar el comando y argumentos como un arreglo de bytes y enviarlo al dispositivo.
izmdb.receive(): Leer la respuesta del dispositivo.
izmdb.close(): Finalizar la comunicacion con el dispositivo antes de terminar el programa.
Para la biblioteca de C:
make make install # Como root
Para el módulo de Python:
make python-install
U opcionalmente instalar ambos en un solo comando:
make install-all
Compilar los programas de demostración:
make demos
Representa a un paquete de información para la comunicación MDB con el dispositivo.
struct izmdb_packet { unsigned char *stream; # Datos contenidos en el paquete int size; # Cantidad de bytes a los que apunta packet.stream };
Estructura de datos opaca utilizada para referirse a un dispositivo.
IZMDB_ERR |
-1 |
IZMDB_OK |
1 |
IZMDB_NOMEM |
-2 |
IZMDB_INVALID_PACKET |
-3 |
IZMDB_DEV_NOT_FOUND |
-4 |
IZMDB_READ_ERROR |
-5 |
IZMDB_INVALID_PARAM |
-6 |
IZMDB_INVALID_PACKET_FROM_DEVICE |
-7 |
IZMDB_CANNOT_OPEN_DEV |
-8 |
IZMDB_WRITE_ERROR |
-9 |
Busca el primer dispositivo USB con identificacion VENDOR_ID:PRODUCT_ID y si lo encuentra, devuelve IZMDB_OK y HANDLE apunta a un handle para el dispositivo, utilizable por izmdb_send_packet() e izmdb_receive_packet().
Cierra la comunicación con el dispositivo USB referido por HANDLE.
Envía al dispositivo manejado por HANDLE la cantidad de bytes DATASIZE apuntados por DATA.
Recibe en el buffer DATABUF de tamaño apuntado por DATASIZE los datos contenidos en el siguiente paquete de comunicación disponible en el dispositivo manejado por HANDLE.
Regresa en el entero apuntado DATASIZE la cantidad de datos recibidos.
Empaquetar con Simple Coin Protocol la secuencia de comando MDB (Comando + argumentos) de longitud DATASIZE a la que apunta PKDATA.
La secuencia de comando va empaquetada asi:
| encabezado | comando + datos | terminador | 0xC1 carga util 0xC2
La carga útil se codifica de manera que si esta incluye los bytes 0xC0, 0xC1 y 0xC2 estos son escapados con un byte 0xC0 y codificados en la siguiente forma:
0xC0 --> 0xC0 0x00 0xC1 --> 0xC0 0x01 0xC2 --> 0xC0 0x02
Todos los demás bytes son copiados tal cual al paquete.
Si el empaquetamiento es exitoso devuelve IZMDB_OK y PACKET apunta al paquete codificado.
Desempaquetar los datos contenidos en el paquete al que apunta PACKET.
Esta es la operación inversa de izmdb_pack().
Si el desempacamiento es exitoso devuelve IZMDB_OK, PKDATA apunta a los datos descodificados y DATASIZE apunta a un entero que representa la cantidad de bytes descodificados.
Envía el paquete MDB apuntado por PACKET al dispositivo USB manejado por HANDLE.
Recibe un paquete MDB y lo almacena en el paquete apuntado por PACKET desde el dispositivo USB manejado por HANDLE.
Se espera que el campo 'stream' de PACKET apunta a un area reservada de memoria de tamaño suficiente y el campo 'size' indica el tamaño de la misma.
Para usar el paquete izmdb solo es necesario importarlo en tu código:
import izmdb
Buscar el dispositivo con USB VendorID VID y USB ProductID PID y establecer comunicacion con el.
Regresa un handle enlazado con ese dispositivo.
Regresa una cadena que representa el número de error ERRNUM.
Cerrar la comunicación con el dispositivo manejado por HANDLE.
En caso de éxito devuelve IZMDB_OK.
Crea un paquete MDB codificando el contenido del arreglo BYTES y lo envía al dispositivo manejado por HANDLE.
BYTES debe ser un objeto bytes, generado por ejemplo con una llamada a bytes():
b = bytes([0x01, 0x12, 0x0F, 0x00])
En caso de éxito devuelve IZMDB_OK.
Recibe el siguiente paquete MDB disponible en el dispositivo manejado por HANDLE y devuelve su contenido descodificado como un arreglo de bytes dentro de un objeto iterable de clase bytes.
Hortensias No 22 Fraccionamiento Jacarandas, Zapopan, Jalisco. CP. 45160 Tel. / Fax 01 (33) 3833-0373
www.asic-linux.com.mx info@asic-linux.com.mx