LINUX.ORG.RU

Потеря байт при обмене по rs-232

 ,


0

1

Всем привет! Собственно, задачка с прежними условиями (ком-порт 8N1, без контроля четности, 115200 бод). Железка обменивается данными с ПК. Смотрим картинку обмена на логическом анализаторе. Данные выдаю кодограммами из 12 байт ( write (fd, buf,12) ). Иногда возникает ситуация, что при выдаче от ПК кодограмма из нескольких байт разрывается на части, интервалы между частями кодограммы варьируются от 100 мкс до 1,5 мс (на картинке эти разрывы показаны красными стрелками). Сигнал RTS при этом живет своей жизнью и сбрасывается значительно раньше (сброс RTS показан синей стрелкой). C чем такое может быть связано? Или такие разрывы правомерны в работе порта? [IMG]http://s019.radikal.ru/i640/1403/b4/801bfa6d497ct.jpg[/IMG]

Код записи в порт:

	ioctl ( fd, TIOCMGET, &status ); 
	status = TIOCM_RTS;
	ioctl ( fd, TIOCMBIS, &status );
	ioctl ( fd, TIOCMGET, &status );
	
	while ( !(status&TIOCM_CTS) && (cntWr < 10) )
	{
		cntWr++;
		status = TIOCM_RTS;
		ioctl ( fd, TIOCMBIS, &status );
 		ioctl ( fd, TIOCMGET, &status );
	}
	if ( !(status&TIOCM_CTS) ) return 1;
	

	write ( fd, buf, len );


	do       
    {
    	ioctl ( fd, TIOCSERGETLSR, &status );
    } while ( !(status & TIOCSER_TEMT) ); 

	status |= TIOCM_RTS;
	ioctl ( fd, TIOCMBIC, &status );


Попробуй вместо fd записать данные просто в файл для начала, все ли нужные данные будут в файле?.

Dron ★★★★★
()

Что-то не понял, от асинхронного интерфейса ты хочешь синхронности?

Короче, внутри фрейма сигнал меняется раз в 1/бод секунд, интервалы между фреймами - любые.

hvatitbanit
()

Если RTS падает, это значит, что DTE (компьютер) не хочет принимать данные. А на передачу это никак не влияет.

Однако у тебя CTS падает, а вот это уже означает, что DCE не хочет принимать данные от компьютера. Может быть поэтому и прерывается передача.

Вообще непонятно, почему у тебя RTS и CTS дергаются. У нынешних микросхем буферы по 16 байт. В твоем случае вообще переполнения никогда не должно наступать. Может быть ты какой-то полудуплексный режим настраиваешь? Если так, то это не нужно.

Вообще в твоем случае можно попытаться вообще не использовать RTS и CTS. Даже вообще оторвать их. Тогда на CTS желательно подать положительное напряжение. Можно подать с DTR. Это на стороне компа. А на стороне устройства, хз, как у тебя там. На крайняк тоже с DTR. Ну или программно игнорировать аппаратный контороль переполнения.

anto215 ★★
()

Ненависть ~:-(

ioctl, write

Нет ни одной проверки возвращаемого значения после вызова функций.

pathfinder ★★★★
()

А вообще ТС должен ещё раз внимательно прочитать ман по функции write(), особенно в части возвращаемых значений. Меньше будет его код содержать необоснованных предположений.

pathfinder ★★★★
()

а где про потери байт-то?

посмотрел свою последнюю поделку про передачу через rs232 не увидел ни одного

ioctl ( fd, TIO-bla-bla-bla

yax123 ★★★★★
()

ты когда write делаешь понимаешь что оно может записать меньше чем ты хочешь?

quest ★★★★
()
Ответ на: комментарий от anonymous

МСВС 12.1 (на основе Линух 2.4.32).

За ссылочку спасибо, в 9.6 подтверждается возможность интервалов между байтами в асинхронном режиме: «синхронный обмен означает, что байты посланы с постоянной скоростью один за другим (с промежутками, равными одному такту тактового генератора).

Асинхронные байты могут быть посланы с различными интервалами времени между байтами»

Putnik
() автор топика
Ответ на: комментарий от hvatitbanit

Тут товарищ на другом форуме утверждает, что ком-порт на скорости 115200 работает ТОЛЬКО в синхронном режиме) Рассказал разработчикам железяки, они сильно, мягко говоря, удивились)

Putnik
() автор топика
Ответ на: комментарий от Eddy_Em

Edde_Em, я глянул про select и если правильно понимаю, её использование имеет смысл при работе с несколькими источниками данных. У меня один источник, один дескриптор.

Собственно, при чтении у меня проблем не возникает, все данные приходят и корректно принимаются. А потери данных при записи

Putnik
() автор топика
Ответ на: комментарий от anto215

anto215, вот выдержка из протокола информационного взаимодействия для железки:

ЭВМ в случае готовности к взаимодействию устанавливает сигнал DTR. Блок осуществляет начальную установку своих схем и по завершению формирует сигнал готовности DSR.

