2013-07-05 3 views
0

Я пытаюсь подключить сигнал и слот на C++, используя библиотеки boost. Мой код в настоящее время открывает файл и считывает данные с него. Тем не менее, я пытаюсь улучшить код, чтобы он мог читать и анализировать данные в реальном времени с помощью последовательного порта. Я бы хотел, чтобы функции анализа вызывались только один раз, когда есть данные, доступные в последовательном порту.Исходящий сигнал, когда байты принимаются в последовательном порту

Как бы я это сделал? Я делал это в Qt раньше, однако я не могу использовать сигналы и слоты в Qt, потому что этот код не использует их moc-инструмент.

+0

Какая ОС вы используете? –

+0

Я использую Ubuntu – user2554193

+0

Можете ли вы описать более подробно то, с чем вы на самом деле боретесь? Обнаружив, что вы получили что-то на последовательном порту, или как использовать 'boost :: signal', или что-то еще? –

ответ

0

Ваша ОС (Linux) предоставляет вам следующий механизм при работе с последовательным портом.

Вы можете установить свой последовательный порт в неканонический режим (путем снятия отметки ICANON с флагом в структуре termios). Затем, если параметры MIN и TIME в c_cc[] равны нулю, функция read() будет возвращать тогда и только тогда, когда в буфере ввода последовательного порта есть новые данные (подробности см. В справочной странице termios). Таким образом, вы можете запустить отдельный поток, отвечающий за получение входящего последовательных данных:

ssize_t count, bytesReceived = 0; 
char myBuffer[1024]; 
while(1) 
{ 
    if (count = read(portFD, 
     myBuffer + bytesReceived, 
     sizeof(myBuffer)-bytesReceived) > 0) 
    { 
    /* 
     Here we check the arrived bytes. If they can be processed as a complete message, 
     you can alert other thread in a way you choose, put them to some kind of 
     queue etc. The details depend greatly on communication protocol being used. 
     If there is not enough bytes to process, you just store them in buffer 
     */ 
     bytesReceived += count; 
     if (MyProtocolMessageComplete(myBuffer, bytesReceived)) 
     { 
       ProcessMyData(myBuffer, bytesReceived); 
       AlertOtherThread(); //emit your 'signal' here 
       bytesReceived = 0; //going to wait for next message 
     } 
    } 
    else 
    { 
    //process read() error 
    } 
} 

Основная идея здесь заключается в том, что поток вызова read() будет активна только при поступлении новых данных. В остальное время ОС сохранит этот поток в состоянии ожидания. Таким образом, он не будет потреблять процессорное время. Это зависит от вас, как реализовать фактическую часть signal.

В приведенном выше примере используется регулярный read системный вызов для получения данных из порта, но вы можете использовать класс boost таким же образом. Просто используйте функцию синхронного чтения, и результат будет таким же.

+0

спасибо. Как отключить флаг ICANON и установить параметры MIN и TIME в c_cc []? – user2554193

+0

Nevermind Я понял это. Поэтому в настоящее время я запускаю ваш код, но ни один из байтов на самом деле не печатается. Я открыл порт, который отлично работает, и установил все настройки так, как вы указали. Однако он не будет считывать данные. – user2554193

+0

Есть много вещей, которые следует учитывать при работе с последовательными портами. Вы должны установить одинаковые скорости передачи, бит данных и четность на обоих портах. Управление потоком лучше отключить, по крайней мере, для начальных испытаний. Все эти настройки выполняются в структуре termios. Для встроенных систем может потребоваться установить режим последовательного порта (RS232, RS485, RS422). Такие порты также будут иметь нестандартную компоновку контактов. Если все настроено правильно на обоих портах, которые вы используете, и данных по-прежнему нет, убедитесь, что отправляющее приложение действительно отправляет данные и что кабель правильно –

Смежные вопросы