LINUX.ORG.RU

serial port && hardware flow control


0

2

Есть устройство, которое принимает данные по RS-232C. К разъёму припаяно всего три вывода: TX (transfer), CTS (Clear to Send) и GND. DSR (Data Set Ready) и DTR (Data Terminal Ready) соединены прямо в кабеле.

Устройство это очень легко захлебнуть данными. Один символ может обрабатываться несколько секунд. И поэтому устройство через вывод CTS даёт понять когда уже можно к нему обращаться.

Вне Linux, используя 0x14 прерывание я просто опрашиваю статус COM-порта на состояние бита CTS перед отправкой каждого байта и всё работает прекрасно.

Но раз уж Linux называется операционной системой, то я хочу, чтобы можно было сделать просто:

$ cat data > /dev/ttyS1
и чтобы система сама позаботилась о том, чтобы устройство не захлёбывалось от данных. Но по какой-то причине этого не происходит.

Я настраиваю порт программой stty так:

$ stty -F /dev/ttyS1 speed 4800 crtscts

>Я настраиваю порт программой stty так:

Сделай это в своей программе потому что она является управляющим терминалом и будет тебе счастье.

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

По ссылке написано:

 CRTSCTS : output hardware flow control (only used if the cable has
                    all necessary lines. See sect. 7 of Serial-HOWTO)

Собственно, мой вопрос можно перефразировать так: будет ли в Linux работать hardware flow control, если из всего множества выводов работает только CTS. Т.е. выполняется ли условие «if the cable has all necessary lines»?

Просто я не хочу писать ещё один cat, который будет работать только для этого устройства.

kde4-hater
() автор топика

>чтобы система сама позаботилась о том, чтобы устройство не захлёбывалось от данных
ну ты, особо про'двинутый, откуда ядру знать сколько данных переслать, чтобы чип устройства не подавился?

Mobyshvein
()
Ответ на: комментарий от kde4-hater

>Нет никакой моей программы. Есть cat.

Понятно, меня смутило вот это :)

Вне Linux, используя 0x14 прерывание я просто опрашиваю статус >COM-порта на состояние бита CTS перед отправкой каждого байта и всё >работает прекрасно.


Для начала убедись что аппаратное управление crtscts действительно активно

stty -a -F /dev/ttyS1


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

Второй абзац, третье предложение.

И поэтому устройство через вывод CTS даёт понять когда уже можно к нему обращаться.

kde4-hater
() автор топика
Ответ на: комментарий от anonymous
speed 4800 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread clocal crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke
kde4-hater
() автор топика
Ответ на: комментарий от kde4-hater

Сдается мне у тебя кабель другой системы :) Установи перемычку - подай принудительно -12 В на cts (или хз какой там на твоем порту уровень логической 1- возьми с контакта который постоянно находится в состоянии логической единицы) и проверь - если cat не зависнет в ожидании то дело в настройках порта, если зависнет - дело в кабеле.

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

Какой кабель указано в первом абзаце.

CTS выдаёт правильные значения. Самописная программка на assembler, помещающаяся в Master Boot Record, сделанная в попытке разобраться в ситуации, читая эти значения CTS, работала без сбоев пару часов, пока я её не выключил.

cat не зависает в ожидании, а отправляет все данные сразу, тогда как несколько символов могут обрабатываться устройством несколько секунд. То есть ведёт себя так, как будто на CTS действительно принудительно подана логическая единица, хотя в действительности это не так.

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

>То есть ведёт себя так, как будто на CTS действительно принудительно подана логическая единица, хотя в действительности это не так.

Вообщето логическая единица на CTS означает что удаленное устройсво не готово принять данные.

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

Для ясности - в компьтерных rs-232 логическая единица -5...-12 В, логический ноль +5...+12 В, в микроконтроллерах соотвественно +5 (3,3)В и 0. Чтобы передающее устройство приостановило передачу - на его линии CTS должна быть логическая 1, 0 означает что удаленное принимающее устройство готово принимать данные. Поэтому если принудительно подать -12 В (логическую единицу) cat должен зависнуть в ожидании при правильных настройках порта.

anonymous
()

>Вне Linux, используя 0x14 прерывание я просто опрашиваю статус COM-порта на состояние бита CTS перед отправкой каждого байта и всё работает прекрасно.о

Не обижайся но ты там что-то набыдлокодил похоже совсем не по стандарту поэтому и работало - CTS опрашивать програмно нафик не нужно - этим занимается контроллер последовательного порта аппаратно. Более того - у тебя там в железяке что-то неправильно с уровнями, потому что на стандарном правильно настроенном порте без 0 на CTS ты сможешь записать в порт только буфер - передача не начнется пока не появится логический 0 на CTS, тоесть даже если CTS висит в воздухе в третьем состоянии - передача не начнется.

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

Text-Terminal-HOWTO: 11.8 Is Hardware Flow Control Done by Hardware ?

Some think that hardware flow control is done by hardware but only a small part of it is done by hardware. Most of it is actually done by your operating system software. UART chips and associated hardware usually know nothing at all about hardware flow control. When a hardware flow control signal is received (due to the signal wire flipping polarity) the hardware gives an electrical interrupt signal to the CPU. However, the hardware has no idea what this interrupt means. The CPU stops what it was doing and jumps to a table in main memory that tells the CPU where to go to find a program which will find out what happened and determine what to do about it. In this case this program stops the outgoing flow of bytes.

Обижаться должен не я, а те кто писали драйверы для serial port в Linux размером в сотни килобайт. Потому что у меня работает, а у них нет. CTS работает нормально. Если отображать состояние CTS интерактивно, то видно, что CTS гаснет когда устройство обрабатывает данные и загорается, когда оно готово принять данные.

Возможно, у Linux сносит башню, когда оказывается, что большинство выводов «висят в воздухе». Например, те же RTS и RX. Но это крайне сомнительно.

Есть ещё мысль, что требуется некоторая задержка после смены уровня CTS. Попробую накатить Linux на 486й и проверить.

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

>CTS работает нормально. Если отображать состояние CTS интерактивно, то видно, что CTS гаснет когда устройство обрабатывает данные и загорается, когда оно готово принять данные.

Есть ещё мысль, что требуется некоторая задержка после смены уровня CTS. Попробую накатить Linux на 486й и проверить.


Тогда все что тебе нужно - это уменьшить размер буфера в драйвере компорта.

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

Попробую накатить Linux на 486й и проверить.

Проверил. На 486м всё работает как надо.

Как уменьшить размер буфера?

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

>Как уменьшить размер буфера?

Вообще отключи FIFO принудительно указав старый тип порта через setserial #setserial /dev/ttyS1 uart 8250

anonymous
()
Ответ на: комментарий от kde4-hater

Умолчал: устройство не получает ни байта.

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

Пробуй

#setserial /dev/ttyS1 uart 16450

странно что с 8250 не работает...Вообще в исходниках можно поправить но это крайний вариант.

anonymous
()
Ответ на: комментарий от kde4-hater

Какой uart сообщает setserial для вашей машинки и для 486-ой?

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