Обмен сообщениями между ЭВМ и блоком выполняется при наличии активного состояния цепей DTR и DSR.

Для передачи любого сообщения в блок ЭВМ активизирует сигнал на линии RTS (запрос на передачу). Блок выставляет в ответ сигнал CTS, после чего ЭВМ по цепи TXD выдает сообщение, после чего снимает сигнал RTS. После снятия сигнала RTS, получив от ЭВМ сообщение заданной длины, блок снимает сигнал CTS.

Если при приеме от ЭВМ сообщения нарушен формат хотя бы одной посылки, блок снимает сигнал CTS и считает принятое сообщение недействительным. Для возобновления передачи ЭВМ должна снять сигнал RTS в ответ на снятие сигнала CTS и затем вновь его установить для организации нового цикла передачи сообщения.

Полудуплекс и прочие извраты вроде бы не назначаю) параметры задаются так:

	fd = open ( name, O_RDWR, O_NOCTTY, O_NDELAY);
	if ( fd < 0 )
	{
		perror ( "unable to open com port" );
		return 0;
	}

	fcntl ( fd, F_SETFL, 0 );
	tcgetattr ( fd, &options );
	cfsetispeed ( &options, B115200 );
	cfsetospeed ( &options, B115200 );

	options.c_cflag |= ( CLOCAL | CREAD );
	options.c_cflag &= ~PARENB;
	options.c_cflag &= ~CSTOPB; // 1 stop bit
	options.c_cflag &= ~CSIZE;
	options.c_cflag |= CS8;		// 8 data bit
	options.c_cflag &= ~CRTSCTS;

	options.c_lflag &= ~ ( ICANON | ECHO | ECHOE | ISIG );
	options.c_iflag &= ~ ( IXON |IXOFF | IXANY | INLCR | ICRNL | IUCLC );

 	options.c_oflag &= ~OPOST;

	tcsetattr ( fd, TCSANOW, &options );

	status |= TIOCM_DTR;
	ioctl ( fd, TIOCMGET, &status );

	if ( status&TIOCM_DSR )
	printf ( "DSR + \n" );

	return fd;
Putnik
() автор топика

Весь тред лень читать. Скажу проще: есть вероятность ошибки чтения. Она самой природой асинхронного режима диктуется. Насколько помню на 19200 - 0.9%.

И эта величина растёт e^

ziemin ★★
()
Ответ на: Ненависть ~:-( от pathfinder

pathfinder, quest, насчет возвращаемого значения write() согласен (ненависть принята =) ).

Но! Смотрим на анализаторе - в канал уходят ВСЕ данные. Все 12 байт кодограммы. Только вот RTS сбрасывается раньше, чем все байты ушли в канал, поэтому блок уже успел по сбросу RTS сбросить CTS, и «запоздавшие» байты попросту не воспринимает.

Посоветовали включить проверку освобождения линии (цикл проверки бита TIOCSERGETLSR) - не помогло.

Putnik
() автор топика
Ответ на: комментарий от yax123

посмотрел свою последнюю поделку про передачу через rs232 не увидел ни одного ioctl ( fd, TIO-bla-bla-bla

а примерчик кода можно? =)

Putnik
() автор топика
Ответ на: комментарий от Putnik

Тут товарищ на другом форуме утверждает, что ком-порт на скорости 115200 работает ТОЛЬКО в синхронном режиме

Это чушь полная. СОМ-порт IBM-PC-образного компьютера вообще не умеет синхронный режим. Там даже в микросхеме нет синхронного режима, и в разъеме нет нужных проводов.

Попробуй вообще не дергать RTS. Программно или аппаратно - неважно. Выставь его в высокий уровень и так и оставь навсегда. Может быть так оно сработает, как следует.

anto215 ★★
()
Ответ на: комментарий от Putnik

Смысл в том, что если ты не выделяешь отдельный поток на постоянное чтение данных из порта, то только при помощи select или poll ты сможешь сделать неблокирующее чтение!

А при записи потери могут быть из-за того, что пишешь ты как-то крайне подозрительно. Ни разу такого способа не видел. Да еще и не проверять коды возврата...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Putnik

Кто такое сказал? Можно и быстрей в асинхронном режиме работать. Главное — что за камень. Если у тебя тактовая частота камня 100кГц, то, ясен пень, 115200 он не потянет!

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Putnik

Примерчик уже выслал эдди (причин не доверять ему проганье уарта пока не было).

Озвучте, что у вас за железяка которая подключается к компу. На чем сделан UART на ней. Какой кабель используется для связи.
А то у меня есть подозрение что вы пытаетесь забодяжить аппаратный контроль потока на связке которая это не сможет сделать. Либо просто просто не согласованность (типа ПК делает soft, а железяка hard).

yax123 ★★★★★
()
Ответ на: комментарий от Eddy_Em

Спасибо за пример)

Да, чтение реализовано у меня в отдельном потоке на базе QThread .

Сейчас меня на другой проект перекинули, позднее отпишу, что получилось)

Putnik
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.