Консультация № 72088
22.01.2007, 14:21
0.00 руб.
0 2 2
Уважаемые господа Программисты!
Надеюсь, с разделом не ошибся.
Суть вопроса:
Работает небольшой сервачок под WinXP – читает с COM порта и отсылает по TCP/IP клиентам данные. По RS232 пишет устройство, само активно, т.е. ч/з 0,25 сек. Засылает данные. Шлейф «нуль-модем».
Требуется: это дело перенести на старенькую машинку по Linux и забыть её в углу… Но вот не как не могу ни чего прочесть c порта, ничего! Что-то не так, а что… Вот исходники – (чисто тестовый вариант) ОС – Debian 3.1.
Второй вопрос сюда же – не могу потоки запустить, компилятор говорит об ошибке, с какими опциями это дело собирается? Или эта система не поддерживает многопоточность?
Заранее благодарю.


Приложение:
/*Чтение из COM порта (COM1) подключение по нуль-модемному шлейфу (1,2.3)* Устройство активно - через 0,25 сек. скидавает в линию данные * скорость = 1200 бод. бит данных = 8 четность = нет стоповый бит = 1 управление потоком = нет* формат кадра [ <0xAA> <пробел> <5 байт данных> ]*/#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <unistd.h>#include <string.h>#include <fcntl.h>#include <termios.h>//**********************************************#define DEBUGtypedef struct termios INFOPORT;//**********************************************int port = 0;//**********************************************FILE* open_f(void){ return fopen("/dev/ttyS0","rb");}void print_f(FILE*f){ unsigned char buf[5] = {0}; int count = fread(buf,5,1,f); printf("p1=%2X,p1=%2X,p1=%2X,p1=%2X,p1=%2X", buf[0],buf[0],buf[0],buf[0],buf[4]);}int open_port(void){ INFOPORT opt; int fd = open("/dev/ttyS0",O_RDWR | O_NOCTTY | O_NDELAY); //--------------------- if(fd == -1) { perror("Не могу открыть прорт - "); return fd; } else fcntl(fd,F_SETFL,FNDELAY);#ifdef DEBUG printf("Порт открыт"); #endif tcgetattr(fd,&opt); opt.c_cflag &= ~PARENB; opt.c_cflag &= ~CRTSCTS; opt.c_cflag &= ~CSTOPB; opt.c_cflag &= ~CSIZE; opt.c_oflag &= ~OPOST; opt.c_cflag |= CREAD; cfsetispeed(&opt,B1200); cfsetospeed(&opt,B1200); opt.c_cflag |= CS8;// opt.c_cflag &= ~(IXON |IXOFF | IXANY); tcsetattr(fd,TCSANOW,&opt); print_attr(opt); return (fd); }void close_port(int fd){ close(fd);}float read_port(char *buf,int count){ float f = 0; int i,read_int = 0; unsigned char cb[16] = {0}; if(port == -1) { memset(buf,0,count); return f; }#ifdef DEBUG printf("Начинаю чтение с порта "); #endif if((read_int = read(port,cb,16))==0) { printf("read_int = %i",read_int); return 0; } for(i=0; i < read_int; i++) { if(cb[i]==0xAA) break; } printf(" [i = %i read_int = %i]",i++,read_int); if((read_int-i)>4) { sprintf(buf,"%i%i%i.%i%i",cb[i+1],cb[i+2],cb[i+3],cb[i+4],cb[i+4]); f = atof(buf); printf(" p1=%2X p2=%2X p3=%2X p4=%2X p5=%2X",cb[i+1],cb[i+2],cb[i+3],cb[i+4],cb[i+4]); } return f;}//------------------------------------------int main(void){ float value = 0; port = open_port(); if(port == -1) { perror("Порт не открыт - "); return 0; } char data[6] = {0}; for(int i=0;i<50;i++) { read_port(data,6); printf("%i) Данные: %s",i,data); sleep(1); } close_port(port); printf("Работа программы закончена"); return 0;}

Обсуждение

Неизвестный
22.01.2007, 15:30
общий
это ответ
Здравствуйте, Виктор Пырлик!
Скомпилировалось вот в таком виде на gcc 3.3.3 и 4.1.1

