crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

Белый пони
  опции профиля:
сообщение 17.3.2011, 16:51
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 9
Регистрация: 27.1.2011
Пользователь №: 2373

Спасибо сказали: 0 раз(а)




Репутация:   0  


Здравствуйте!

Столкнулся с проблемой, в ходе вычисления временного интервала с помощью rdtsc().
Вот программа, которая считывает значения, приходящие на последовательный порт и засекающая временные промежутки между их считванием:

dumb3.cpp
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <stdint.h>

extern __inline__ uint64_t rdtsc(); 

void SetSIO( int fd,
                  unsigned int BaudRate,   // B0 B50 ... B9600 B19200 B38400
                  unsigned int Parity,     // 1 ... 4 ( odd, even, mark, space)
                  unsigned int DataBits,     // CS5 ... CS8
                  unsigned int StopBits,     // 0 или 1 (1 или 2)
                  unsigned int FlowControl); // 0 .. 3 ( RTS/CTS,  XON/XOFF, both, none)

int main(void)
{
unsigned char R[50];  // read data
char key[1];

short bytesrd;
int fp;              // tty's descriptor

unsigned long ini, end;   // rdtsc() limits 


///////// keyboard settings, reserve copy of initial/////
 struct termios tp1;
 struct termios tp2;

  tcgetattr(0,&tp1);
  tp2=tp1;
  tp2.c_iflag&=~ICRNL;
  tp2.c_lflag&=~ICANON;
  tp2.c_lflag&=~ECHO;
  tp2.c_cc[VMIN ]=1;
  tp2.c_cc[VTIME]=0;
  tcsetattr(0,TCSANOW,&tp2);
////////////////////////////////////////////////////////

fp = open( "/dev/ttyS0", O_RDWR | O_NONBLOCK);
SetSIO( fp, B9600, 0, CS8, 0, 3);

fd_set set0, set;      // forming set of COM and keyboard descriptors
FD_ZERO( &set);
FD_SET( fp, &set);
FD_SET(  0, &set);
set0 = set;

ini = rdtsc();
while(1)
    {
    if ( select( fp+1, &set, NULL, NULL, NULL ) > 0)
        {
        if( FD_ISSET( fp, &set))
            { 
            bytesrd = read( fp, R, 1);            
                        if( bytesrd == -1){ printf("\ninit oi!!!"); break;}            
            end = rdtsc();
            printf("%2X %li \n", R[0], (end - ini)/3000 ); // примерная частота процессора в МГц
            ini = end;
            }

        if( FD_ISSET( 0, &set) )    
            { 
            bytesrd = read( 0, key, 1);
            if ( bytesrd != -1 )printf(" %c pressed. \n", key[0]);
            if( key[0] == 27){ break;}
            }
        }
    
    set = set0;    
    }
tcflush( fp, TCIOFLUSH);
tcsetattr(0,TCSANOW,&tp1);   // restore keyboard settings

close(fp);
printf("\n");
}


extern __inline__ uint64_t rdtsc() {
   uint64_t x;
   __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
   return x;
 }
(процедура SetSIO - настраивает параметры com-порта, она громоздкая и мне кажется, к проблеме отношения не имеет. Но если что - могу и её запостить)

Cигналы принимаются от девайса с известными интервалами - 10 раз в секунду пачками по 9 байт. перед первый байтом пачки - большая пауза, примерно 95 мс.
Проблема в том, что эта самая программа, будучи запущения разными способами, выдаёт разные временные промежутки:

При запуск в терминале графической оболочки Gnome ("./dump3") в терминал выводится:
1
//пришедший байт, временной интервал после предыдущего байта в микросекундах
2 96434
4 22
F4 8
0 8
30 7
13 7
4 7
EF 7
0 3935
2 96471
4 23
F4 8
0 8
30 7
13 7
4 7
EF 7
0 3971
2 96436
4 22
F4 8
0 8
30 8
13 7
4 7
EF 7
0 3968
...

При запуске в терминале без графической оболочки (Cntrl+Alt+F1 в Убунту) в терминал выводится:
2
2 96464
4 231
D0 240
0 239
30 227
13 227
4 227
CB 225
0 2398
2 96461
4 233
D2 238
0 238
30 225
13 225
4 224
CD 224
0 2406
...


