Товарищи! Похоже, проблема
РЕШИЛАСЬ. Осталось только выяснить, каким образом (см. ниже).
Но мне всё равно хотелось бы разобраться с этим как следует, чтобы был урок на будущее.
Denjs писал(а): ↑04.09.2010 15:30
Управляющие сигналы я игнорирую. Они и в приборе игнорируются, и в программе при задании настроек порта.
гм... а что на самом деле твориться в регистрах контроллера под вендой / под линуксом / под досом смотрели? (последний наиболее интересен.. мне рассказывать не надо - я уже не пойму... - сами сравните ваши 3 набора...)...
Что творится в регистрах порта я не проверял. До этого просто не дошло. Хотя, надо бы, действительно, посмотреть, что там в разных операционках.
кабель какой у вас? пробовали заменить на 3-х жильный? что-бы гарантированно игнорировать управляющие сигналы...
Кабель у нас сразу же был 3-жильный, так что на управляющие сигналы по замыслу не было никаких видов.
и ещё мысль... тупая но кто знает что "там" происходит... у вас программа с каким приоритетом запускается? в досе-то он понятно практически всегда "почти-реал-таймовый"... просто я к отличию однозадачных ОС от многозадачных...
С приоритетом я тоже пробовал поиграться. Но оказалось, что разницы между обычным и "приоритетом реального времени" (если быть точным, то не совсем реального времени, а в том, что присутствует в стандартном ядре "Linux". Т.е. установил планировщик "SCHED_FIFO" при помощи функции sched_setscheduler() для этой программы. Это немного стабилизировало периодичность действий программы, но не помогло устранить обрывов передачи.
ssh писал(а): ↑04.09.2010 15:59
v2e писал(а): ↑02.09.2010 22:48
На осциллографе поймать конкретный байт на такой скорости не удаётся, но сегодня проверили прохождение байтов электронной "ловушкой" (см. ниже)
надо постараться. и притом рассмотреть вид последовательной посылки. если в процессе самопроизвольно меняется скорость обмена, то прибор может перестать реагировать на вашу посылку, даже если она и уходит. проверка с нуль-модемом этого не покажет (что такое "электронная ловушка", не знаю).
На осциллографе мы просмотрели передачу, засинхронизировав его с периодом работы программы. Наблюдали некоторое время, и скорость передачи не менялась (рассинхронизации развёртки осциллографа и сигнала не происходило). Видимо, скорость обмена самопроизвольно не менялась. Да и, честно говоря, я никогда не сталкивался с самопроизвольным изменением скорости обмена COM-порта. Но раз вы обратили на это внимание (видимо, преценденты были), то теперь я буду держать ухо востро.
вот надо убедиться, что все эти драйверы вырублены во время работы вашей программы. в частности, адреса используемого вами сом-порта НЕ должно быть в файле "/proc/ioports", а его прерывания - в "/proc/interrupts". если это не так - то кто-то с вами конкурирует (это не полная проверка, но хоть что-то).
Хм... Я об этих файлах не знал. Спасибо за совет. Надо будет и за ними понаблюдать как-нибудь.
насчет инициации обмена по прерываниям - мысль хорошая.
Дело в том, что я совершенно не знаю, как пользоваться прерываниями. Знаком с ними только по наслышке, но никогда не доводилось использовать. Может быть, вы могли бы мне дать какую-нибудь ссылку на пример или документацию какую-нибудь по этому поводу?
и наконец, если у вас дело хорошо идет под досом - то есть шанс, что и под dosemu неплохо будет. можно попробовать запустить программу в ее досовской версии под эмулятором (но все же лучше разобраться с чистым линуксом).
Вот я тоже решил, что надо "разобраться с чистым линуксом". Как минимум, у Linux открыты исходники и большое сообщество, что должно упрощать разбирательство, как я полагаю.
Теперь о некоторых достижениях.
Итак,
РЕШЕНИЕМ проблемы послужило включение аппаратного буфера FIFO при инициализации и настройке порта.
Код: Выделить всё
outb(0x01, base_address+2); // FIFO buffer on.
// Запись единицы в младший разряд регистра 0x3f8+2
// 0x3f8 - базовый адрес используемого СОМ-порта
Я полагал, что если микросхема этот буфер поддерживает, то он по умолчанию используется. Видимо, это совсем не обязательно. Получается, что
- В DOS'е он либо работает по умолчанию, либо программа попросту успевает забирать из порта байты быстрее, чем прибор их туда поставляет (не знаю, насколько это возможно), либо аппаратный буфер FIFO включён и накапливает эти байты.
- В Windows он, выходит, выключен по умолчанию.
- В GNU/Linux'e он по умолчанию выключен.
Однако, несмотря на успешную работу с включённым вручную буфером, остаётся неясным следующий момент.
Насколько я понимаю, когда буфер не используется, порт может содержать только один байт. Тогда, если в порт приходит ещё один байт, то он должен переписать прежний байт, не так ли? По идее, должен подняться флаг ошибки, но тем не менее, бит, показывающий наличие в порту пришедшего байта, должен быть равен 1. А у меня получается, что он равен 0, т.к. программа останавливается на этапе ожидания прихода байт в порт (т.е. ожидания единицы в этом разряде).
Что же происходит с принимаемыми байтами в порту при отключенном аппаратном буфере?
Кроме того, я не могу объяснить теперь, почему программа довольно стабильно работала при задержке между записью в порт и чтением из него в 50 мс. Уж за это время там точно должно было всё поперазаписаться в этом порту.
