Стоит мультикарта на чипсете WCH CH352L, у неё есть родной драйвер для Linux, поставил настроил как надо:
# dmesg|grep ttyS
[ 1.313772] serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[ 1.313944] serial8250: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
[ 1.314574] 00:08: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[ 1.314866] 00:09: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
[ 1.315268] 0000:00:07.0: ttyS2 at I/O 0xdf00 (irq = 18) is a XScale
[ 1.315502] 0000:00:07.0: ttyS3 at I/O 0xe000 (irq = 18) is a XScale# setserial -g /dev/ttyS*
/dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4
/dev/ttyS1, UART: 16550A, Port: 0x02f8, IRQ: 3
/dev/ttyS2, UART: 16550A, Port: 0xdf00, IRQ: 18 - порт мультикарты
/dev/ttyS3, UART: 16550A, Port: 0xe000, IRQ: 18 - порт мультикарты
в результате на чтение работает отлично, а вот при передаче буфер переписывается циклический, т.е. у 16550А буфер 16 байт как и надо, если передавать слова не более 16 байт то все ок(ttyS1 и ttyS3 соединены через нуль модемный кабель):
# echo "1234567890123456" > /dev/ttyS3# cat /dev/ttyS1
1234567890123456а если больше то первые слова переписываются последними:
#echo "12345678901234567890" > /dev/ttyS3
# cat /dev/ttyS1
78905678901234567890#echo "12345678901234567890abcdef" > /dev/ttyS3
# cat /dev/ttyS1
1890abcdef1234567890abcdefТ.е. получается что байты не успевают уйти из буфера UART FIFO, и переписываются новыми поступающими байтами.
Как это можно вылечить и почему так происходит?? может кто нить встречался, а то у меня уже мозги кипят с этими платами...
>Как это можно вылечить и почему так происходит?? может кто нить встречался,
>а то у меня уже мозги кипят с этими платами...a flow-control как настроен, он то и должен придерживать передающую сторону при заполнении буфера.
>
>>Как это можно вылечить и почему так происходит?? может кто нить встречался,
>>а то у меня уже мозги кипят с этими платами...
>
>a flow-control как настроен, он то и должен придерживать передающую сторону при
>заполнении буфера.В данном случае flow-сontrol не должен иметь значеие,т.к. это fifo буфер, здесь получается что прерывание не успевает отрабатывать, есть параметр такой триггер левел но как его установить хз, написано что setserial это не может
Вот не эту тему:The 16550A (or 16550) FIFO chip comes with 16 byte FIFO buffers. This means that it can receive up to 14 bytes (or send 16 bytes) before it has to interrupt the CPU. Not only can it wait for more bytes, but the CPU then can transfer all (14 to 16) bytes at a time. This is a significant advantage over the obsolete UARTs, which only had 1 byte buffers. The CPU receives less interrupts, and is free to do other things. Data is rarely lost. Note that the interrupt threshold of FIFO buffers (trigger level) may be set at less than 14. 1, 4 and 8 are other possible choices. As of late 2000 there was no way the Linux user could set these directly (setserial can't do it). While many PC's only have a 16550 with 16-byte buffers, better UARTS have even larger buffers.
Note that the interrupt is issued slightly before the buffer gets full (at say a "trigger level" of 14 bytes for a 16-byte buffer). This allows room for a couple more bytes to be received before the interrupt service routine is able to actually fetch all these bytes. The trigger level may be set to various permitted values by kernel software. A trigger level of 1 will be almost like an obsolete UART (except that it still has room for 15 more bytes after it issues the interrupt).
вот самое интересное:
Note that the interrupt threshold of FIFO buffers (trigger level) may be set at less than 14. 1, 4 and 8 are other possible choices. As of late 2000 there was no way the Linux user could set these directly (setserial can't do it). While many PC's only have a 16550 with 16-byte buffers, better UARTS have even larger buffers.
>>
>>>Как это можно вылечить и почему так происходит?? может кто нить встречался,
>>>а то у меня уже мозги кипят с этими платами...
>>
>>a flow-control как настроен, он то и должен придерживать передающую сторону при
>>заполнении буфера.
>
>В данном случае flow-сontrol не должен иметь значеие,т.к. это fifo буфер,
>получается что прерывание не успевает отрабатывать,не вижу логики, ну и что, что fifo размер то 16 байт. Раз заполнился и никто его не освободил значит надо прекращать принимать, для этого и придумали flow-control и даже проводки отдельные есть для таких случаев. Если медленная сторона не успевает обрабатывать, то быстрая должна прекратить передачу. У com есть несколько разных способов управления как при помощи специальных линий так и программные.
>получается что прерывание не успевает отрабатывать, есть параметр такой триггер левел
>но как его установить хз, написано что setserial это не может
>а если например ppp запустить, будет успевать?
Может вы что-то не правильно поняли. Возможно если нет процесса читающего /dev/ttyS то и прерывания буфер не освобождают поскольку данные никому не нужны, зачем тратить на них такты, а вы читаете последние данные оставшиеся в буфере. Вообще есть много статей по работе с ком-портами в linux. Стоит их внимательней почитать. Думаю тригер левел тут ни причём.
>а если например ppp запустить, будет успевать?Нет не будет успевать, опробовано уже множество всяческого софта и железа, допустим сканер штрих кода работает на этом порту без проблем, так как тока на вход, а ККМ уже не может, т.к. данные бегают в обе стороны(с другими платами соответственно нормально)
>Может вы что-то не правильно поняли. Возможно если нет процесса читающего /dev/ttyS
>то и прерывания буфер не освобождают поскольку данные никому не нужны,
>зачем тратить на них такты, а вы читаете последние данные оставшиеся
>в буфере. Вообще есть много статей по работе с ком-портами в
>linux. Стоит их внимательней почитать. Думаю тригер левел тут ни причём.
>Перечитал множество статей (несколько десятков точно), поборол несколько карт, и точно могу сказать что flow control имеет отношения ко всем буферам, кроме fifo-шного(т.к. он очень маленький, в него поступают данные из 8к кэша драйвера), к нему имеет отношение как раз таки trigger level, который должен генерировать прерывание когда в буфере накапливается 14 байт.
Нашел, что можно поменять триггерлевел путем установки 6 и 7 бита FCR регистра, но почему то тока для rx буфера(который и так работает нормально), а tx можно тока отключить.Linux Serial How-To:
http://tldp.org/HOWTO/Serial-HOWTO-4.html#ss4.8
http://tldp.org/HOWTO/Serial-HOWTO-19.html#ss19.3
Прошу прощения, я не внимательно прочёл проблему, что у вас переполняется буфер передачи. То есть данные с порта ещё не ушли, а драйвер туда помещает уже новую порцию. Тут действительно flow-control не поможет он для предотвращения переполнения буфера принимающего оборудования. Тригер левел собственно тоже только для приёма чтоб разгрузить CPU, не генерировать прерывание при приёме каждого байта, а только при заполнении буфера чтоб обработчик забрал все принятые данные скопом за один раз. Сообственно поэтому он и нужен только для rx регистра.
За буфером tx регистра должен следить драйвер и не допускать его переполнения, у вас он этого не делает. Возможно драйвер кривоват или ему надо передать какие-то хитрые параметры при загрузке модуля. Смотрите инструкцию и исходники драйвера.
>Прошу прощения, я не внимательно прочёл проблему, что у вас переполняется буфер
>передачи. То есть данные с порта ещё не ушли, а драйвер
>туда помещает уже новую порцию. Тут действительно flow-control не поможет он
>для предотвращения переполнения буфера принимающего оборудования. Тригер левел собственно тоже только
>для приёма чтоб разгрузить CPU, не генерировать прерывание при приёме каждого
>байта, а только при заполнении буфера чтоб обработчик забрал все принятые
>данные скопом за один раз. Сообственно поэтому он и нужен только
>для rx регистра.Согласен на счет rx, но для tx он также нужен, т.к. прерывание генерируется как для отправки так и для получения.
>За буфером tx регистра должен следить драйвер и не допускать его переполнения,
>у вас он этого не делает. Возможно драйвер кривоват или ему
>надо передать какие-то хитрые параметры при загрузке модуля. Смотрите инструкцию и
>исходники драйвера.Да вот в том то и дело что драйвер там какой то хитрый, выполнен не в виде модуля, а виде исполняемого файла, который загружается при старте, в результате карта определяется как 16550А и соответственно использует стандартный serial драйвер, но походу все таки это происходит как то коряво..
Ладно, спасибо за помощь.
>Согласен на счет rx, но для tx он также нужен, т.к. прерывание
>генерируется как для отправки так и для получения.И тоже только для разгрузки CPU и нужно драйверу чтоб просто оптимальнее использовать такты CPU, на переполнение это не должно влиять при любом значении тригера.
>Да вот в том то и дело что драйвер там какой то
>хитрый, выполнен не в виде модуля, а виде исполняемого файла, который
>загружается при старте, в результате карта определяется как 16550А и соответственно
>использует стандартный serial драйвер, но походу все таки это происходит как
>то коряво..
>раз есть файл устройства то есть и драйвер ядра. Посмотрите какой драйвер обслуживает файл устройства, вдруг там можно в /sys/ что-то подкрутить. Исполняемый файл не является драйвером, он скорее производит настройку самой карты и по всей видимости криво или вы ему не передали какие-то очень важные параметры. Ищете документацию по ваше карте может там что полезное написано.
>
>И тоже только для разгрузки CPU и нужно драйверу чтоб просто оптимальнее
>использовать такты CPU, на переполнение это не должно влиять при любом
>значении тригера.Ну fifo буфер и нужен чтоб не при посылке/отправке каждого байта генерить прерывание, что сильно нагружает проц, а при накоплении 14 байт(для 16550А), дак вот в данном случае такое чувство что из кэша драйвера записалось в fifo 16, а прерывание не сгенерировано и соответственно отправки не произошло, а в fifo данные начинают писаться по второму кругу и затирают уже лежащие там байты, а отправка перерывание на отправку генериться как будьто после какого то тайм аута(понять бы какого)
>
>раз есть файл устройства то есть и драйвер ядра. Посмотрите какой драйвер
>обслуживает файл устройства, вдруг там можно в /sys/ что-то подкрутить. Исполняемый
>файл не является драйвером, он скорее производит настройку самой карты и
>по всей видимости криво или вы ему не передали какие-то очень
>важные параметры. Ищете документацию по ваше карте может там что полезное
>написано.Здесь согласен. В lshw показывает что используется стандартный драйвер serial, вот думаю че можно там "подкрутить". Я зделал как в readme было написано...а в инете ни че путного по ней не нашел, хрень китайская...
>[оверквотинг удален]
>>использовать такты CPU, на переполнение это не должно влиять при любом
>>значении тригера.
>
>Ну fifo буфер и нужен чтоб не при посылке/отправке каждого байта генерить
>прерывание, что сильно нагружает проц, а при накоплении 14 байт(для 16550А),
>дак вот в данном случае такое чувство что из кэша драйвера
>записалось в fifo 16, а прерывание не сгенерировано и соответственно отправки
>не произошло, а в fifo данные начинают писаться по второму кругу
>и затирают уже лежащие там байты, а отправка перерывание на отправку
>генериться как будьто после какого то тайм аута(понять бы какого)В зависимости от настройки микросхема UART может работать в разных режимах и не обязательно с прерываниями.
>
>>
>Здесь согласен. В lshw показывает что используется стандартный драйвер serial, вот думаю
>че можно там "подкрутить". Я зделал как в readme было написано...а
>в инете ни че путного по ней не нашел, хрень китайская...
>железка без доков, да ещё и не работающая проще выкинуть.
>В зависимости от настройки микросхема UART может работать в разных режимах и
>не обязательно с прерываниями.А какие у неё еще есть режимы и как в них можно перевести железяку?
>железка без доков, да ещё и не работающая проще выкинуть.
да дело в том что под виндой работала, в свое время набрали, а щас начали все на никсы переводить...
>
>>В зависимости от настройки микросхема UART может работать в разных режимах и
>>не обязательно с прерываниями.
>
>А какие у неё еще есть режимы и как в них можно
>перевести железяку?
>У вас есть какой-то исполняемый файл который возможно и производит настройку железки на нужный режим. Смотрите на плату что за микросхема какие у неё есть режимы и как и чем она поддерживается в linux. По всей видимости железка не переведена в нужный режим.
Да Буфер FIFO вообще не обязательный компонент в ОС, что уж он так озаботил тебя своей важностью, что касаемо переполнения по каналу порта передачи, то его скорость ~ разА`1,5-2 ниже приёмной если соединён по модему, а объём поди явно одинаков на обоих каналах. Реальное решение по этой проблемке это уменьшить объём буфера по каналу передачи минимум в 1,5 раза. Скажу что я сам вообще уже больше не использую FIFO, возможно отклик и увеличился на доли, но в целом система в INET работает реактивней и без тормозов ...
>>В зависимости от настройки микросхема UART может работать в разных режимах и
>>не обязательно с прерываниями.
> А какие у неё еще есть режимы и как в них можно
> перевести железяку?
>>железка без доков, да ещё и не работающая проще выкинуть.
> да дело в том что под виндой работала, в свое время набрали,
> а щас начали все на никсы переводить...Здравствуйте, возникла аналогичная проблема в этими контроллерами. Подскажите пожалуйста, удалось ли Вам решить проблему?