Страниц: [1]
  Печать  
Автор Тема: Чтение с последовательного порта  (Прочитано 4034 раз)
Fregl
Sr. Member
****
Offline Offline

Сообщений: 396


Просмотр профиля
« : Июня 18, 2010, 05:55:00 pm »

Такая проблема, нужно постоянно считывать с последовательного порта данные NMEA,
но столкнулся с тем, что через пару тройку операций чтения полных строк NMEA, read
начинает возвращать только строки длиной 8 байт.
Пример работы программы выложен ниже
Код:
# ./sgpstime
GPS Time server 0.1 started
/dev/ser1 opened
Starting serial port reading
Waiting for clients
FTXTµU5gE
$PSRFTXT,CLK:  95200
$PSRFTXT,CHNL: 12
$GPGGA,134950.000,4956.1285,N,03621.6479,E,1,06,1.4,174.0,M,16.8,M,,0000*52
$GPGSA,A,3,17,27,15,28,11,08,,,,,,,2.5,1.4,2.1*36
$GPRMC,134950.000,A,4956.1285,N,03621.6479,E,0.13, read 256 bytes - parsing
28.97,180610,,*3B
$PSRFTXT,Version:GSW3.2.4_3.1.00.12-SDK003P1.00a
$PSRFTXT,Version2:F-GPS-03-0701231
$PSRFTXT,WAAS Disable
$PSRFTXT,TOW:  481804
$PSRFTXT,WK:   1588
$PSRFTXT,POS:  3312586 2438752 4858319
$PSRFTXT,CLK:  95203
$GPGGA,134951.000,495 read 256 bytes - parsing
6.1289,N,03621.6472,E,1,04,2.1,173.9,M,16.8,M,,0000*5E
$GPGSA,A,3,17,27,28,11,,,,,,,,,2.4,2.1,1.0*3F
$GPRMC,134951.000,A,4956.1289,N,03621.6472,E,0.17,144.17,180610,,*0A
$PSRFTXT,Version:GSW3.2.4_3.1.00.12-SDK003P1.00a
$PSRFTXT,Version2:F-GPS-03-07012 read 256 bytes - parsing
31
$PSRFTXT,WAAS Disable
$PSRFTXT,TOW:  481805
$PSRFTXT,WK:   1588
$PSRFTXT,POS:  3312586 2438751 4858319
$PSRFTXT,CLK:  95204
$PSRFTXT,CHNL: 12
$GPGGA,134951.999,4956.1290,N,03621.6476,E,1,04,2.1,173.4,M,16.8,M,,0000*56
$GPGSA,A,3,17,27,28,11,,,,, read 256 bytes - parsing
,,,,2.4,2.1,1.0*3F
$GPRMC,134951.999,A,4956.1290,N,03621.6476,E,0.24,300.77,180610,,*0B
$PSRFTXT,Version:GSW3.2.4_3.1.00.12-SDK003P1.00a
$PSRFTXT,Version2:F-GPS-03-0701231
$PSRFTXT,WAAS Disable
$PSRFTXT,TOW:  481806
$PSRFTXT,WK:   1588
$P read 246 bytes - parsing
SRFTXT,P read 8 bytes - parsing
OS:  331 read 8 bytes - parsing
2585 243 read 8 bytes - parsing
8751 485 read 8 bytes - parsing
8319
$P read 8 bytes - parsing
SRFTXT,C read 8 bytes - parsing
LK:  952 read 8 bytes - parsing
07
$PSR read 8 bytes - parsing
FTXT,CHN read 8 bytes - parsing
L: 12
$ read 8 bytes - parsing
PSRFTXT, read 8 bytes - parsing
Baud rat read 8 bytes - parsing
e: 4800  read 8 bytes - parsing

$GPGGA read 8 bytes - parsing
,134953. read 8 bytes - parsing
000,4956 read 8 bytes - parsing
.1290,N, read 8 bytes - parsing
accept() error : Interrupted function call
closing all used ports
вот исходник
Код:
void * com_scan_proc(void * p)
{
ssize_t read_bytes;
uint8_t read_buffer[256];
while(1)
{
read_bytes = read(com_fd,&read_buffer,256);
if(read_bytes<=0)
{
fprintf(stderr,"%s read() error : %s\n",port_name,sys_errlist[errno]);
exit(-1);
}
else
{
read_buffer[read_bytes]=0;
printf("%s read %d bytes - parsing\n",read_buffer,read_bytes);
// pthread_mutex_lock(&mutex);
// Parser->ParseBuffer(read_buffer,read_bytes);
// pthread_mutex_unlock(&mutex);
}
}
}
вот инициализация и запуск
Код:
if((com_fd = open(port_name,O_RDONLY | O_NOCTTY))==-1)
{
fprintf(stderr,"serial port open() error : %s\n",sys_errlist[errno]);
return errno;
}

struct termios options;
tcgetattr(com_fd, &options);
cfsetispeed(&options, B4800);
cfsetospeed(&options, B4800);
options.c_cflag |= (CLOCAL | CREAD);
if(tcsetattr(com_fd, TCSANOW, &options)!=0)
{
fprintf(stderr,"serial port tcsetattr() error : %s\n",sys_errlist[errno]);
return errno;
}

printf("Starting serial port reading\n");
pthread_create(&tid,NULL,&com_scan_proc,NULL);
В программе два потока, в основном еще серверный сокет который принимает соединения и возвращает немного данных клиенту, после чего закрывает клиентский сокет.
Во втором потоке собственно идет чтение с последовательно порта.
Записан
Fregl
Sr. Member
****
Offline Offline

Сообщений: 396


Просмотр профиля
« Ответ #1 : Июня 21, 2010, 11:45:43 am »

никаких советов и идей? все так запущено на форуме?
Записан
lastcross
Full Member
***
Offline Offline

Сообщений: 241


Просмотр профиля
« Ответ #2 : Июня 21, 2010, 12:17:56 pm »

А сколько по вашему он должен считывать?
read не зря возвращает количество прочитанных байт (сколько было готов на момент чтения).
Собирайте в кучу - и парсте на здоровье.
Записан
qnxloder
Sr. Member
****
Offline Offline

Сообщений: 292


Просмотр профиля
« Ответ #3 : Июня 21, 2010, 12:19:42 pm »

Похоже первые несколько итераций идет чтение из буфера драйвера, поэтому читает по 256 байт, а потом по таймауту или по промежутку между 8 байтами... Можно попробовать настроить поля с_сс структуры termios...
Записан
lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #4 : Июня 21, 2010, 02:05:55 pm »

Да, это нормально. Вычитывай до символа перевода строки и только потом отдавай на парсинг наверх.
Записан

Fregl
Sr. Member
****
Offline Offline

Сообщений: 396


Просмотр профиля
« Ответ #5 : Июня 21, 2010, 02:55:27 pm »

да так и сделал. впрочем как оказалось для парсинга gps не обязательно передавать всю строку целиком...
я сначала думал что контроллер gps будет слать мне строки целиком, скорее всего это он не делает.
вобщем задачка решена.
Записан
Страниц: [1]
  Печать  
 
Перейти в: