|
|
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
Всем привет) В общем я на форуме не давно, не знаю даже как спросить, чтоб вы меня не завалили письмами типо я идиот и т.д. Так что спрошу как есть... Пишу программу для Асинхронного считывания данных с ком порта... Ну как пишу, написал) Всё работает, НО, не так как хочется... Скажем устройство передаёт мне пакет из 18 байт. Моя программа принимает его кусками, сначала там 4, потом 10, потом опять 4 И каждый раз эти цыфры произвольные... Никогда не приходит пакет целиком, для того чтобы его собрать приходится создавать второй поток и вобщем там я и завис, но я думаю что проблема где-то в конфигурации... Вот код: #include "putt1.h" /*Этой мой заголовок в нём лежит:*/ #include <termios.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/signal.h> #include <sys/types.h> #include <pthread.h> #include "stdint.h" #define FALSE 0 #define TRUE 1 /*Импортируемые функии лучше не задумывайтесь зачем они, это к делу отношения не имеет*/ extern int FCS(char *rf,int len ); extern void sbor_adresov (char *bufer); extern void Active_EP_Request_JSON (char *bufer); extern void Simple_desc_request_JSON (char *bufer); extern void ZDO_IEEE_ADDR_req_JSON (char *bufer); void signal_handler_IO (int status); /* объявление обработчика сигнала */ volatile int STOP=FALSE; volatile int flags; int wait_flag=TRUE; /* TRUE до получения сигнала */ int res; struct termios options,options_old; struct sigaction saio; char SEND[256]; char bufer [256]; unsigned char buf[256]; char *ports2[]= { "/dev/ttyUSB0", "/dev/ttyUSB1", "/dev/ttyUSB2", "/dev/ttyUSB3", "/dev/ttyUSB4", "/dev/ttyUSB5", } ; #include <pthread.h> #include <string.h> #define FALSE 0 #define TRUE 1 int fd; void signal_handler_IO (int status) { wait_flag = FALSE; } int open_ports(){ fd=open(ports2[0],O_RDWR|O_NOCTTY| O_NDELAY|O_NONBLOCK); if (fd<0){ return 1;} printf("\nPort Open - 1 \n"); int fres = tcflush(fd, TCIFLUSH); if (fres < 0){printf("tcflush() error %d\n", fres);} saio.sa_handler = signal_handler_IO; sigemptyset(&saio.sa_mask); saio.sa_flags = saio.sa_flags|SA_SIGINFO; saio.sa_restorer = NULL; saio.sa_sigaction = signal_handler_IO; sigaction(SIGIO,&saio,NULL); fcntl(fd, F_SETOWN, getpid()); fcntl(fd, F_SETFL, FASYNC); tcgetattr(fd,&options_old); options.c_cflag |= (B115200 | CS8 | CLOCAL | CREAD| CRTSCTS ); options.c_cflag &= ~( ICANON ); options.c_iflag |= IGNPAR|IGNBRK; options.c_cflag &= ~(CS5 | CS6 | CS7 ); options.c_cflag |= CS8; options.c_iflag &= ~(IXON | IXOFF | IXANY ); options.c_cflag &= ~(PARENB | PARODD | ECHO | ECHOE |ISIG ); options.c_oflag &= ~OPOST; options.c_lflag = 0; options.c_cc[VMIN] = 0; options.c_cc[VTIME] = 0; options.c_cflag &= ~ CSTOPB; options.c_cflag &= ~CSIZE; tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&options); } void* read_only () { open_ports() ; while (STOP==FALSE) { /*Это бесконечный цикл неосновного потока, раньше программа была однопоточная и было удобно, пока я не заметил, что буфер мой рассыпается на части*/ if (wait_flag==FALSE) { int ee=0; res = read(fd,buf,255); for (;ee<res;ee++) { printf("buf[%i]:%x \n",ee, buf[ee]); bufer[ee]=buf[ee]; } printf ("---\n"); wait_flag = TRUE; int fres = tcflush(fd, TCIFLUSH); if (fres < 0){printf("tcflush() error %d\n", fres);} } } tcsetattr(fd,TCSANOW,&options_old); } int reads () { pthread_t t1; pthread_create(&t1,NULL,read_only,NULL); /*Ну это запуск неосновного потока*/ } int write_read (char *Send_buf,int len){ /*Запись в порт работает прекрасно*/ int e=4; unsigned char result =0x00; for (;e<len;e++){result ++;} Send_buf[1] = result; int i=0; int resFCS = FCS(Send_buf,len); for (;i<len;i++){ SEND [i] = Send_buf [i]; } SEND [len] = resFCS; int foll; usleep(500); foll = write(fd, SEND, sizeof(SEND)); usleep(500); if (foll < 0){printf("write error %d\n", foll);} } /*Вобщем я перепробовал и канонический и неканонический ввод, кучу разных настроек из интернета и сам побредил чуток с конфигурацией А буфер как рассыпался так и рассыпается FE 45 56 87 DD 55 AA 44 99 11 88 11 88 00 11 - должен быть такой, а приходит FE 45 56 87 потом DD 55 AA 44 99 потом 11 88 11 88 00 11 Вот это я называю рассыпается) А так как у меня это в бесконечном цикле нужен второй поток чтобы исправить, а это накладки на проц и оперативку... А мне они не к чему) Да и не люблю я сишные потоки) */ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 14:45 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
COM-порт пакетами данные не отправляет. Он побайтово работает. Ты считываешь данные быстрее, чем устройство их посылает. В чем проблема, лично мне не понятно. Зачем второй поток, что бы что-то собирать - лично мне тоже не понятно. С COM-портами работал очень давно и "ручками" через прерывания. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 14:52 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
Ну побайтово, да) Но он эти байты сам закидывает в буфер... Он их туда набрасывает а я уже забираю) Но вот проблема то в том, что он накидает 5 штук, а потом ещё 3 ну всегда по разному, я не понимаю почему он сразу не набросает 8? Ну второй поток бред согласен, но так я вышел из положения, теперь вот сижу исправляю) Про сами ком порты мне мало что известно, только то что есть в интернете, а как это через прерывания? Может мне бы помогло? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 14:57 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
Иван_2014, Байты эти, наверное имеют какую-то "структуру", скорее всего есть стоповые "байты", которые нужно дождаться пока они появятся в буфере? Далее уже собранные байты отправлять функциям на обработку. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 15:14 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
Имеют, Все 8 бит используются, Каждый байт несёт данные типа char DATA = 0xFE например, с этим всё порядке, используется один стоповый бит кажется : options.c_cflag &= ~ CSTOPB; Мне тут подсказали умную мысль ----- Мне почему-то кажется, что это нормальное поведение для неблокирующего I/O. Сколько в буфер успело прийти байт, столько тебе read() сразу и возвращает. ---- Я вот думаю как мне подрихтовать конфиг, чтобы все байты успевали прийти в буфер ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 15:19 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
Иван_2014Я вот думаю как мне подрихтовать конфиг, чтобы все байты успевали прийти в буфер Никак. Разные устройства "отправляют" и "принимают" по-разному. Еще и юсб-преобразователи каждый сам себе хозяин и вносит свою лепту. Так что самый надежный способ это иметь жесткий формат пакета с, например, началом и/или концом пакета (определенный байт или последовательность байтов). Накапливать в буфер полученные байты с последующим поиском этих меток. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 15:30 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
Каждый раз мне в буфер устройство шлёт разное количество данных) Но я точно знаю что первым байтом всегда будет 0xFE а дальше неопределённое количество но не больше 256... Может быть 18 может быть 25 может да по разному кароче) Смысл в том что моя программа зашвыривает меня кусочками от этих 18... Я точно знаю что это кусочки именно этих 18... Потому что я тыкаю кнопку на одном устройстве, оно по сети передаёт пакет на устройство, подсоединённое к компу, а потом этот пакет через ком порт отправляется ко мне на комп, только кусками а не целиком... А мне нужен этот пакет целиком чтобы был в буфере, чтобы он туда весь залез и я его забрал, за один такт цикла, за один вызов функции read (); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 15:36 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
Иван_2014А мне нужен этот пакет целиком чтобы был в буфере, чтобы он туда весь залез и я его забрал, за один такт цикла, за один вызов функции read (); "Рассмотрено и отказано". Придется программировать, как и положено: собирается буфер, анализируется (поиск метки), если метка найдена, то буфер отдается на обработку и очищается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 15:40 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
Так у меня так и написано, signal handler io функция Улавливает передающий сигнал, ставит метку, идёт чтение буфера, Но в этом дурацком буфере только часть данных а мне нужны все, и он остальную часть с аэрокосмической скоростью кидает вдовесок... Но цикл делает несколько тактов, функция read()срабатывает от 2-4 раз, зависит от величины сетевого пакета... вот я сижу и мучаюсь думаю сделать второй поток, чтобы он собрал эти кусочки в один, но чёт лажа какая-то получается и поэтому мне кажется что это не правильный выход из ситуации... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 15:46 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
wadman Придется программировать, как и положено: собирается буфер, анализируется (поиск метки), если метка найдена, то буфер отдается на обработку и очищается. либо анализируется таймаут после прихода последнего символа - за заданный интервал ничего не пришло - пакет готов ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 16:02 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
Иван_2014Имеют, Все 8 бит используются, Каждый байт несёт данные типа char DATA = 0xFE например, с этим всё порядке, используется один стоповый бит кажется : options.c_cflag &= ~ CSTOPB; Мне тут подсказали умную мысль ----- Мне почему-то кажется, что это нормальное поведение для неблокирующего I/O. Сколько в буфер успело прийти байт, столько тебе read() сразу и возвращает. ---- Я вот думаю как мне подрихтовать конфиг, чтобы все байты успевали прийти в буферman tcsetattr однако. Попробуйте поставить чего-нибудь больше нуля в options.c_cc[VTIME] и может быть в options.c_cc[VMIN] ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 16:03 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
Изопропилwadman Придется программировать, как и положено: собирается буфер, анализируется (поиск метки), если метка найдена, то буфер отдается на обработку и очищается. либо анализируется таймаут после прихода последнего символа - за заданный интервал ничего не пришло - пакет готов Редкий случай. Особенно, когда железка работает на чипе, который при открытии порта флешит буфер раз в 10 секунд и без разницы - пусто там или имеется сотня байт. Это из личного опыта. Потому и рекомендую нормально программировать сразу, а не искать пути схалявничать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 16:05 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
Всё я решил проблему.... Удалось схалявничать хД))) if (wait_flag==FALSE) { Сюда добавил следующее int len=0; do { usleep(100); res=read(fd, buf,255); } while (res == 0); do { len+=res; usleep(100); res=read(fd, buf+len,255-len); } while (res != 0); Заставил его пыжиться от нехрин делать, а потом собирать всё до тех пор пока собирать будет нечего хД) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 16:15 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
Иван_2014Но я точно знаю что первым байтом всегда будет 0xFE а дальше неопределённое количество но не больше 256... ... А мне нужен этот пакет целиком чтобы был в буфере, чтобы он туда весь залез и я его забрал, за один такт цикла, за один вызов функции read (); Как по твоему получатель должен узнать что пакет передан целиком? Как выше написали - неделимая единица 1 байт, все остальное зависит от скорости передачи, т.е. будет приходить побайтно, сколько байт за раз прочитается зависит только от того сколько в буфере накопилось на момент чтения. Т.к. у тебя известно только начало, то читать все что приходит и складывать в свой промежуточный буфер до появления начала следующего блока. И второй вариант - задать таймаут (вычислить опытным путем), если в течение него ничего не пришло, считать что это конец и больше ничего не придет. Ну и промежуточный буфер отдавать на обработку только после получения пакета целиком. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 16:27 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
Иван_2014, вы цыфирку 100 с потолка взяли? Если за 100 микросекунд очередной байт не успеет подойти - опять облом будет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 16:31 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
а мне больше нравится "производительность" такого решения. При 18 байтовых "пакетах" и задержки минимум в 100 ms на пакет, скорость в байт/сек не такая уж и большая. А вообще, конечно, все зависит от задачи и устройства. Для задачи типа просто набор номера на модеме - почему бы и нет. IMHO ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 16:43 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
100 микросекунд это не 100 миллисекунд. Это одна десятитысячная секунды. Примерно время передачи одного байта на скорости 115200. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 17:01 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
Иван_2014Каждый раз мне в буфер устройство шлёт разное количество данных) Но я точно знаю что первым байтом всегда будет 0xFE а дальше неопределённое количество но не больше 256...При таком потоке данных чтение можно заканчивать в двух случаях: 1. Получен 0xFE; 2. С последнего 0xFE получено 256 байт данных, не содержащих 0xFE. P.S. Правильное приложение будет учитывать, что возможна ошибка, когда 256 байт данных уже получено, данные продолжают поступать, но 0xFE в этих данных нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 18:33 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
Иван_2014Всё я решил проблему.... Удалось схалявничать хД))) Неудачное решение. Даже если десяток отладочных тестов прошло успешно. Про 100 мкс уже написали, чуть больше и получишь полпакета. Если пойдет два пакета подряд - прочитаешь как один. Все попытки привести асинхронный режим к синхронному с помощью таймаутов в лучшем случае дают тормоза, в худшем сбои и глюки. В твоем случае обязательно надо анализировать данные на соответствие протоколу обмена. PS Шутка с долей шутки: "Если программа выполняет мистические действия - значит вы написали что-то невероятно глупое". В твоем случае надо готовится к "мистике" )) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 18:35 |
|
||
|
COM порт, буфер чтения заполняется частями... Язык чистый C
|
|||
|---|---|---|---|
|
#18+
Всем спасибо большое за советы) Цифру эту я реально с потолка взял, взял и написал другую, и ещё кое - где добавил таймаутик ) И всё приходит как положено ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2014, 18:36 |
|
||
|
|

start [/forum/topic.php?fid=16&msg=38670956&tid=1341324]: |
0ms |
get settings: |
7ms |
get forum list: |
8ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
146ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
38ms |
get tp. blocked users: |
1ms |
| others: | 217ms |
| total: | 430ms |

| 0 / 0 |
