Программирование com-портов. Изменение буфера r/w FIFO?

Доброго времени суток.


Ваяем тут одну железяку с кучей СОМ-портов, работающую под линем. И для отладки драйверов и железа ваяю программу тестирования СОМ-портов. Чтобы не изобретать велосипед за основу была взята программа linux-serial-test.


Эмпирическим путём мы поняли, что при передаче данных в порт, они записываются в промежуточный буфер, а от туда уже передаются в СОМ-порт (америку мы не открыли, просто открыли размер этого буфера). Оказалось, что он занимает 4 килобайта. Получается забавная вещь, что вызывая процедуру передачи данных, по готовности порта пример кода
void process_write_data()
{
	int count = 0;
	unsigned char write_data[1024] = {0}; //буфер 1 килобайт
	while (1) {
		int i;
		for (i = 0; i < sizeof(write_data); i++) { //заполняем буфер данными
			write_data[i] = _write_count_value;
			_write_count_value++;
		}

		int c = write(_fd, &write_data, sizeof(write_data));

		if (c > 0) {
			_write_count += c;
			count += c;
		}
		if (c < sizeof(write_data)) { //проверяем всё ли передали?
			_write_count_value -= sizeof(write_data) - c;
			break; //да, всё, выходим из цикла
		} else {
			count += c;
		}
	}
}




Мы не можем быть уверенны в том, что данные передались. Фактически получается так, что система нам говорит о готовности передачи, мы укладываем туда данные, а фактически мы укладываем 4 килобайта внутреннего буффера, и данные ещё даже не начали передаваться.

Внимание вопросы:
1. Возможно ли изменить с помощью, например, ioctl размер буфера записи/чтения (драйвер пока перепахивать не очень хочется)?
2. Есть ли возможность сделать более real time передачу через СОМ-порт (со стороны user space и kernel space)?
  • Вопрос задан
  • 10437 просмотров
Пригласить эксперта
Ответы на вопрос 5
Ariman
@Ariman
Доки на драйвер говорят, что буферы не более 64 байт, а обычно и вовсе 16.
Килобайтные буферы, если они и есть, находятся выше собственно драйвера последовательного порта.
Ответ написан
Ariman
@Ariman
Это буфер TTY, вот чего.
Строка 51 include/linux/tty.h
По умолчанию — одна страница. Задать индивидуально для ком порта вы не сможете, как я понимаю, только изменить глобальный размер TTY во всей системе. Но можно попробовать подергать этот самый tty_wait_until_sent, чтобы понять, когда данные из буфера ушли в железо.
Ответ написан
В коде драйверов COM-портов для Java, например в PureJavaComm, встречал очень простой способ: смотрим скорость передачи и делим на неё размер данных. Получаем время, которое нужно подождать до завершения передачи.

rs232 ну очень примитивный протокол. Передача идёт постоянно, с одной и той же скоростью, пока в буфере есть данные. И не важно, подключено ли к порту устройство, которое эти данные получает. Способа определить наличие устройства нет.

Ну а размер буфера указать можно, так же как и и узнать переданы ли все данные из буфера. Сказать какие ioctl использовать, к сожалению, не могу. Но разобраться довольно легко. Для примера, как это делается, можно заглянуть в код PureJavaComm — там есть соответствующие вызовы.
Ответ написан
Мда, а размер буфера PureJavaComm не устанавливает.
Ответ написан
Комментировать
Ariman
@Ariman
(Случайно дублировался пост)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы