The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Оптимизация алгоритма чтение данных с компорта"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (C/C++)
Изначальное сообщение [ Отслеживать ]

"Оптимизация алгоритма чтение данных с компорта"  +/
Сообщение от TITO (ok) on 02-Мрт-11, 11:47 
Здравствуйте уважаемые. Я хочу попросить вас помочь мне в оптимизации моей программки для чтения данных с ком порта. На данный момент меня не устраивает сам алгоритм который я использую в программе для чтения, так как он использует циклы которые грузят процессор до 5-6% что является не оптимальным. Не могли бы вы мне помочь изменить алгоритм. Скорость ком порта 4800 режим 8N1 пакет состоит из 16 байт вида CADR01234567891011. Пакеты приходят каждые 0.1 секунд. У меня проблема в том чтобы оптимально собрать его(пакет) в массив с которым я мог бы дальше работать в программе. Если вы подскажете мне как это сделать, я буду вам очень благодарен.

Привожу текст моей программы:
Функция read_device (читает данные с ком порта)

char read_device(fd,ch)
{
   unsigned char s[1];
   int nBytes;
  
   nBytes = read(fd, s, sizeof(s));
   if(nBytes>0){    // если прочитали нормальные данные то вернем их
      ch=s[0];
      return ch;
   }
  
  
   return 0; // иначе вернем 0
}

Main:

int main(int argc, char** argv)
{
  int speed = 4800,rBytes;
  unsigned char ch,devname[256];
  
  
  
  filelog=fopen("MVS_logfile.txt","w");    // создаем лог файл
  if(!filelog){
     printf("Cant create file with logs!\n");
     exit(1);
  }
  ////////////////////////////////////////////////
  strcpy(devname, "/dev/ttyUSB0");

  int c, fd, cfd;
  if (argc > 1) {    // открываем девайс
    while (1) {
      c = getopt (argc, argv, "d:s:");
      if (c == -1)
    break;
      switch (c) {
      case '\0':
    fprintf(stderr,"Error: Unknown command ");
    print_help ();
    return -1;
      case 'h':
    print_help ();
     return 0;
    break;
      case 's':
    speed = atoi(optarg);
    break;
      case 'd':
    strcpy (devname, optarg);
    break;
      default:
    print_help ();
    return 0;
      }
    }
  }
  set_signal ();
  if( (fd = opendevice(devname, speed)) < 0) {
    fprintf(stderr,"FATAL ERROR: Can not open %s\n",devname);
    exit(-1);
  }
  }
  
  
///////////// Start read device /////////////////////////////
  while((!stop))
  {
    ch=read_device(fd,ch);
    
    if(ch=='R'){ // выбираем данные каналов из потока
      for(rBytes=0;rBytes<12;rBytes++){    // читаем 12 байт данных из потока
    ch=read_device(fd,ch);
    if(ch!=0)
      databuf[rBytes]=ch;        // если read_device вернула не 0, пишем байт в массив данных
    else{
      usleep(6200);                      // спим
      rBytes--;                              // вычитаем индекс массива так как 0 нам не нужен
    }
      }
      
      crtfile(databuf,rBytes,&filelog); // функция обработки данных собранных в массив
    
     }
    
  }
  

  closedevice(fd);
  fclose(filelog);
  
  
  return 0;
}
Настройки ком порта:

int opendevice(char* device, int speed)
{
  struct termios new;
  speed_t sspeed;
  int res = 0, fd = 0;
  if(( fd = open(device, O_RDWR | O_NDELAY | O_NOCTTY)) < 0){
    perror("Can not open device");    
    return -1;
  }
  //ttyUSBx settings
  
         sspeed = B4800;

  memset (&new, 0, sizeof (new));
  cfmakeraw(&new);
  new.c_cflag &= ~PARENB; // parent bit
  new.c_cflag &= ~CSTOPB;
  new.c_cflag &= ~CSIZE; // 1 stop bit
  new.c_cflag  = CS8;     // 8bit data
  new.c_cflag |= CREAD;  // Enable Receiver
  new.c_cflag |= CLOCAL; // Ignore modem control lines.
  new.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
  new.c_oflag &= ~OPOST;
  new.c_cc[VMIN] = 1;    // 1 simbols for read
  new.c_cc[VTIME] = 1;    // Time of reading of 1 symbol  


  res = cfsetispeed(&new, sspeed); //baud rate 4800
  if (res<0){
    perror("Can not set speed of device");
    return -1;
  };

      
  tcflush(fd, TCIOFLUSH);
  res = tcsetattr(fd, TCSAFLUSH, &new);
  if (res<0){
    perror("Can not set attribute to device");
    return -1;
  };
  return fd;
}

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Оптимизация алгоритма чтение данных с компорта"  +/
Сообщение от pavlinux (ok) on 03-Мрт-11, 01:54 
> Если вы подскажете мне как

Всё нормально, проверил, программа работает!

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

2. "Оптимизация алгоритма чтение данных с компорта"  +/
Сообщение от DeadLoco (ok) on 03-Мрт-11, 21:06 
>[оверквотинг удален]
>       databuf[rBytes]=ch;      
>     else
>     {
>       usleep(6200);      
>       rBytes--;      
>     }
>   }
>       crtfile(databuf,rBytes,&filelog);
>  }
>}

Я так понимаю, нагрузка именно в этом цикле, и по микрослипу. А зачем он вообще нужен?

Посмотрите код tip.c из FreeBSD: http://www.freebsd.org/cgi/cvsweb.cgi/src/usr.bin/tip/tip/ti... - функцию tipin(void)

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

3. "Оптимизация алгоритма чтение данных с компорта"  +/
Сообщение от Alex_S (??) on 08-Мрт-11, 02:16 
> Здравствуйте уважаемые. Я хочу попросить вас помочь мне в оптимизации моей программки
> для чтения данных с ком порта. На данный момент меня не
> устраивает сам алгоритм который я использую в программе для чтения, так
> как он использует циклы которые грузят процессор до 5-6% что является
> не оптимальным. Не могли бы вы мне помочь изменить алгоритм. Скорость
> ком порта 4800 режим 8N1 пакет состоит из 16 байт вида
> CADR01234567891011. Пакеты приходят каждые 0.1 секунд.

а почему бы не использовать select() с таймаутом ?
  

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру