запись в /dev/tty/S...

Все о программировании под *nix
Аватара пользователя
smart
Увлекающийся
Сообщения: 80
Зарегистрирован: 06 сен 2008, 19:36
Откуда: МИНСК
Контактная информация:

запись в /dev/tty/S...

Сообщение smart »

есть непонятный глючок, с которым пока не могу побороться
после записи в tty "fd" происходит "пролёт" установленной задержки удержания уровня DTR.

Код: Выделить всё

void sendtomoto(int serial,unsigned char *data, int len )
{
	set_DTR( 1 , &serial);
	usleep(1000);
        write(serial,&data[0],len);
        tcdrain(serial);
	usleep(10000);
	set_DTR( 0 , &serial);
}
порт открыт как

Код: Выделить всё

 fd = open(RADIODEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK | O_NDELAY);
 c_cflag = BAUDRATE | CS8 |  CLOCAL | CREAD;
 c_oflag = 0;
 c_lflag = 0;
 c_cc[VMIN]=0;
 c_cc[VTIME]=1;
на "приём" работает всё идеально, правда уровня DTR и не требуется. Приём по SIGIO.
комбинация битов c_cflag не влияет CRTSCTS CLOCAL

Аватара пользователя
smart
Увлекающийся
Сообщения: 80
Зарегистрирован: 06 сен 2008, 19:36
Откуда: МИНСК
Контактная информация:

Re: запись в /dev/tty/S...

Сообщение smart »

usleep(10000);
пролетает после записи в уарт как будто нет этой задержки и время удержания DTR
не отрабатывает как надо.
Задержка перед записью в уарт - работает, а после нет !
В принципе, и с таким урезанным временем после записи и слёта уровня DTR работает устройство - но боюсь что на более шустрых машинах может не работать.

Аватара пользователя
smart
Увлекающийся
Сообщения: 80
Зарегистрирован: 06 сен 2008, 19:36
Откуда: МИНСК
Контактная информация:

Re: запись в /dev/tty/S...

Сообщение smart »

Код: Выделить всё

// set DTR level, return -1 if error
int set_DTR(int level, int *fd)
{
	int serline;
    ioctl (*fd, TIOCMGET, &serline);
	if (level == 1) 
	{ 
 	  serline |= TIOCM_DTR;
	  return ioctl (*fd, TIOCMSET, &serline);
	}
	if (level == 0) 
	{ 
 	  serline &= ~TIOCM_DTR;
	  return ioctl (*fd, TIOCMSET, &serline);
	}
	return -1;
}
где то так. Ничего умнее не придумал :evil:
А вот слет уровня - возможно при получении сигнала о приёме (выдача байтов отдаётся обратно физически - типа MBUS для сотовых) сносит крышу ядру - sigusr уходит в

Код: Выделить всё

void signal_handler_IO (int status)
{
    wait_flag = FALSE;
}
и, возможно задержка убивается.
В целом программулька прошла мучения с аппаратными глюками и теперь чешу репу
над интерфейсом, пока в консоли и, возможно и навсегда...

Аватара пользователя
smart
Увлекающийся
Сообщения: 80
Зарегистрирован: 06 сен 2008, 19:36
Откуда: МИНСК
Контактная информация:

Re: запись в /dev/tty/S...

Сообщение smart »

как обычно, отвечаю сам себе
usleep убивается сигналом.

PS админы - при входе на форум - поменяйте картинки на читаемые - или вы так сс..те что бот зайдет, что человек не понимает что написано ?

Аватара пользователя
X-Stranger
Администратор
Сообщения: 1238
Зарегистрирован: 09 сен 2001, 04:46
Контактная информация:

Re: запись в /dev/tty/S...

Сообщение X-Stranger »

Информация полученная самостоятельно запоминается лучше. Спасибо, что не забыл ответ выложить.

P.S. smart, если не читается, то на самой капче есть кнопочка "обновить", которая показывает другую картинку. Картинки генерируются внешним сервисом. Так что хватить сс..ть в муку и поднимать пыль.
usually I'm kind

Аватара пользователя
smart
Увлекающийся
Сообщения: 80
Зарегистрирован: 06 сен 2008, 19:36
Откуда: МИНСК
Контактная информация:

Re: запись в /dev/tty/S...

Сообщение smart »

хм, это понятно, что кнопачка, да вот пока пять раз нажмешь и получишь читаемое, уже начинаешь сомневаться - а надо ли ? :D
Но, сегодня без картинки - спасибо !

Аватара пользователя
smart
Увлекающийся
Сообщения: 80
Зарегистрирован: 06 сен 2008, 19:36
Откуда: МИНСК
Контактная информация:

Re: запись в /dev/tty/S...

Сообщение smart »

сегодня "родил" таки самовосстанавливаемую после сигнала задержку. Был вариант ещё на clock(), но он жрал проц как главный, по плешку.
оба варианта ниже

первый навеян с
http://cc.byexamples.com/2007/05/25/nan ... nd-usleep/

Код: Выделить всё

void mysleep(unsigned long mks) 
{
struct timespec time,errortime;
if ((mks * 1000) > 999999999)
	{
		time.tv_sec = mks / 1000000;
		time.tv_nsec = 0;
	}
else
	{
		time.tv_sec = 0 ;
		time.tv_nsec = mks * 1000;
	}
while (nanosleep(&time,&errortime) != 0) 
	{
		time.tv_nsec = errortime.tv_nsec;
		time.tv_sec = errortime.tv_sec;
	}
}
а ресурсожрущий с http://www.velocityreviews.com/forums/t ... -in-c.html

Код: Выделить всё

void mysleep(unsigned long u)
{
clock_t end, start = clock();
if (start == (clock_t) -1) return;
end = start + CLOCKS_PER_SEC * (u / 1000000.0);
while (clock() < end) ;
} 

Ответить