При запуске в том же терминале без графической оболочки с направлением вывода не в консоль, а в файл ( "./dump3.cpp > yyy.txt"):
3
2 29861
4 49
54 5
0 4
30 4
13 4
4 4
50 4
0 3934
2 96454
4 5
54 4
0 4
30 4
13 4
4 4
50 4
0 3986
2 96463
4 5
54 4
0 4
30 4
13 4
4 4
50 4
0 3986

Откуда такие различия?
И где значения ближе к правде?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
Iron Bug
  опции профиля:
сообщение 22.3.2011, 17:48
Сообщение #2


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


ну, значит у тебя программа сама тормозит. попробуй сделать два потока и в одном (с высоким приоритетом) читать данные и складывать в какой-то буфер(чтобы было быстро), а в другом (с более низким приоритетом) считывать буфер и переносить куда угодно - в консоль или в файл. ну или если девайс работает недолго, то накапливать данные и потом в конце программы их выводить.
у тебя ini = end; после printf идёт, а это не есть гут. ибо printf может тормозить.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Белый пони
  опции профиля:
сообщение 23.3.2011, 16:04
Сообщение #3


Новичок


Группа: Новичок
Сообщений: 9
Регистрация: 27.1.2011
Пользователь №: 2373

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Iron Bug @ 22.3.2011, 17:48) *
ну, значит у тебя программа сама тормозит. попробуй сделать два потока и в одном (с высоким приоритетом) читать данные и складывать в какой-то буфер(чтобы было быстро), а в другом (с более низким

приоритетом) считывать буфер и переносить куда угодно - в консоль или в файл. ну или если девайс работает недолго, то накапливать данные и потом в конце программы их выводить.
у тебя ini = end; после printf идёт, а это не есть гут. ибо printf может тормозить.


Для проверки считываю 90 значений сначала в массив и только после закрытия порта - вывожу в консоль:
gettime2.cpp
...
int main(void)
{
unsigned char R[50];  // read data
for( int i = 0; i < 50; i++ ) R[i] = 0xFF;
char key[1];

short bytesrd;
int fp;              // tty's descriptor

unsigned long ini, end;   // rdtsc() limits 

unsigned char    byteArray[90];
unsigned long   rdtscArray[90];
unsigned long gettimeArray[90];

struct timespec Ini;
struct timespec End;

Ini.tv_sec = Ini.tv_nsec = End.tv_sec = End.tv_nsec = 0;

///////// keyboard settings, reserve copy of initial/////
 struct termios tp1;
 struct termios tp2;

  tcgetattr(0,&tp1);
  tp2=tp1;
  tp2.c_iflag&=~ICRNL;
  tp2.c_lflag&=~ICANON;
  tp2.c_lflag&=~ECHO;
  tp2.c_cc[VMIN ]=1;
  tp2.c_cc[VTIME]=0;
  tcsetattr(0,TCSANOW,&tp2);
////////////////////////////////////////////////////////

fp = open( "/dev/ttyS0", O_RDWR | O_NONBLOCK);
SetSIO( fp, B9600, 0, CS8, 0, 3);

fd_set set0, set;      // forming set of COM and keyboard descriptors
FD_ZERO( &set);
FD_SET( fp, &set);
FD_SET(  0, &set);
set0 = set;

ini = rdtsc();
clock_gettime( CLOCK_MONOTONIC, &Ini);
unsigned short i = 0;
tcflush( fp, TCIOFLUSH);
while( i < 90)
    {
    if ( select( fp+1, &set, NULL, NULL, NULL ) > 0)
        {

        if( FD_ISSET( fp, &set))
            { 
            bytesrd = read( fp, R, 1);            
                if( bytesrd == -1){ printf("\ninit oi!!!"); break;}
                if( R[1] != 0xFF ){ printf("\nbuffer stuck: %2x %2X %2X", R[1], R[2], R[3]);}                                            
            end = rdtsc();
            clock_gettime( CLOCK_MONOTONIC, &End);
            //printf("%2X %li  %li\n", R[0], (end - ini)/3014, (End.tv_nsec - Ini.tv_nsec)/1000 );
            
               byteArray[i] = R[0];            
              rdtscArray[i] = (end - ini) / 3014;
            gettimeArray[i] = (End.tv_nsec - Ini.tv_nsec) / 1000;
            
            ini = end;
            Ini.tv_nsec = End.tv_nsec;
            i++;
            }

        if( FD_ISSET( 0, &set) )    
            { 
            bytesrd = read( 0, key, 1);
            if ( bytesrd != -1 )printf(" %c pressed. \n", key[0]);
            if( key[0] == 27){ break;}
            }
        }
    
    set = set0;    
    }
tcflush( fp, TCIOFLUSH);
tcsetattr(0,TCSANOW,&tp1);   // restore keyboard settings
close(fp);

for( i = 0; i < 90; i++) printf("%2X\t%li\t%li\t%X\t%X\n", byteArray[i], rdtscArray[i], gettimeArray[i], rdtscArray[i], gettimeArray[i]);
printf("\n");
}
...

