Linux шпаргалки
COM порт в Linux представляет собой файл устройства. Типичное расположение такого файла
\dev\ttySx для обычного COM порта или \dev\ttyUSBx для
USB-RS переходника, где x = 0,1,2.
Встречаются также \dev\ttyOSx и др.
Для начала работы COM порт необходимо открыть:
int F_ID = -1; open(«\dev\ttyUSB0», O_RDWR | O_NOCTTY); if(F_ID == -1)
Если F_ID отличается от -1 , значит COM порт открыт успешно
и можно переходить к его настройке.
Чтение текущих настроек:
struct termios options; /*структура для установки порта*/ tcgetattr(F_ID, &options); /*читает пораметры порта*/
cfsetispeed(&options, B57600); /*установка скорости порта*/ cfsetospeed(&options, B57600); /*установка скорости порта*/
options.c_cc[VTIME] = 20; /*Время ожидания байта 20*0.1 = 2 секунды */ options.c_cc[VMIN] = 0; /*минимальное число байт для чтения*/
options.c_cflag &= ~PARENB; /*бит четности не используется*/ options.c_cflag &= ~CSTOPB; /*1 стоп бит */ options.c_cflag &= ~CSIZE; /*Размер байта*/ options.c_cflag |= CS8; /*8 бит*/ options.c_lflag = 0; options.c_oflag &= ~OPOST; /*Обязательно отключить постобработку*/ options.c_iflag = 0; options.c_iflag &= ~ (INLCR | IGNCR | ICRNL);
Чтение и отправка данных
unsigned char buff[16] = ; int size = 8; int n = read(F_ID, buff, size);
unsigned char buff[4] = ; int size = 4; int n = write(F_ID, buff, size);
Завершение работы
Дополнительные возможности
Кроме сигналов TX и RX в COM порте присутствуют дополнительные сигналы,
например: RTS, CTS и т.д
иногда с ними необходимо работать.
Установка RTS:
int status; ioctl(F_ID, TIOCMGET, &status); status |= TIOCM_RTS; ioctl(F_ID, TIOCMSET, &status);
int status; ioctl(F_ID, TIOCMGET, &status); status &= ~TIOCM_RTS; ioctl(F_ID, TIOCMSET, &status);
В итоге получаем набор функций
#include #include #include #include #include #include
#include int F_ID = -1; /*---------------------------------------------------------------------------- Открыть COM порт COM_name: путь к устройству, например: /dev/ttyS0 или /dev/ttyUSB0 - для USB speed: скорость, например: B9600, B57600, B115200 ----------------------------------------------------------------------------*/ bool openPort(const char *COM_name,speed_t speed) < F_ID = open(COM_name, O_RDWR | O_NOCTTY); if(F_ID == -1) < char *errmsg = strerror(errno); printf("%s\n",errmsg); return false; >struct termios options; /*структура для установки порта*/ tcgetattr(F_ID, &options); /*читает пораметры порта*/ cfsetispeed(&options, speed); /*установка скорости порта*/ cfsetospeed(&options, speed); /*установка скорости порта*/ options.c_cc[VTIME] = 20; /*Время ожидания байта 20*0.1 = 2 секунды */ options.c_cc[VMIN] = 0; /*минимальное число байт для чтения*/ options.c_cflag &= ~PARENB; /*бит четности не используется*/ options.c_cflag &= ~CSTOPB; /*1 стоп бит */ options.c_cflag &= ~CSIZE; /*Размер байта*/ options.c_cflag |= CS8; /*8 бит*/ options.c_lflag = 0; options.c_oflag &= ~OPOST; /*Обязательно отключить постобработку*/ tcsetattr(F_ID, TCSANOW, &options); /*сохронения параметров порта*/ return true; > /*---------------------------------------------------------------------------- Прочитать данные из COM порта buff - буфер для принятых данных size - количество запрашиваемых байт ----------------------------------------------------------------------------*/ int readData(unsigned char *buff,int size) < int n = read(F_ID, buff, size); if(n == -1) < char *errmsg = strerror(errno); printf("%s\n",errmsg); >return n; > /*---------------------------------------------------------------------------- Отправить в COM порт данные buff - буфер данных для отправки size - количество отправляемых байт ----------------------------------------------------------------------------*/ int sendData(unsigned char* buff,int len) < int n = write(F_ID, buff, len); if(n == -1) < char *errmsg = strerror(errno); printf("%s\n",errmsg); >return n; > /*---------------------------------------------------------------------------- Закрыть COM порт ----------------------------------------------------------------------------*/ void closeCom(void) < close(F_ID); F_ID = -1; return; >/*---------------------------------------------------------------------------- Установить RTS ----------------------------------------------------------------------------*/ void setRTS() < int status; ioctl(F_ID, TIOCMGET, &status); status |= TIOCM_RTS; ioctl(F_ID, TIOCMSET, &status); >/*---------------------------------------------------------------------------- Очистить RTS ----------------------------------------------------------------------------*/ void clrRTS() < int status; ioctl(F_ID, TIOCMGET, &status); status &= ~TIOCM_RTS; ioctl(F_ID, TIOCMSET, &status); >/*---------------------------------------------------------------------------- Пример использования ----------------------------------------------------------------------------*/ int main() < bool res = openPort("\dev\ttyUSB0",B9600); if(!res) < printf("Невозможно открыть COM порт\n"); return 0; >unsigned char buff[8] = ; sendData(buff,8); int s = readData(rbuff,4); if(s < 4) < printf("Нет ответа\n"); return 0; >/* Наш код */ return 0; >
скорость порта ttyUSB
Добрый день!
OC:Debian 3.16.36-1+deb8u2.
К серверу подключен 3G-модем Huawei E1550, версия прошивки — 11.608.14.15.311
Модем видится как 3 устройства:
/dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyUSB2
stty: /dev/ttyUSB1: cannot perform all requested operations
Тебе не нужно ничего ставить, ttyUSB если это не usb->uart никак к этой скорости не привязаны.
Как тогда узнать реальную скорость на этом порту?
Сколько пролезло через USB столько и будет.
для этого необходимо узнать — поддерживает ли модем другую скорость. И скорее всего необходимо будет выполнить AT команду на модеме, которая переключит его порт на скорость больше чем 9600. Передернуть модем. А после уже думать об увеличении скорости USB порта (виртуального порта)
Скорость нужна только в одном случае, когда на железной стороне у тебя реальный U(S)ART. В остальных случаях типа usb-модемов — это рудимент оставленный для совместимости интерфейсов.
однако некоторые USB модемы работают на скорости 115200 по умолчанию. Конечно — если UARTa нет в модеме то это эмуляция. посмотрел спеку на свой модем — сходу не нашел АТ команды по смене скорости. Возможно скорость зашита жестко в драйвер модема.
подключись с любой другой скоростью. изменений не увидишь.
Ну и тебя не смущает, что ты получаешь 14MBit через 115200 порт?
Dark_SavanT ★★★★★ ( 27.04.17 14:56:30 MSK )
Последнее исправление: Dark_SavanT 27.04.17 14:57:10 MSK (всего исправлений: 1)
это рудимент оставленный для совместимости интерфейсов.
Да полноте. Какой рудимент? Это типичное забивание гвоздей микроскопом. Типа мы сделаем видимость что у нас есть микроскоп, но вот все крутилки сделаем фальшивыми, вроде крутилка есть, а не крутится. По вашей логике с таким же успехом вы можете назвать рудиментом управление скорости на эзернете.
Ведь технически управление скоростью может пригодиться, скажем если проц свистка не успевает прожевать, он может себя разгрузить и успевать больше, если выставит правильную скорость с какой он может жевать данные, так как буферизация уже ляжет на внешний проц большого брата.
По вашей логике с таким же успехом вы можете назвать рудиментом управление скорости на эзернете.
На eth управление скоростью приводит к вполне конкретным изменениям на физическом уровне. Потому не рудимент.
Ведь технически управление скоростью может пригодиться, скажем если проц свистка не успевает прожевать, он может себя разгрузить и успевать больше, если выставит правильную скорость с какой он может жевать данные, так как буферизация уже ляжет на внешний проц большого брата.
Пока usb-ep не отдаст ACK, ему следующий не отправят. Буферизация и так на хосте происходит. Так что в случае с usb-модемом, это именно рудимент.
Не надо путать с usb-u(s)art, где установка скорости на tty является установкой скорости физического u(s)art.
Пока usb-ep не отдаст ACK, ему следующий не отправят.
Это работает пока вы делаете «ATкороткая комманда», а вот когда льются данные, то уже получаются блоки, и значить производится буферизация и в свистке, а значить просаживаем производительность.
Не надо путать с usb-u(s)art, где установка скорости на tty является установкой скорости физического u(s)art.
В данном случае физика виртуально-эмулированная, и именно благодаря стандартизированному интерфейсу можно было б заюзать крутилку. Вот что точно является рудиментом, это нестандартное управление скоростями больше 115200. Именно по этому и забивают на эту крутилку.
У меня вон синтезатор ямаховский, пока ему свой «драйвер» не написал, который притормаживает обмен по USB, ничего больше килобайта залить на стандартных дровах было нельзя.
у меня модем sierra в одном из режимов для передачи пакетов создается другой интерфейс.
• “DIP”—Direct IP interface
• “QMI”—QMI interface
wwan0 Link encap:Ethernet HWaddr 96:B2:F8:87:0A:07 BROADCAST NOARP MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
Конечно этот интерфейс в свою очередь может гонять пакеты через тот же самый /dev/ttyUSB3 (к которому терминалкой цепляешься). но в системе после подключения появляется 5 файлов ttyUSBХ в /dev
Не пробовал на 9600 к модему подключаться, но скорее всего не получиться.
Vlad-76 ★★★★ ( 27.04.17 15:41:41 MSK )
Последнее исправление: Vlad-76 27.04.17 15:47:52 MSK (всего исправлений: 1)
Это работает пока вы делаете «ATкороткая комманда», а вот когда льются данные, то уже получаются блоки, и значить производится буферизация и в свистке, а значить просаживаем производительность.
Для начала почитать сюда, потом в исходники линуксовых драйверов. Сейчас там почти неплохо, пять лет назад местами был мрак.
У меня вон синтезатор ямаховский, пока ему свой «драйвер» не написал, который притормаживает обмен по USB, ничего больше килобайта залить на стандартных дровах было нельзя.
Ну так стандартные дрова могут и не знать про особенности конкретной железяки.
А вообще, с наступлением 3G/4G, PPP интерфейс становится сильно ограничивающим в плане скорости. Потому сейчас модемы стараются делать как usb-eth в лучшем случае cdc-wdm, в худшем RNDIS. И работает действительно быстрее.
Ну так стандартные дрова могут и не знать про особенности конкретной железяки.
Они и не могут знать, ибо это usb-midi, какая там железка за midi дрова линукса узнавать в общем случае не обязаны, так как это можно только получить уже по проприетарному протокол-расширению ямахи. Самое смешное, что эта модель шнурка явно прописана в документации в виде рекомендации по покупке видов аксессуаров к синтезатору. Похоже проблема чисто китайская, дооптимизировались, но общая, форумы пестрят ей.
А ты попробуй и увидишь что он отлично откликается и на 9600 и даже пакеты будут ходить примерно с той же скоростью.
А потом сравни с QMI(который умеет modemmanager, если ты к десктопному линуксу цепляешься). В общем случае latency будет ниже и максимальная скорость повыше, но это если БС тебе отдаст достаточно широкий поток.
Похоже проблема чисто китайская, дооптимизировались
Китайцы, особенно не брендовые, очень любят класть с прибором на стандарты и реализацию делать лишь бы дешевле. Так что с ненулевой вероятностью может оказаться, что если взять такой же шнурок но нормального производителя, будет работать. А может не будет и проблема была сразу.
Dark_SavanT ★★★★★ ( 27.04.17 16:27:56 MSK )
Последнее исправление: Dark_SavanT 27.04.17 16:28:13 MSK (всего исправлений: 1)