and73y
Пункты: 1154
Регистрация: 25.11.2009
Добрый день.
Не нашел на форуме инфы о том, как работать с COM портом.
Код int main(){
FILE *file = fopen("/dev/ttyS0", "r+");
if (file == NULL){
return 0;
}
fprintf(file, "Dart Vader helps you...");
int ch = fgetc(file);
fprintf(stdout, "%d\n", ch);
fclose(file);
return 1;
}
В винде HyperTerminal'ом коннекчусь к COM порту.
Запускаю программу в telnet.
В гипере вылазит надпись, а вот в обратную сторону данные не идут (из гипера в телнет).
В чем проблема?
P.S.
Ядро пользую стандартное (из комплекта).
alman
Пункты: 740
Регистрация: 04.02.2011
Пол: Мужчина
Возможно, не помешает ключ 't', говорящий системе корректно обрабатывать контрольные символы.
FILE *file = fopen("/dev/ttyS0", "rt+");
А вместо HyperTerminal лучше исполmзовать свежую версию putty - один из лучших терминалов для Windows.
Упс, только заметил. Есть такое понятие, как Line Discipline и режимы терминала. В простейшем случае Вам надо нажать Enter на терминале, чтобы getc "всосал" данные. Погуглите на предмет ioctl, termios и canonical mode. Даю 99.999% гарантии, что "проблема" именно в этом. Просто переключите режим работы устройства таким образом, чтобы не было ожидания Enter.
alman
Пункты: 740
Регистрация: 04.02.2011
Пол: Мужчина
Вот решение Вашей проблемы:
struct termios oldSettings, newSettings;
tcgetattr( fileno( file ), &oldSettings );
newSettings = oldSettings;
newSettings.c_lflag &= (~ICANON & ~ECHO);
tcsetattr( fileno( file ), TCSANOW, &newSettings );
and73y
Пункты: 1154
Регистрация: 25.11.2009
Спасиб за советы.
Код int Reader::Tests(){
FILE *file = fopen("/dev/ttyS0", "rt+");
if (file == NULL){
return SYSTEM_ERR;
}
struct termios options;
tcgetattr(fileno(file), &options);
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
tcsetattr(fileno(file), TCSANOW, &options);
fprintf(file, "Dart Vader helps you...\n");
int ch = fgetc(file);
fprintf(stdout, "%d\n", ch);
fclose(file);
return 0;
}
не помогло(
Чтобы работать нормально с COM портом надо вырубать оттуда терминалку.
Для этого идем в /etc/inittab и комментируем строку запуска getty.
После этого надо выполнить
init -q
Вопрос - в схеме на некоторых пинах есть еще COM порты (RX0 TX0 и т.п.), на них есть отражение в /dev ?
MTh
Пункты: 921
Регистрация: 19.09.2010
На все ком-порты должно быть. Называются они ttyS0, ttyS1 и т.д. если конечно в ядре настроено так.
and73y
Пункты: 1154
Регистрация: 25.11.2009
Пасибо, проверю.
на всякий случай привожу код инициации ком порта, мож кому пригодится)
Код
class SerialParams{
public:
SerialParams();
int Baudrate;
int DBits;
char Parity;
int SBits;
};
int SerialReader::InitPort(SerialParams *sparams, int fd){
if (fd == -1){
_logger->ToLogF("Init", "fd error: %d", fd);
return SYSTEM_ERR;
}
struct termios options;
tcgetattr(fd, &options);
options.c_cflag &= ~(EXTA | EXTB | HUPCL | CRTSCTS | CSIZE);
options.c_cflag |= (CLOCAL | CREAD);
options.c_lflag &= ~(ICANON | XCASE | ECHO | ECHOE | ECHOK | ECHONL | NOFLSH | IEXTEN | ECHOCTL | ECHOPRT | ECHOKE | FLUSHO | PENDIN | TOSTOP | ISIG);
options.c_lflag |= ISIG;
options.c_iflag &= ~(IXON | IXOFF | IXANY | BRKINT | INLCR | IGNCR | ICRNL | IUCLC | IMAXBEL);
options.c_iflag &= ~(INPCK | IGNPAR | PARMRK | ISTRIP);
options.c_oflag &= ~(OPOST | OLCUC | ONLCR | OCRNL | ONOCR | ONLRET | OFILL | OFDEL | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY);
// options.c_oflag &= ~(OPOST | OLCUC | ONLCR | OCRNL | ONOCR | ONLRET | OFILL | OFDEL | NL0 | NL1 | CR0 | CR1 | CR2 | CR3 | TAB0 | TAB1 | TAB2 | TAB3 | BS0 | BS1 | VT0 | VT1 | FF0 | FF1);
switch(sparams->Baudrate){
case 600:
cfsetispeed(&options, B600);
cfsetospeed(&options, B600);
break;
case 1200:
cfsetispeed(&options, B1200);
cfsetospeed(&options, B1200);
break;
case 1800:
cfsetispeed(&options, B1800);
cfsetospeed(&options, B1800);
break;
case 2400:
cfsetispeed(&options, B2400);
cfsetospeed(&options, B2400);
break;
case 4800:
cfsetispeed(&options, B4800);
cfsetospeed(&options, B4800);
break;
case 9600:
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
break;
case 19200:
cfsetispeed(&options, B19200);
cfsetospeed(&options, B19200);
break;
case 38400:
cfsetispeed(&options, B38400);
cfsetospeed(&options, B38400);
break;
case 57600:
cfsetispeed(&options, B57600);
cfsetospeed(&options, B57600);
break;
case 115200:
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
break;
case 230400:
cfsetispeed(&options, B230400);
cfsetospeed(&options, B230400);
break;
default:
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
_logger->ToLogF("Init", "baudrate error: %d", sparams->Baudrate);
break;
}
switch(sparams->DBits){
case 8:
options.c_cflag |= CS8;
break;
case 7:
options.c_cflag |= CS7;
break;
case 6:
options.c_cflag |= CS6;
break;
case 5:
options.c_cflag |= CS5;
break;
default:
options.c_cflag |= CS8;
_logger->ToLogF("Init", "databits error: %d", sparams->DBits);
break;
}
switch(sparams->Parity){
case 'n':
options.c_cflag &= ~PARENB;
break;
case 'e':
options.c_iflag |= (INPCK | PARMRK | ISTRIP);
options.c_cflag |= PARENB;
options.c_cflag &= ~PARODD;
break;
case 'o':
options.c_iflag |= (INPCK | PARMRK | ISTRIP);
options.c_cflag |= PARENB;
options.c_cflag |= PARODD;
break;
case 's':
options.c_cflag &= ~PARENB;
break;
default:
options.c_cflag &= ~PARENB;
_logger->ToLogF("Init", "parity error: %c", sparams->Parity);
break;
}
switch(sparams->SBits){
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
options.c_cflag &= ~CSTOPB;
_logger->ToLogF("Init", "stopbits error: %d", sparams->SBits);
break;
}
if (tcsetattr(fd, TCSANOW, &options) != 0){
return READER_INIT_ERR;
}
return OK;
}
int SerialReader::GetParams(const char *params, SerialParams *outparams){
//9600,8,n,1
int baudrate;
int dbits;
char parity;
int sbits;
if (sscanf(params, "%d,%d,%c,%d", &baudrate, &dbits, &parity, &sbits) != 4){
_logger->ToLogF("GetParams", "params err: %s", params);
return READER_PARAMS_ERR;
}
_logger->ToLogF("GetParams", "params: %d, %d, %c, %d", baudrate, dbits, parity, sbits);
outparams->Baudrate = baudrate;
outparams->DBits = dbits;
outparams->Parity = parity;
outparams->SBits = sbits;
return OK;
}
and73y
Пункты: 1154
Регистрация: 25.11.2009
нету ttyS1((((
как настроить ядро чтобы появились остальные ком порты?
Jury093
Пункты: 54259
Регистрация: 25.05.2009
Пол: Мужчина
Из: Санкт-Петербург
Цитата как настроить ядро чтобы появились остальные ком порты?
проверить по всей цепочке
сначала сунуться в сорцы ядра в файл платы и проверить там
потом запустить конфигуратор ядра и проверить там
потом.. хм.. написать что у вас за рутовая - может банально девайсы не прописаны (например в системе ReadOnly)..
попробуйте mdev или udev перезапустить
или ручками создать через mknod, параметры подглядеть у ttyS0 минор сделать +1..
На любой вопрос есть любой ответ.
and73y
Пункты: 1154
Регистрация: 25.11.2009
Да, действительно.
В файлике "board-..." не были верно сконфигурированы ttyS1 и ttyS2.