2012-03-13 1 views
3

Я чувствую, что это должно быть общим состоянием ошибки для последовательных коммуникаций, но мне еще предстоит увидеть хорошее решение.Последовательная запись в блокировке Linux, решение для синхронизации времени?

У меня установлен последовательный порт, который не блокируется, и я отключил управление потоком. Затем я использую Select, чтобы определить, когда я могу написать порт. Я пытаюсь написать большие буферы (больше размера страницы, 4 тыс., Что, по моему мнению, является количеством программной буферизации, предоставляемой порту). Первая часть записи будет проходить, но затем я блокирую попытку записать остальные, если последовательное соединение сломано или конечный потребитель отключен/перезагружен. Я думал о написании меньших фрагментов данных, но мне кажется, что в конце концов я наполним буфер и снова займусь этим случаем. Есть ли способ запросить доступный буфер до написания? Способ изменения размера буфера без перекомпиляции ядра?

Моя цель состоит в том, чтобы иметь возможность таймаута сбойной записи, чтобы я мог очистить и уведомить пользователя. Я не хочу, чтобы хвост неисправного сообщения прошел прямо, когда устройство возвращается. Последовательные настройки (бод, стоп-биты и т. Д.) Также могут меняться со временем, и я не хочу, чтобы они менялись, пока у меня может быть запись.

Я определил, что могу послать поток сигнал sigusr1, и это отменит текущую запись, но это не кажется таким изящным. Возможно, это предпочтительный метод? Также я изучил использование aio_write, но я никогда не использовал его раньше, и я не знаю его ограничений.

Если у кого-то есть хорошее решение для выхода из строя неудачных записей, мне было бы интересно услышать их. Благодарю.

EDIT: Я провел больше исследований, и мой вопрос был не совсем правильным. Я использовал последовательные порты psuedo, и запись на них вела себя иначе, чем реальные последовательные порты. Вопрос по-прежнему будет иметь значение, если вы включили управление потоком аппаратных средств или вам пришлось использовать последовательные порты psuedo.

+0

Устанавливая последовательного порта неблокирующем, вы имеете в виду, что вы установили дескриптор файла для неблокирования с вызовом fcntl() или флагом O_NONBLOCK для открытия()? – nos

+0

Я установил его на вызов, чтобы открыть. Считаете ли вы, что настройка fcntl приведет к разным результатам? – john

+0

Если дескриптор файла правильно настроен на блокировку, и все остальное сделано правильно, это звучит как ошибка ядра. Неблокирующий 'write' не должен блокироваться по какой-либо причине, периоду. – Kaz

ответ

1

Отправка потока сигнала - лучший способ сделать это, хотя я бы сделал это, используя timer для установки таймаута; если я правильно помню, это то, что я сделал в прошлом (pesudo-код):

timer_create(); 
int value = write(fd, buffer, buff_len); 
if(value < 0 && errno == EINTR) { 
    /* We were interrupted by a signal - write failed. */ 
}else if(value < 0){ 
    timer_delete(); 
    /* other error */ 
}else if(value != buff_len){ 
    timer_delete(); 
    /* did not write out entire buffer */ 
}else{ 
    timer_delete(); 
    /* Write should be good */ 
} 

см: http://pubs.opengroup.org/onlinepubs/009604499/functions/timer_create.html

+0

См. Мое редактирование выше. Это хорошее решение для записи с контролем аппаратного потока. Вы также можете временно отключить управление потоком в другом потоке, чтобы позволить байтам стечь. – john

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