Код следует так же, как и вывод программы.
Я сделал следующий тестовый код, который воспроизводит проблему.Это тест на светодиодной доске (я что-то пишу, на плате горит светодиод).Проблема не относится к этому оборудованию, у меня такое же поведение на другом оборудовании.Фактический код является многоуровневым и лучше, но демонстрирует то же поведение.
Ситуация 1: я подключаю аппаратное обеспечение и запускаю программу, и она показывает поставленный вывод.Он делает то, что должен делать только один раз и только если я предварительно подключаю оборудование.Последующие операции отсоединения-присоединения завершаются неудачно на устройстве (например, без светодиода).
ситуация 2: То же самое происходит, если я запускаю программу, а затем подключаю оборудование.В такой ситуации оно никогда не функционирует.
Я не понимаю чего-то принципиально.Почему в ситуации 1 при первом «запуске» к нему не подключен драйвер ядра, а при последующих «запусках» он есть?Я уже экспериментировал (много) комментируя код относительно драйверов ядра, перемещая последовательность команд безрезультатно ...
где моя ошибка, пожалуйста?Если возможно, объясните это немного, потому что я заблудился ...
#include <stdlib.h>
#include <stdio.h>
#include <thread>
#include <iostream>
#include "libusb-1.0/libusb.h"
class test {
public:
int done = 0;
int rc = 0;
test() {
init();
}
virtual ~test() {
shutdown();
}
private:
const static uint8_t umRequestType = 0x21;
const static uint8_t umRequest = 9;
const static uint16_t umValue = 0x0200;
const static unsigned int umTimeout = 2000;
const static int interface = 0; //test board's interface
libusb_device_handle *handle = NULL;
int init() {
libusb_hotplug_callback_handle hp[2];
int product_id, vendor_id, class_id;
int rc;
vendor_id = 0xd209;
product_id = 0x1401;
class_id = LIBUSB_HOTPLUG_MATCH_ANY;
rc = libusb_init(NULL);
if (rc < 0) {
printf("failed to initialise libusb: %s\n", libusb_error_name(rc));
}
if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
printf("Hotplug capabilites are not supported on this platform\n");
libusb_exit(NULL);
}
rc = libusb_hotplug_register_callback(NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, LIBUSB_HOTPLUG_ENUMERATE, vendor_id,
product_id, class_id, static_hotplug_callback, this, &hp[0]);
if (LIBUSB_SUCCESS != rc) {
fprintf(stderr, "Error registering callback 0\n");
libusb_exit(NULL);
}
rc = libusb_hotplug_register_callback(NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, LIBUSB_HOTPLUG_ENUMERATE, vendor_id,
product_id, class_id, static_hotplug_callback_detach, this, &hp[1]);
if (LIBUSB_SUCCESS != rc) {
fprintf(stderr, "Error registering callback 1\n");
libusb_exit(NULL);
}
}
void shutdown() {
if (handle) {
libusb_close(handle);
}
libusb_exit(NULL);
}
static int LIBUSB_CALL static_hotplug_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data) {
return reinterpret_cast<test *>(user_data)->hotplug_callback(ctx, dev, event, user_data);
}
int hotplug_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data) {
struct libusb_device_descriptor desc;
(void) ctx;
(void) dev;
(void) event;
(void) user_data;
rc = libusb_get_device_descriptor(dev, &desc);
if (LIBUSB_SUCCESS != rc) {
fprintf(stderr, "Error getting device descriptor\n");
}
printf("Device attached: %04x:%04x\n", desc.idVendor, desc.idProduct);
rc = libusb_open(dev, &handle);
if (LIBUSB_SUCCESS != rc) {
fprintf(stderr, "Error opening device\n");
}
rc = libusb_kernel_driver_active(handle, interface);
printf("libusb_kernel_driver_active returned %d\n",rc);
if (rc == 1) { //find out if kernel driver is attached
printf("A kernel driver is active\n");
rc = libusb_detach_kernel_driver(handle, interface);
if (rc != LIBUSB_SUCCESS) {
printf("libusb_detach_kernel_driver() failed: %s - %d\n",libusb_error_name(rc),libusb_strerror((libusb_error) rc));
return false;
} else {
printf("detached kernel driver\n");
}
}
rc = libusb_set_configuration(handle, 1);
printf("libusb_set_configuration returned %d\n",rc);
if (handle) {
rc = libusb_set_auto_detach_kernel_driver(handle, 1);
if (rc != LIBUSB_SUCCESS) {
printf("libusb_set_auto_detach_kernel_driver() failed: %s - %d\n",libusb_error_name(rc),libusb_strerror((libusb_error) rc) );
} else {
printf("libusb_set_auto_detach_kernel_driver() has been set\n");
}
}
rc = libusb_claim_interface(handle, interface);
if (rc != LIBUSB_SUCCESS) {
printf("libusb_claim_interface() failed: %s - %d\n",libusb_error_name(rc),libusb_strerror((libusb_error) rc));
return false;
}
//get the bConfigurationValue
int config = 0;
rc = libusb_get_configuration(handle, &config);
std::cout << "libusb_get_configuration returned " << rc << "\n";
std::cout << "config value is " << config << "\n";
if (handle) {
std::array<unsigned char, 2> data{0x00, 0xff};
auto byteCount = libusb_control_transfer(handle, umRequestType, umRequest, umValue, interface, &data[0], data.size(), umTimeout);
printf("#bytes written to board: %d\n", data.size());
libusb_close(handle);
handle = NULL;
}
done++;
return 0;
}
static int LIBUSB_CALL static_hotplug_callback_detach(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data) {
return reinterpret_cast<test *>(user_data)->hotplug_callback_detach(ctx, dev, event, user_data);
}
int hotplug_callback_detach(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data) {
(void) ctx;
(void) dev;
(void) event;
(void) user_data;
printf("Device detached\n");
if (handle) {
libusb_close(handle);
handle = NULL;
}
done++;
return 0;
}
};
int main(int argc, char *argv[]) {
std::unique_ptr<test> testClass1 = std::make_unique<test>();
while (testClass1->done < 5) {
printf("#evens: %d\n",testClass1->done);
if (libusb_handle_events_completed(nullptr, nullptr) != LIBUSB_SUCCESS)
printf("libusb_handle_events() failed: %s\n", libusb_error_name(testClass1->rc));
std::this_thread::sleep_for(std::chrono::microseconds(1000000));
}
//the end
}
Ситуация с выводом программы 1:
/home/****/CLionProjects/usbdebugpoc/cmake-build-debug/usbdebugpoc
Device attached: d209:1401
libusb_kernel_driver_active returned 0
libusb_set_configuration returned 0
libusb_set_auto_detach_kernel_driver() has been set
libusb_get_configuration returned 0
config value is 1
#bytes written to board: 2
#evens: 1
Device detached
#evens: 2
Device attached: d209:1401
libusb_kernel_driver_active returned 1
A kernel driver is active
detached kernel driver
libusb_set_configuration returned 0
libusb_set_auto_detach_kernel_driver() has been set
libusb_get_configuration returned 0
config value is 1
#bytes written to board: 2
#evens: 3
Device detached
#evens: 4
Device attached: d209:1401
libusb_kernel_driver_active returned 1
A kernel driver is active
detached kernel driver
libusb_set_configuration returned 0
libusb_set_auto_detach_kernel_driver() has been set
libusb_get_configuration returned 0
config value is 1
#bytes written to board: 2
Process finished with exit code 0