Аномалия последовательной связи в Linux? - PullRequest
1 голос
/ 16 июля 2009

Я использую вызов select для связи с внешней подсистемой (протокол для нее был предоставлен и реализован как поток Qt) через последовательный порт RS232. У нас нет аппаратного обеспечения для внешних систем, и поэтому мы разработали собственные симуляторы, использующие .Net 2.0 и C #, чтобы имитировать поведение базового оборудования подсистемы. Есть 5 разных подсистем, которые общаются с нашим приложением. Каждый интерфейс для подсистемы реализован как поток Qt. Поскольку это не приложение реального времени, и у нас нет реального оборудования, когда мы общаемся с помощью симуляторов, все системы находят работу в течение 24 часов или около того, и после этого связь идет вверх и вниз, и, в конечном счете, вся связь прерывается, когда я перезагружаю тренажер без закрытия приложения, все становится хорошо. Почему это происходит?

Полагаю, поскольку .Net / C # не является платформой реального времени, а также после того, как симуляторы работают в течение 24 часов, скорость отправки данных начинает снижаться, что вызывает засорение последовательных портов; перезапуск сбрасывает все и, таким образом, все возвращается в нормальное состояние. Это всего лишь предположение. Если у кого-то есть лучшее мнение, поделитесь им. Обратите внимание, что симуляторы были сделаны другой командой .Net парней.

Примечание. Каждый протокол имеет разные скорости передачи данных: 1 Гц, 5 Гц, 10 Гц.

Существует одна система, которая просто не возобновляет связь даже после того, как симулятор перезапускается после перезагрузки. Конфигурация порта для этой системы

SetPortConfiguration()
{
    tcgetattr(Fd,&mOldtio); 
       mNewtio.c_cflag = B4800 | CS8 | CLOCAL | CREAD | CRTSCTS;
       mNewtio.c_iflag = 0; //setting the input flag to icrnl causes a blank frame to be displayed after every frame.
       mNewtio.c_oflag = 0;
       mNewtio.c_lflag =ICANON;
       mNewtio.c_cflag &=~PARENB;
       mNewtio.c_cflag &= ~CSTOPB;
        //mNewtio.c_cflag &= ~HUPCL;  //added on 24/3/09
       mNewtio.c_cc[VEOL]=0; //setting VEOL to '\r' or '\n' causes a blank frame to be displayed after every frame.
       mNewtio.c_cc[VKILL] = 0;     /* @ */
       mNewtio.c_cc[VSTART] = 0;     /* Ctrl-q */
       mNewtio.c_cc[VSTOP]  = 0;     /* Ctrl-s */
       mNewtio.c_cc[VMIN]=0;
       mNewtio.c_cc[VTIME]=0;
       tcflush(Fd, TCIFLUSH);
       tcflow(Fd,TCION);
       tcsetattr(Fd,TCSANOW,&mNewtio);
}

Также есть функция сброса порта:

ResetPort()
{
    tcflush(Fd, TCIFLUSH); //flush all data received but not read

    tcflow(Fd,TCIOFF); //transmits a STOP character, which stops the terminal device from transmitting data to the system 
    tcsetattr(Fd, TCSANOW, &mOldtio);//set the old terminal settings

    ClosePort(); //close port
    OpenPort(mStrPortNo); //open the port specified by port number and in read mode
    SetPortConfiguration();
}

Если есть какой-либо разрыв в коммуникации, я вызываю функцию ResetPort, которая закрывает и снова открывает порт. Это решает проблему во всех случаях, кроме одной системы, скажем, XYZ. Система XYZ отправляет данные в формате NMEA с каждым пакетом в виде строки данных, оканчивающейся комбинацией возврата каретки, LineFeed.

Кто-нибудь знает, в чем может быть проблема?

Ответы [ 2 ]

1 голос
/ 16 июля 2009

Бит .Net real time - красная сельдь. Последовательные порты настолько медленные, что 8086 может их контролировать. Любой современный процессор, скорее всего, будет иметь запасные циклы, даже при 115200 бод. Даже если это не так, глубина буферов RS232 обычно измеряется в миллисекундах, а не часах.

«Засорение» последовательных портов слишком сильно продвигает физические аналогии.

Трудно точно понять, что является причиной вашей проблемы, потому что вы на самом деле не сказали нам, что это такое. «Разрушение» - это не то, что мы можем решить. Байты потеряны, пишет тайм-аут - к такому конкретному поведению мы можем обратиться.

0 голосов
/ 17 июля 2009

Я решил проблему. Мои извинения, если я не смог понять мою точку зрения. Ранее мы использовали обработку сигналов для последовательного взаимодействия с каждой системой, подключенной к выделенному последовательному порту, эта конструкция была ошибочной с самого начала, так как обработчик сигналов в нашем случае был слишком сложным. В идеале обработчик сигнала должен просто устанавливать некоторые флаги, он не должен включать вызовы функций, поскольку могут возникнуть проблемы с синхронизацией, которые могут быть обработаны, тогда он превращается в снежный кошмар синхронизации, который трудно отладить, как я обнаружил в моем приложении. Такая конструкция приводит к потере пакетов, поступающих от последовательных портов. Чтобы справиться с этой ситуацией, мы использовали функцию сброса порта, которая была грубым способом исправить проблему потери пакетов. Я удалил обработчик сигнала и использовал выбор вызова для отдельных систем. Но не сбросил порт сброса, который был частью более раннего дизайна. При отладке я обнаружил, что resetport - ложная функция, и сбросил ее. Вуаля !! теперь все работает отлично. На записи, мой совет всем, кто использует последовательную связь на платформе linux для использования системного вызова select. Вы освобождаетесь от обработки деталей последовательной связи и просто концентрируетесь на обработке входящих пакетов.

Надеюсь, это решение поможет всем, кто работает над последовательной связью на платформах linux / unix. Литературы по этому вопросу не так много, и весь поиск в сети приведет вас к некоторым документам, которые, хотя и хороши, не очень помогают в практических приложениях. Я признателен за помощь, предложенную всеми участниками stackoverlow, которая дала мне немыслимые перспективы взглянуть на проблему под рукой. Спасибо, ребята, ура !!!!!!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...