Есть код
int open_port()
{
int fd; /* Файловый дескриптор для порта */
fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
/* Не удалось открыть порт */
/* perror() выводит сообщение (в стандартный поток ошибок), затем
описание последней случившейся ошибки (на основании errno) */
perror("open_port: Unable to open /dev/ttyS0 - ");
}
else
{
/* Порт успешно открыт */
/* fcntl выполняет одну из различных дополнительных операций над файловым дескриптором fd */
/* F_SETFL - Устанавливает часть флагов, относящихся к состоянию файла,
согласно значению, указанному в аргументе arg. (0) */
fcntl(fd, F_SETFL, 0);
printf("Ok - Port open!\n");
}
return (fd);
}
int main(int argc, char **argv)
{
system("clear");
int fd;
fd = open_port();
/* ----------------- Запись ------------------*/
int n; /* Количество посланных байт(write) */
char buf[] = "qwertyuiop"; /* Буффер ввода */
int length; /* Длина строки ввода (Количество байт) */
length = strlen(buf);
n = write(fd, buf, length);
/* write возвр. -1 при ошибке */
/* stderr - стандартный поток ошибок */
if (n == -1)
{
fputs("Записать не удалось!\n", stderr);
}
else
{
printf("Успешно записано %d байт(а) \n", n);
}
/* ------------------ Чтение ---------------- */
int k,i;
fcntl(fd, F_SETFL, FNDELAY);
char buf1[10];
k = read(fd, buf1, length);
if (k == -1)
{
printf("buffer = %s, Kod = %d \n", buf1, k);
printf("Ошибка чтения!\n");
}
else
{
printf("buffer = %s, Kod = %d \n", buf1, k);
}
close(fd);
printf("Ok - Port Close!\n\n");
return 0;
}
Который должен читать и писать в компорт. Пишет он исправно, а читать из него не получается. Код это не совсем мой, и в теме разбираюсь слабо, по-этому у меня 2 вопроса, первый как читать из ком порта и 2-й где почитать как это работает. Ком порт у меня сейчас замкнут сам на себя TXD на RXD через миником "это" работает.
По-умолчанию терминал (и последовательный порт в частности) открываются в режиме подходящем для телетайпа (что видно из названия tty) или терминала. Отсюда две особенности, которые больше всего мешают работать данному коду:
'\n'
в buf
: char buf[] = "qwertyuiop\n";
Также есть ещё одна проблема с неблокирующим чтением: ко времени, когда процесс начинает читать, данные из системного буфера просто не успевают передаться в порт. т.к.а скорость порта по-умолчанию всего 9600 бод, а попытка чтения происходит почти моментально.
Решения:
O_SYNC
read
'а, убрав fcntl(fd, F_SETFL, FNDELAY);
usleep ((1000000L/9600L+1)*8*n*2)
(осторожно, время примерное. в реальном коде полагаться на него не стоит, хотя произвольное значение в числе взято только удвоение задержки)Настраивать порт можно примерно как в ответе @eri с помощью tcsetattr()
, но я советую разобраться во флагах (2/3 в коде мёртвый груз, который ИМХО только отвлекает от сути) и внимательно прочитать man 3 tcsetattr
.
Как Вы поняли что он пишет исправно? Если порт открыт другой программой параллельно, то читаться он будет только в одну из них.
И нужно установить параметры скорости и битов на порту.
Вот например:
Копипаста из моего кода, которая скопипасчена (найду откуда-напишу ссылку)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
void setport(int fd){
struct termios tty;
memset (&tty, 0, sizeof tty);
cfsetospeed (&tty, 115200);
cfsetispeed (&tty, 115200);
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
// disable IGNBRK for mismatched speed tests; otherwise receive break
// as \000 chars
tty.c_iflag &= ~IGNBRK; // disable break processing
tty.c_lflag = 0; // no signaling chars, no echo,
// no canonical processing
tty.c_oflag = 0; // no remapping, no delays
tty.c_cc[VMIN] = 0; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
// enable reading
tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
tty.c_cflag |= 0;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;
if (tcsetattr (fd, TCSANOW, &tty) != 0)
{
fprintf (stderr,"error %d from tcsetattr", errno);
}
}
int main(int argc, char **argv){
......
int fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC);
if (fd<0) {
return -11;
}
setport(fd);
......
}
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Всем привет, работаю с двумерным массивом таким образом заполняю:
Есть программа, которой нужны админские привилегии (например, доступ в папку "C:\Program Files")Прога запускается под обычным пользователем
При открытии главного активити считываю строки из текста потом забиваю их в static String [] в отдельном классе от активитиГлавный активити делает...