gcc 2.95.3 компилировать отказался, ссылаясь на то, что он состоит в интимных отношениях с таким кодом :-)

Приложение:
/*Чтение из COM порта (COM1) подключение по нуль-модемному шлейфу (1,2.3)* Устройство активно - через 0,25 сек. скидавает в линию данные * скорость = 1200 бод. бит данных = 8 четность = нет стоповый бит = 1 управление потоком = нет* формат кадра [ <0xAA> <пробел> <5 байт данных> ]*/#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <unistd.h>#include <string.h>#include <fcntl.h>#include <termios.h>//**********************************************#define DEBUGtypedef struct termios INFOPORT;//**********************************************int port = 0;//**********************************************FILE* open_f(void){ return fopen("/dev/ttyS0","rb");}void print_f(FILE*f){ unsigned char buf[5] = {0}; int count = fread(buf,5,1,f); printf("p1=%2X,p1=%2X,p1=%2X,p1=%2X,p1=%2X", buf[0],buf[0],buf[0],buf[0],buf[4]);}int open_port(void){ INFOPORT opt; int fd = open("/dev/ttyS0",O_RDWR | O_NOCTTY | O_NDELAY); //--------------------- if(fd == -1) { perror("Не могу открыть прорт - "); return fd; } else fcntl(fd,F_SETFL,FNDELAY);#ifdef DEBUG printf("\nПорт открыт\n"); #endif tcgetattr(fd,&opt); opt.c_cflag &= ~PARENB; opt.c_cflag &= ~CRTSCTS; opt.c_cflag &= ~CSTOPB; opt.c_cflag &= ~CSIZE; opt.c_oflag &= ~OPOST; opt.c_cflag |= CREAD; cfsetispeed(&opt,B1200); cfsetospeed(&opt,B1200); opt.c_cflag |= CS8;// opt.c_cflag &= ~(IXON |IXOFF | IXANY); tcsetattr(fd,TCSANOW,&opt);// print_attr(opt); return (fd); }void close_port(int fd){ close(fd);}float read_port(char *buf,int count){ float f = 0; int i,read_int = 0; unsigned char cb[16] = {0}; if(port == -1) { memset(buf,0,count); return f; }#ifdef DEBUG printf("\nНачинаю чтение с порта\t"); #endif if((read_int = read(port,cb,16))==0) { printf("read_int = %i\n",read_int); return 0; } for(i=0; i < read_int; i++) { if(cb[i]==0xAA) break; } printf("\t[i = %i read_int = %i]\n",i++,read_int); if((read_int-i)>4) { sprintf(buf,"%i%i%i.%i%i",cb[i+1],cb[i+2],cb[i+3],cb[i+4],cb[i+4]); f = atof(buf); printf("\tp1=%2X\tp2=%2X\tp3=%2X\tp4=%2X\tp5=%2X\n",cb[i+1],cb[i+2],cb[i+3],cb[i+4],cb[i+4]); } return f;}//------------------------------------------int main(void){ float value = 0; port = open_port(); if(port == -1) { perror("Порт не открыт - "); return 0; } char data[6] = {0}; int i; for(i=0;i<50;i++) { read_port(data,6); printf("\n%i)\tДанные:\t%s",i,data); sleep(1); } close_port(port); printf("\nРабота программы закончена\n"); return 0;}
Неизвестный
22.01.2007, 18:26
общий
это ответ
Здравствуйте, Виктор Пырлик!

подправил немного перенеся объявления переменных в начало фунции и откомпилил.
проверил через нульмодемный кабель все принимается.
=====
9) Данные:
Начинаю чтение с порта [i = 0 read_int = -1]

10) Данные:
Начинаю чтение с порта [i = 0 read_int = -1]

11) Данные:
Начинаю чтение с порта [i = 16 read_int = 16]

12) Данные:
Начинаю чтение с порта [i = 16 read_int = 16]
====
на другой стороне терминальной программой отсылал мусор просто

каждое чтение через секунду как и ожидалось. а что должно быть то?
Форма ответа