Я пытаюсь сделать следующее: - у нас есть AXIS-контроллер, который подключен к Linux (18.04) через чип CP2102 к USB-порту. Мы хотим прочитать значения GPIO 0-3-бит через C-программу на linux-машине.
В моей C-программе я вижу USB-порт, и когда я читаю конфигурацию, он показывает всю нужную информацию:
bLength: 12
bDescriptorType: 01
bcdUSB: 0200
bDeviceClass: 00
bDeviceSubClass: 00
bDeviceProtocol: 00
bMaxPacketSize: 40
idVendor: 10C4
idProduct: EA60
bcdDevice: 0100
biManufacturer: 01
iProduct: 02
iSerialNumber: 0003
iNumConfigurations: 01
Config descriptor CP210x
bLength: 09
bDescriptorType: 02
wTotalLength: 0020
bNumInterfaces: 01
bConfigurationValue: 01
iConfiguration: 00
bmAttributes: 0080
MaxPower: 32
Для меня это означает, что я подключен к правильному последовательному устройству (/ dev / ttyUSB0 в моем случае).
Теперь мне очень непонятно, какие звонки я могу сделать, чтобы прочитать эти GPIO-биты. Пока я не могу найти какие-либо вызовы linux-API, которые я могу использовать в своей программе.
Исходный код, который я написал (не идеальный, но он только для проверки. Когда он заработает, я его почистю)
#include <stdio.h>
#include <stdlib.h>
#include <usb.h>
int main()
{
int nr_of_busses;
int nr_of_devices;
int j, r;
struct usb_bus *usb_busses;
struct usb_bus *ptr_usb_busses;
struct usb_device *ptr_usb_devices;
struct usb_device_descriptor desc;
uint8_t path[8];
usb_init();
perror( "Init LibUSB" );
nr_of_busses = usb_find_busses();
fprintf( stderr, "Nr of busses found: %i\n", nr_of_busses );
nr_of_devices = usb_find_devices();
fprintf( stderr, "Nr of devices found: %i\n", nr_of_devices );
usb_busses = usb_get_busses();
if ( usb_busses == NULL ) {
fprintf(stderr, "USB_busses = NULL\n");
perror( "Get busses" );
}
else {
ptr_usb_busses = usb_busses;
while ( ptr_usb_busses != NULL ) {
fprintf( stderr, "USB Buss : %s\n", ptr_usb_busses->dirname );
fflush( stderr );
ptr_usb_devices = ptr_usb_busses->devices;
while (ptr_usb_devices != NULL) {
fprintf( stderr, "FileName : %s\n", ptr_usb_devices->filename );
fflush( stderr );
sleep(3);
// Check if this is the cp210x-device I´m looking for. If so print the information, just to be sure and to compare with the documentation
if (ptr_usb_devices->descriptor.idProduct == 0xEA60 ) {
fprintf(stderr, "bLength: %02X\nbDescriptorType: %02X\nbcdUSB: %04X\nbDeviceClass: %02X\nbDeviceSubClass: %02X\n",
ptr_usb_devices->descriptor.bLength,
ptr_usb_devices->descriptor.bDescriptorType,
ptr_usb_devices->descriptor.bcdUSB,
ptr_usb_devices->descriptor.bDeviceClass,
ptr_usb_devices->descriptor.bDeviceSubClass );
fprintf(stderr, "bDeviceProtocol: %02X\nbMaxPacketSize: %02X\nidVendor: %04X\nidProduct: %04X\nbcdDevice: %04X\n",
ptr_usb_devices->descriptor.bDeviceProtocol,
ptr_usb_devices->descriptor.bMaxPacketSize0,
ptr_usb_devices->descriptor.idVendor,
ptr_usb_devices->descriptor.idProduct,
ptr_usb_devices->descriptor.bcdDevice );
fprintf(stderr, "biManufacturer: %02X\niProduct: %02X\niSerialNumber: %04X\niNumConfigurations: %02X\n",
ptr_usb_devices->descriptor.iManufacturer,
ptr_usb_devices->descriptor.iProduct,
ptr_usb_devices->descriptor.iSerialNumber,
ptr_usb_devices->descriptor.bNumConfigurations );
fprintf ( stderr, "Config descriptor CP210x\n");
fprintf( stderr, "bLength: %02X\nbDescriptorType: %02X\nwTotalLength: %04X\nbNumInterfaces: %02X\n",
ptr_usb_devices->config->bLength,
ptr_usb_devices->config->bDescriptorType,
ptr_usb_devices->config->wTotalLength,
ptr_usb_devices->config->bNumInterfaces );
fprintf( stderr, "bConfigurationValue: %02X\niConfiguration: %02X\nbmAttributes: %04X\nMaxPower: %02X\n",
ptr_usb_devices->config->bConfigurationValue,
ptr_usb_devices->config->iConfiguration,
ptr_usb_devices->config->bmAttributes,
ptr_usb_devices->config->MaxPower );
fflush( stderr );
usb_dev_handle *handle = usb_open( ptr_usb_devices );
// dev_dbg( ptr_usb_devices, "Test");
perror( "usb_open : ");
int stat = usb_set_configuration( handle, ptr_usb_devices->config->bConfigurationValue );
perror( "usb_set_configuration : ");
int interfaceNum = ptr_usb_devices->config->interface->altsetting->bInterfaceNumber;
stat = usb_claim_interface( handle, interfaceNum );
int altNum = ptr_usb_devices->config->interface->altsetting->bAlternateSetting;
stat = usb_set_altinterface( handle, altNum );
perror( "usb_set_altinterface : ");
// Now I need forever to read the GPIO-bits. How do I do that?
while (1) {
}
}
fprintf(stderr, "\n");
fflush( stderr );
ptr_usb_devices = ptr_usb_devices->next;
}
ptr_usb_busses = ptr_usb_busses->next;
}
fprintf( stderr, "All bus-names printed" );
fflush( stderr );
}
exit(0);
}
После компиляции я запускаю вышеуказанную программу через sudo ./a.out
.
Теперь у меня есть следующие проблемы:
Также я действительно не могу найти C-вызовы, которые я могу использовать для чтения битов GPIO в этой программе.
Есть ли библиотека для ссылки, в которой описаны правильные вызовы?
Вероятно, есть очень простое решение для этого, но я не могу найти его, поэтому, вероятно, я смотрю в неправильных местах.
Не то, чтобы Вы понимаете его превратно, Вы просто врезаетесь в стену времени. Совет, существует очень в возрасте документации в Интернете, Вы лучше начинаете проверять дату последнего изменения прежде, чем считать его.
Существует два способа сделать драйвер USB. Или мы можем сказать что два типа драйверов
Драйвер пространства ядра, драйвер в дереве ядра или как модуль
Драйвер пространства пользователя, использование драйвера libusb
(который отдельно использует универсальный драйвер ядра),
Вероятно, Вы нашли некоторые сообщения что, пытаясь получить доступ к USB-устройствам без драйвера ядра.
Однако для Вашего случая, CP210x имеет драйвер пространства ядра и уже реализовал функцию GPIO. Может быть это, не было ранее столько людей, узнают об этом. Никакая потребность пройти путь libusb, иначе необходимо реализовать много функций с нуля после таблицы данных CP210x.
Драйвер пространства ядра
Драйвер пространства пользователя (просто пример, не полнофункциональный)
https://github.com/VCTLabs/cp210x-program Первая фиксация 9 сентября 2010
Silicon Labs уже зарегистрировала его
Как управлять GPIOs CP210x во времени выполнения
25.07.2018 | 4:56
На Linux
Драйвер CP210x был распределен как часть ядра Linux с тех пор v2.6.12, и операции GPIO также поддерживаться Linux 4.10.0 ядер или позже.
При использовании более старой версии ядра загрузите последний Linux драйвер VCP со ссылки ниже и объедините GPIO связанный с операцией исходный код в ядро. .zip пакет содержит драйвер VCP и шоу примера кода, как управлять GPIOs.
https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers.
После слияния драйвера cp210x.c VCP скомпилируйте, это с делает команду и устанавливает его с командой "insmod". Обратите внимание, что команда "rmmod cp210x.ko" должна быть выполнена, если драйвер VCP уже существует прежде, чем установить драйвер та поддержка управление GPIO.
В cp210x_gpio_example.c используйте следующую функцию для открытия устройства CP210x.
fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
Используйте функцию ниже для чтения фиксатора, где третий параметр gpioread является буферным адресом однобайтовой длины для хранения значения фиксатора чтения.
ioctl(fd, IOCTL_GPIOGET, &gpioread);
Возвращенное значение фиксатора чтения представлено следующим образом: биты 0–7: Текущее состояние фиксатора, где бит 0 является GPIO0, кусает 1, GPIO1, и т.д. До GPIOn, где n является общим количеством контактов GPIO интерфейсные поддержки.
Используйте функцию ниже для записи фиксатора, где третий параметр gpio является значением фиксатора записи.
ioctl(fd, IOCTL_GPIOSET, &gpio);
Значение фиксатора записи, которое предоставляется в фазе Данных, представляет следующим образом:
биты 0–7: Маска состояния фиксатора (в битах 8-15) для записи, где бит 0 является GPIO0, кусает 1, GPIO1, и т.д. До GPIOn, где n является общим количеством контактов GPIO интерфейсные поддержки.
биты 8–15: состояние Фиксатора для записи, где бит 8 является GPIO0, кусает 9, GPIO1, и т.д. До GPIOn, где n является общим количеством контактов GPIO интерфейсные поддержки.
Получите больше информации от AN571.
Скомпилируйте приложение с “gcc cp210x_gpio_example.c”, исполняемый файл “a.out” сгенерирован. Выполните его с “./a.out”.
Я пробовал много разных приложений, и это сделало мой день:
https://github.com/ondrej1024/crelay
Работает без каких-либо модификаций модуля cp210x на ядре 4.19 на моей малине!