Я давно использую переполнение стека, и большинство проблем, решение которых уже доступно.Это первый раз, когда я действительно не могу понять это с помощью Интернета.Я надеюсь, что у кого-то есть ответ на следующую проблему.
Введение В настоящее время я работаю над проектом, который должен быть способен выполнить команду и действовать в соответствии с ее ответом.Этот проект выполняется в системе на основе Debian в консольном приложении c ++.Чтобы иметь возможность выполнять такие команды, я попытался использовать библиотеку LibUSB .
Проблема Всякий раз, когда отправляются пакеты, он не возвращает действительный ответ, как описанов документации оборудования.доступен инструмент по умолчанию, который запускает команду callibration, я прослушал эти пакеты с помощью Wireshark , но структура вызовов прерываний OUT для инструмента callibration отличается от сгенерированной LibUSB, поэтому (я думаю) вызываеткоманда не должна быть выполнена.
В документации представлена одна из следующих команд, которая должна выполнить диагностическую проверку, которая возвращает 5 байтов данных.
[0] Header: 0x02
[1] Command: 0x4C
[2] Byte to send: 0x02 (N bytes to send, Argument + data size)
[3] Argument: 0x09
[4] Data: 0x00
Ответ должен иметь следующий формат:
[0] Header: 0x02
[1] Command: 0x4C
[2] Byte to send: 0x03 (N bytes to send, Argument + data size)
[3] Argument: 0x09
[4] Processing result: D-1
[5] Diagnostic result: D-2
D-1 : либо 0x01: нормальное, либо 0x00 Ошибка D-2 : либо 0x00: нормальное или нет 0x00, связанный код ошибки.
Испытанные вещи
- Типы передачи:
- Синхронный:
- Libusb_bulk_transfer
- Libusb_control_transfer
- libusb_interrupt_transfer
- Асинхронный:
- Libusb_fill_bulk_transfer
- Libusb_fill_control_transf_t_5_51_transf_5pt_transfer
Я пробовал обе асинхронные синхронные реализации библиотеки LibUSB.Передача управления Я попытался случайным образом переключить переменные после того, как наиболее логичные способы их заполнения закончились, но безуспешно, как и следовало ожидать.Поскольку результаты, обнаруженные при перехвате пакетов, четко указывают на то, что выполняются вызовы INTERRUPT.
Интерфейсы: Аппаратное обеспечение имеет два интерфейса.Интерфейс 0, который содержит OUT 0x02 и IN 0x81, и интерфейс 1, который содержит OUT 0x04 и IN 0x83.Обнаружение прерывания USB-вызова на устройство, запускаемое инструментом, при условии, что интерфейс 1 используется для команды диагностики.(Также пробовал интерфейс 0 как с IN, так и с OUT, не смог заставить его работать.
Обнаружение пакетов с помощью Wireshark
Результаты запроса и ответа об обнаружении пакетов, сгенерированных с помощью инструментария: IMG: прерывание OUT (я отметил бит, где команда фактически предоставляется) IMG: прерывание IN-ответ Этот код фактически работает и возвращает ожидаемый набор данных в своем слоте данных (как описановыше, формат возврата правильный, 0x01 и 0x00).
Запрос и ответ, сгенерированные с помощью LibUSB с использованием кода: IMG: прерывание OUT IMG: прерывание IN ответ
Да, я также попытался установить максимальный размер буфера для оборудования, равный 64. К сожалению, не сработал. Как видно, оба запроса сильно отличаются, использую ли я неправильную передачуметод? Это другой поддерживаемый формат, в котором вы можете отправлять команды?
Используемый фрагмент кода: фрагмент кода немного устарел, я пытался переписывать / редактировать его несколько раз,последние реализации используются из онлайн-примеров.
#define USB_VENDOR_ID <VENDOR_ID>/* USB vendor ID used by the device
* 0x0483 is STMs ID
*/
#define USB_PRODUCT_ID <PRODUCT_ID> /* USB product ID used by the device */
#define USB_ENDPOINT_IN (LIBUSB_ENDPOINT_IN | 0x83) /* endpoint address */
#define USB_ENDPOINT_OUT (LIBUSB_ENDPOINT_OUT | 0x04) /* endpoint address */
#define USB_TIMEOUT 3000 /* Connection timeout (in ms) */
#define INTERFACE_NO 1
static libusb_context *ctx = NULL;
static libusb_device_handle *handle;
static uint8_t receiveBuf[64];
uint8_t transferBuf[64];
uint16_t counter=0;
int main(int argc, char **argv) {
libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices
libusb_device_handle *dev_handle; //a device handle
libusb_context *ctx = NULL; //a libusb session
int r; //for return values
ssize_t cnt; //holding number of devices in list
r = libusb_init(&ctx); //initialize the library for the session we just declared
if(r < 0) {
qDebug()<<"Init Error "<<r<<endl; //there was an error
return 1;
}
libusb_set_debug(ctx, 4); //set verbosity level to 3, as suggested in the documentation
cnt = libusb_get_device_list(ctx, &devs); //get the list of devices
if(cnt < 0) {
qDebug()<<"Get Device Error"<<endl; //there was an error
return 1;
}
qDebug()<<cnt<<" Devices in list."<<endl;
dev_handle = libusb_open_device_with_vid_pid(ctx, 0x0AFA, 0x7D3); //these are vendorID and productID I found for my usb device
if(dev_handle == NULL)
qDebug()<<"Cannot open device"<<endl;
else
qDebug()<<"Device Opened"<<endl;
libusb_free_device_list(devs, 1); //free the list, unref the devices in it
unsigned char *data = new unsigned char[5] { 0x02, 0x4C, 0x02, 0x09, 0 }; //data to write
data[0]= 0x02;data[1]= 0x4C;data[2]=0x02;data[3]=0x09; data[4]= 0; //some dummy values
int actual; //used to find out how many bytes were written
if(libusb_kernel_driver_active(dev_handle, INTERFACE_NO) == 1) { //find out if kernel driver is attached
qDebug()<<"Kernel Driver Active"<<endl;
if(libusb_detach_kernel_driver(dev_handle, INTERFACE_NO) == 0) //detach it
qDebug()<<"Kernel Driver Detached!"<<endl;
}
r = libusb_claim_interface(dev_handle, INTERFACE_NO); //claim interface 0 (the first) of device (mine had jsut 1)
if(r < 0) {
qDebug()<<"Cannot Claim Interface"<<endl;
return 1;
}
qDebug()<<"Claimed Interface"<<endl;
for(int i = 0; i != sizeof(data); i++) {
fprintf(stderr, "[%d] - %02x\n", i, data[i]);
}
qDebug()<<"Writing Data..."<<endl;
r = libusb_bulk_transfer(dev_handle, (USB_ENDPOINT_OUT | LIBUSB_ENDPOINT_OUT), data, sizeof(data), &actual, 0); //my device's out endpoint was 2, found with trial- the device had 2 endpoints: 2 and 129
if(r == 0 && actual == sizeof(data)) //we wrote the 4 bytes successfully
qDebug()<<"Writing Successful!"<<endl;
else
qDebug()<<"Write Error"<<endl;
fprintf(stderr, "Error Writing: %s", libusb_strerror(static_cast<libusb_error>(r)));
r = libusb_release_interface(dev_handle, INTERFACE_NO); //release the claimed interface
if(r!=0) {
qDebug()<<"Cannot Release Interface"<<endl;
return 1;
}
qDebug()<<"Released Interface"<<endl;
libusb_close(dev_handle); //close the device we opened
libusb_exit(ctx); //needs to be called to end the
delete[] data; //delete the allocated memory for data
return 0;
}
Я надеюсь, что есть кто-то, способный и готовый помочь мне здесь, потому что я работал над этим в течение трех дней подряд и до сих пор укрылсяне получил логическое решение этой проблемы.
Заранее спасибо!
~ Mark