При всех трёх вариантах запуска выдаются примерно одинаковые интервалы ( в этот раз распечатал значения интервалов ещё и в hex):
Раскрывающийся текст
 2    77903    77890    1304F    13042
 5    6    5    6    5
AF    4    4    4    4
 0    4    4    4    4
30    4    4    4    4
13    4    4    4    4
 5    4    4    4    4
A9    4    4    4    4
 0    7948    7948    1F0C    1F0C
 2    92007    92001    16767    16761
 5    5    4    5    4
AF    4    4    4    4
 0    4    4    4    4
30    4    4    4    4
13    4    4    4    4
 5    4    4    4    4
A9    4    4    4    4
 0    7965    7965    1F1D    1F1D
 2    92006    92000    16766    16760
 5    4    4    4    4
AF    4    4    4    4
 0    4    4    4    4
30    4    4    4    4
12    4    4    4    4
 5    4    4    4    4
A9    4    4    4    4
 0    7967    7966    1F1F    1F1E
 2    92010    92000    1676A    16760
 5    4    4    4    4
AF    4    4    4    4
 0    4    4    4    4
30    4    4    4    4
13    4    4    4    4
 5    4    4    4    4
A9    4    4    4    4
 0    7968    7968    1F20    1F20
 2    92002    92000    16762    16760
 5    4    4    4    4
AF    4    4    4    4
 0    4    4    4    4
30    4    4    4    4
13    4    4    4    4
 5    4    4    4    4
A9    4    4    4    4
 0    7969    7967    1F21    1F1F
 2    92014    92000    1676E    16760
 5    4    4    4    4
AF    4    4    4    4
 0    4    4    4    4
30    4    4    4    4
13    4    4    4    4
 5    4    4    4    4
A9    4    4    4    4
 0    8015    8016    1F4F    1F50
 2    91969    91970    16741    16742
 5    6    6    6    6
AF    4    4    4    4
 0    4    4    4    4
30    4    4    4    4
13    4    4    4    4
 5    4    4    4    4
A9    4    4    4    4
 0    7948    7946    1F0C    1F0A
 2    92011    -908001    1676B    FFF2251F
 5    5    5    5    5
AF    4    4    4    4
 0    4    4    4    4
30    4    4    4    4
13    4    4    4    4
 5    4    4    4    4
A9    4    4    4    4
 0    7968    7968    1F20    1F20
 2    92007    92002    16767    16762
 5    4    4    4    4
AF    4    4    4    4
 0    4    4    4    4
30    4    4    4    4
13    4    4    4    4
 5    4    4    4    4
A9    4    4    4    4
 0    7966    7965    1F1E    1F1D
 2    92009    92000    16769    16760
 5    4    4    4    4
AF    4    4    4    4
 0    4    4    4    4
30    4    4    4    4
12    4    4    4    4
 5    4    4    4    4
A9    4    4    4    4
 0    7968    7968    1F20    1F20

Видимо именно printf, действительно, всё задерживал. Причём в текстовой консоли он тормозил больше. И это мне не понятно :( Я думал без графической оболочки всё должно работать быстрее наоброт.

А ещё непонятно, откуда в gettime вылезло отрицательно значение ( см. вывод выше):
Цитата
13 4 4 4 4
5 4 4 4 4
A9 4 4 4 4
0 7948 7946 1F0C 1F0A
2 92011 -908001 1676B FFF2251F
5 5 5 5 5
AF 4 4 4 4

вроде бы до переполнения переменной ещё полтора старших байта осталось :mellow:.

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме


Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 21.6.2025, 7:02