> Запросто. Когда я говорил, что фифо не будет работать я > имел в виду ИМЕННО фифо. То есть порт будет работать как > старый 16450 (или как его так, у которого фифо вообще нет).
Дык почему мне приходится ИИР пулить, если фифо по-умолчанию выключено? После загрузки голого ДОСа запускается только моя прога - никто ФИФО не включает.
> Очередь запрещена по умолчанию. Если ее не включать - будет > работать только RBR (receive buffer register - можно > считать однобайтной очередью). Включается в FCR (FIFO > control register). Но кроме того придется выставлять еще > highwater (порог срабатывания прерывания) и т.д..
Что же у меня в очередь вставало? Я то ФИФО не трогал.
> Если работаешь на прерываниях, то тебе придет прерывание, > когда он освободится. Если же предпочитаешь поллить, читай > LSR (line status register) там два бита THRE (transmit > holding register empty) и TEMPT (transmitter empty). THRE > ставится в 1, когда очередной байт из буфера ушел в > передатчик (но передатчик может еще работать), а TEMPT - > когда передатчик не работает.
Прерывание, разумеется, должно произойти, когда буфер (transmit holding register) опустошится, т.е. после закидывания первого байта, если очередь не равна нулю, а потом (после заполнения очереди) с периодом передачи байтиков?
Еще я заметил, что СОМпорт "нежная" вещь. Припаял провода (~3м) к сигналам готовности. Подаю сигнал на один - и во втором тоже сигнал появлялся. Распрямил (скрученные колечком) провода и разнес друг от друга - наводка пропала.
_asm {
mov dx, AdressCOM2
in al, dx
and ax, 00000111b
mov BytePrich, al
and ax, 00000001b
mov BytePhact, al
mov dx, AdressCOM0
in al, dx
mov ByteInf, al
}
if (BytePhact==1) return;
if (!BytePrich) {
_asm {
mov dx, AdressCOM5
in al, dx
}
}
if (BytePrich&4) {
// Принятый байт Записывается в некоторый буфер
COM_BUF_IN[e][P_in_buf[e]]=ByteInf; if ((++P_in_buf[e])>69) P_in_buf[e]=0;
}
if (BytePrich&2) {
if (P_out_buf[e]!=0) {
ByteInf=COM_BUF_OUT[e][P_stat_buf[e]]; P_stat_buf[e]++; P_out_buf[e]--;
// Байт может быть передан
/*
if (Param2==0) {
_asm {
mov al, ByteInf
mov dx, AdressCOM0
out dx, al
}
} else
{
Param2_buf [e]=ByteInf;
Param2_IDENT[e]=TIMECOMINTERR;
}
*/
}
}
if (BytePrich&6) {
_asm {
mov dx, AdressCOM6
in al, dx
}
}
goto repeat;
}
Все разработки, по большему счету, схожи.22.09.03 11:11 Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman Отредактировано 22.09.03 11:17 Количество правок: 2
---
Сначала сохраняю предыдущее состояние порта, чтобы потом все восстановить.
> // Обработчки прерывания > void interrupt COM_1 () { > > COMfunction(0); // Функция обработчика > > _asm { > mov al, 0x20 > out 0x20, al > //out 0xa0, al > } > } Обработчик выглядит примерно так:
---
Не забываю подтверждение контроллеру. Читать состояние, если изменилось состосние, читать данные, если пришли данные...
Если это 4 прерывание, но не от СОМпорта, передаю его дальше по цепочке.
Тогда мне только оправдаться остается ;)22.09.03 19:13 Автор: oleaster Статус: Незарегистрированный пользователь Отредактировано 22.09.03 22:51 Количество правок: 1
1. В своих "наработках" я выдернул участок кода из своей проги (сама прога большая и "нечитабельная"), которая обслуживает 14 СОМ портов (2 стандартных+8-портовая плата+4-портовая плата) ,- поэтому там "проскочил" второй контроллер.
2. Я свою первую прогу для СОМ порта написал только 4 месяца назад - со всеми вытекающими отсюда ....
Но кое-какие проблемы могу осветить:
- была ситуация, когда не шли прерывания , если не очищать FIFO-буфер перед началом (я себе это так представил).
Сюжет примерно следующий - сначала загружается прога, работающая с СОМ-портом без прерываний, а затем моя (с прерываниями) - прерывания у меня не шли. Причем если после перезагрузки загрузить первой мою прогу ,- прерывания шли нормально.
- была ситуация, когда при одной разводке кабеля ("без готовности") программа работала, а при другой нет ("с готовностью") ,- не шли прерывания на прием.
В настоящее время все эти проблемы у меня решены.
3. Я полностью в работе порта не разбирался (заработало у меня и ладно) + теоретик из меня никудышный ... ,- благо есть amirul, который и мне в свое время помог с СОМ портом разобраться.
Не обидешься, если я скажу, что не стал разбираться в твоих исходняках ;)
Если у тебя так и не заработает "свое", просто попробуй "мое" ,- оно проверено на нескольких "железках" и вроде работает.
Тогда мне только оправдаться остается ;)23.09.03 10:43 Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
> Но кое-какие проблемы могу осветить: > - была ситуация, когда не шли прерывания , если не очищать > FIFO-буфер перед началом (я себе это так представил). > Сюжет примерно следующий - сначала загружается прога, > работающая с СОМ-портом без прерываний, а затем моя (с > прерываниями) - прерывания у меня не шли. Причем если после > перезагрузки загрузить первой мою прогу ,- прерывания шли > нормально. > - была ситуация, когда при одной разводке кабеля ("без > готовности") программа работала, а при другой нет ("с > готовностью") ,- не шли прерывания на прием.
Судя по всему в этом вышесказанном ФИФО и был виноват.
> 3. Я полностью в работе порта не разбирался (заработало у > меня и ладно) + теоретик из меня никудышный ... ,- благо > есть amirul, который и мне в свое время помог с СОМ портом > разобраться. > Не обидешься, если я скажу, что не стал разбираться в твоих > исходняках ;) > Если у тебя так и не заработает "свое", просто попробуй > "мое" ,- оно проверено на нескольких "железках" и вроде > работает.
"Свое" я привел только для того, чтобы показать, что оно от "Вашего" почти ни чем не отличается.
"Мое" вроде как делает вид, что вроде как заработало. Помогли повторные опросы идентификации прерывания.
Варианты22.09.03 20:04 Автор: amirul <Serge> Статус: The Elderman
> 2. Я свою первую прогу для СОМ порта написал только 4 > месяца назад - со всеми вытекающими отсюда .... > Но кое-какие проблемы могу осветить: > - была ситуация, когда не шли прерывания , если не очищать > FIFO-буфер перед началом (я себе это так представил). > Сюжет примерно следующий - сначала загружается прога, > работающая с СОМ-портом без прерываний, а затем моя (с > прерываниями) - прерывания у меня не шли. Причем если после > перезагрузки загрузить первой мою прогу ,- прерывания шли > нормально. Возможно прерывания были просто запрещены. А если разрешены, то например FIFO был заполнен (или в случае отключенного FIFO - регистр RBR), и прерывание, сигнализирующее о приеме данных уже и так pend-илось и не срабатывало повторно (это я уже написал в другом посте). В виндовых дриверах, чтобы перезапустить пендящиеся прерывания используется следующий метод (рекомендую к использованию в собственных разработках):
ЗАПРЕТИТЬ ВСЕ ПРЕРЫВАНИЯ
РАЗРЕШИТЬ ВСЕ ПРЕРЫВАНИЯ
При разрешении запускаются прерывания, которые ждут обработки. Запрещение/разрешение производится через регистр IER (Interrupt Enable Register).
> - была ситуация, когда при одной разводке кабеля ("без > готовности") программа работала, а при другой нет ("с > готовностью") ,- не шли прерывания на прием. А тут возможно не шли не прерывания, а сами данные. Не могу сказать точно, но если есть DTR-DSR или RTS-CTS и при этом приемник показывает что он не готов, то большинство передатчиков просто не будут посылать данные. И ясное дело не будет никаких прерываний. Возможно нужно было поднять DTR и CTS.
> 3. Я полностью в работе порта не разбирался (заработало у > меня и ладно) + теоретик из меня никудышный ... ,- благо > есть amirul, который и мне в свое время помог с СОМ портом > разобраться. Дык, я тоже не особо заморачивался - почитал Михаила Гука "Энциклопедия периферийных устройств PC" - там все понятно написано, хотя и сжато.
Вот об этом я и говорил.22.09.03 11:20 Автор: amirul <Serge> Статус: The Elderman
---
> Не забываю подтверждение контроллеру. Читать состояние, > если изменилось состосние, читать данные, если пришли > данные... > Если это 4 прерывание, но не от СОМпорта, передаю его > дальше по цепочке.
Обработалось одно прерывание и выход. На самом деле нужно нечто типа
while (!(com_port_interrupt_identification_mask & 1)) {
// Здесь идет switch обработчика и выставляется флаг, что было обработано прерывание от порта
}
// Если флаг не установлен - передать по цепочке
---
А непосредственно *до* этого что происходит?19.09.03 16:43 Автор: amirul <Serge> Статус: The Elderman
> Перестают идти прерывания. Может какие-то хитрости с ФИФО? > Если с ней, то как ее программировать? Какие установки > по-умолчанию? ФИФО на прерывания никак не влияет насколько мне известно (в том смысле, что отличие только в размере буфера 1 байт и 16). Влияет только регистр IER (interrupt enable register) и бит OUT2 в MCR (modem control register).
Но. Возможно ты неправильно обрабатываешь само прерывание. Прерывание срабатывает только один раз и пока не будет обработано - следующее такое не придет. А в сочетании с приоритезацией прерываний, возможно ты обрабатываешь только самое высокоприоритетное прерывание и выходишь из обработчика. Бит 0 (No Interrupt Pending) в IIR (interrupt identification register) остается в 0 и прерывание не приходит, так как считается, что до сих пор обрабатывается старое.
А вообще, опиши подробнее, что ты вообще делаешь - будет легче понять что ты делаешь не так.
А непосредственно *до* этого что происходит?22.09.03 11:36 Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
> ФИФО на прерывания никак не влияет насколько мне известно > (в том смысле, что отличие только в размере буфера 1 байт и > 16). Влияет только регистр IER (interrupt enable register) > и бит OUT2 в MCR (modem control register).
Я почему про ФИФО подумал - я ведь точно не знаю как оно работает, потому что документация под руки не попадалась. Думал, что наступает ситуация, когда должно возникнуть прерывание, но первое еще не обработано. Оно (второе) встает в очередь. После обработки первого нужно проверить очередь на наличие в нем отложенного прерывания, а я этого не делаю - не знаю как. Завершаю обработку первого и выхожу из обработчика. Все остальные сигналы продолжают вставать в очередь за вторым...
> Но. Возможно ты неправильно обрабатываешь само прерывание. > Прерывание срабатывает только один раз и пока не будет > обработано - следующее такое не придет. А в сочетании с Подтверждение контроллеру посылаю. Если прерывание от изменения состояния порта - читаю регистр состояния, прерывание по получению данных - считываю их....
> приоритезацией прерываний, возможно ты обрабатываешь только > самое высокоприоритетное прерывание и выходишь из > обработчика. Бит 0 (No Interrupt Pending) в IIR (interrupt > identification register) остается в 0 и прерывание не > приходит, так как считается, что до сих пор обрабатывается > старое.
А вот здесь чуть поподробнее.
> А вообще, опиши подробнее, что ты вообще делаешь - будет > легче понять что ты делаешь не так.
Задача была следующая:
==================================================================
Нужен микропроцессорный контроллер. Два логических входа, один логический выход. На выход выставляется логическая единица при обнаружении логической единицы с первого логического входа. Время, в течение которого на выходе присутствует логическая единица, прямо пропорционально зависит от частоты сигналов на втором логическом входе.
Полезно иметь возможность менять микрокод перепрошивкой ПЗУ (флэш-память желательно). Так же полезно иметь возможность менять параметры: минимальное время присутствия логической единицы на логическом выходе и соотношение частоты логических сигналов на втором логическом входе и времени присутствия логической единицы на логическом выходе.
Минимальный интервал сигналов на первом входе ~5 миллисекунд, на втором ~1 миллисекунда. Максимальная дискретность выходных сигналов ~1 микросекунда. Минимальная частота обработки 1 мегагерц.
Предусмотреть выключение питания, стабилизатор питания от сети постоянного тока 12 вольт, сохранение работоспособности при питающем напряжении в диапазоне от 8 до15 вольт.
Интерфейс: Выход – напряжение питания, ток 3 ампера (до 5 ампер - уточняется), индуктивная нагрузка. Первый вход – 12 вольт активное состояние, управление по фронту, предусмотреть фильтрацию помехи (уточняется). Второй вход потребует усиление до ТТЛ, индуктивный датчик или слаботочный датчик, напряжение милливольты, ток микроамперы.
Возможен вариант: Время логической единицы на выходе имеет фиксированную величину (тоже предусмотреть возможность изменения), если сигнал с третьего логического входа имеет активное состояние, которое равно логическому нулю (замкнут на «землю»).
==================================================================
Перед тем как железяку делать, хотелось бы на писюке отладить.
Взял СОМпорт - есть два сигнала на вход, которые вызывают прерывание, два на выход, хотя хватает одного.
Перепрограммировал таймер под бОльшую частоту. Разумеется во столько же раз реже передаю таймерное прерывание старому обработчику. Ведется свой счетчик. При прерывании от СОМпорта вычитаю разницу счетчиков. В основной программе вывожу эту разницу - сколько раз тикнуло между прерываниями от СОМ порта. На СОМпорт подал сигнал от датчика вращения кулера (как раз 12 вольт и частота нормальная). Примерно в течение секунды чиселки на экране бегут (изменяются около какого-то значения), потом не изменяются ни на единичку.
А непосредственно *до* этого что происходит?22.09.03 12:04 Автор: amirul <Serge> Статус: The Elderman
> Я почему про ФИФО подумал - я ведь точно не знаю как оно > работает, потому что документация под руки не попадалась. Если ты его не проинициализируешь - оно работать вообще не будет :-)
> Думал, что наступает ситуация, когда должно возникнуть > прерывание, но первое еще не обработано. Оно (второе) > встает в очередь. После обработки первого нужно проверить > очередь на наличие в нем отложенного прерывания, а я этого > не делаю - не знаю как. Завершаю обработку первого и выхожу Так и есть. Чтобы проверить наличие отложенного прерывания надо прочитать IIR еще раз. То есть делать это в цикле пока бит 0 не станет в 1.
> > identification register) остается в 0 и прерывание не > > приходит, так как считается, что до сих пор > обрабатывается > > старое. > > А вот здесь чуть поподробнее. Приоритеты прерываний в порядке убывания следующие: RLS, RDA, CTI, THR, MS. А теперь по русски:
RLS - Line error
RDA - Char received
CTI - Timeout (только для FIFO)
THR - Char transmitted
MS - Modem status changed
Как сбрасываются ты знаешь. После сброса прерывания с более высоким приоритетом нужно проверить нет ли прерывания с меньшим. Для этого нужно повторно прочитать IIR.
Вроде как заработало!23.09.03 11:00 Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
> Если ты его не проинициализируешь - оно работать вообще не > будет :-)
А как это ФИФО инициализировать?
Старые ДОСовские проги спокойно работают на 16550А, и даже не "догадываются" про наличие ФИФО. Они-то это ФИФО не инициализируют.
Может же моя програмка поступать так же?
> Так и есть. Чтобы проверить наличие отложенного прерывания > надо прочитать IIR еще раз. То есть делать это в цикле пока > бит 0 не станет в 1.
Попробовал вчера вечером - есть эффект!
> Приоритеты прерываний в порядке убывания следующие: RLS, > RDA, CTI, THR, MS. А теперь по русски: > > RLS - Line error > RDA - Char received > CTI - Timeout (только для FIFO) > THR - Char transmitted > MS - Modem status changed > > Как сбрасываются ты знаешь. После сброса прерывания с более > высоким приоритетом нужно проверить нет ли прерывания с > меньшим. Для этого нужно повторно прочитать IIR.
Долго погонять не удалось - времени было мало - поздно приехал. Может быть разок зависало, или мне показалось. Раньше и секунды не работало. Вчера несколько раз по минутке гонял - судя по всему помогло.
Спасибо большое за подсказку. А то я во всяких МАНах и ФАКах ковырялся - ничего об этом не было, видимо старые были, еще про 16450. В некоторых ошибки были - не было указано, что нужно OUT2 установить, чтобы прерывания шли.
Один вопрос остался - как узнать, что это именно 16550А, как установить длину очереди или запретить очередь, как после закидывания байта в передатчик понять, что туда еще один влезет (в очереди еще есть место)?
Вроде как заработало!23.09.03 12:01 Автор: amirul <Serge> Статус: The Elderman
> > Если ты его не проинициализируешь - оно работать > вообще не > > будет :-) > > А как это ФИФО инициализировать? > Старые ДОСовские проги спокойно работают на 16550А, и даже > не "догадываются" про наличие ФИФО. Они-то это ФИФО не > инициализируют. > Может же моя програмка поступать так же? Запросто. Когда я говорил, что фифо не будет работать я имел в виду ИМЕННО фифо. То есть порт будет работать как старый 16450 (или как его так, у которого фифо вообще нет).
> Спасибо большое за подсказку. А то я во всяких МАНах и > ФАКах ковырялся - ничего об этом не было, видимо старые > были, еще про 16450. В некоторых ошибки были - не было В 16450 это точно так же сделано. Вообще большую часть инфы о работе порта я почерпнул из чтения сырцов виндового дривера.
> указано, что нужно OUT2 установить, чтобы прерывания шли. > Один вопрос остался - как узнать, что это именно 16550А, Вот как это делается в виндовом дривере:
#define SERIAL_IIR_FIFOS_ENABLED 0xc0
DISABLE_ALL_INTERRUPTS(Extension->Controller);
WRITE_MODEM_CONTROL(
Extension->Controller,
(UCHAR)SERIAL_MCR_OUT2
);
//
// See if this is a 16550. We do this by writing to
// what would be the fifo control register with a bit
// pattern that tells the device to enable fifo's.
// We then read the iterrupt Id register to see if the
// bit pattern is present that identifies the 16550.
//
WRITE_FIFO_CONTROL(
Extension->Controller,
SERIAL_FCR_ENABLE
);
regContents = READ_INTERRUPT_ID_REG(Extension->Controller);
if (regContents & SERIAL_IIR_FIFOS_ENABLED) {
// ФИФО присутствует, это 16550(А)
}
---
> как установить длину очереди или запретить очередь, как Очередь запрещена по умолчанию. Если ее не включать - будет работать только RBR (receive buffer register - можно считать однобайтной очередью). Включается в FCR (FIFO control register). Но кроме того придется выставлять еще highwater (порог срабатывания прерывания) и т.д..
> после закидывания байта в передатчик понять, что туда еще > один влезет (в очереди еще есть место)? Если работаешь на прерываниях, то тебе придет прерывание, когда он освободится. Если же предпочитаешь поллить, читай LSR (line status register) там два бита THRE (transmit holding register empty) и TEMPT (transmitter empty). THRE ставится в 1, когда очередной байт из буфера ушел в передатчик (но передатчик может еще работать), а TEMPT - когда передатчик не работает.
Вроде как заработало!23.09.03 14:14 Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
> Запросто. Когда я говорил, что фифо не будет работать я > имел в виду ИМЕННО фифо. То есть порт будет работать как > старый 16450 (или как его так, у которого фифо вообще нет).
Дык почему мне приходится ИИР пулить, если фифо по-умолчанию выключено? После загрузки голого ДОСа запускается только моя прога - никто ФИФО не включает.
> Очередь запрещена по умолчанию. Если ее не включать - будет > работать только RBR (receive buffer register - можно > считать однобайтной очередью). Включается в FCR (FIFO > control register). Но кроме того придется выставлять еще > highwater (порог срабатывания прерывания) и т.д..
Что же у меня в очередь вставало? Я то ФИФО не трогал.
> Если работаешь на прерываниях, то тебе придет прерывание, > когда он освободится. Если же предпочитаешь поллить, читай > LSR (line status register) там два бита THRE (transmit > holding register empty) и TEMPT (transmitter empty). THRE > ставится в 1, когда очередной байт из буфера ушел в > передатчик (но передатчик может еще работать), а TEMPT - > когда передатчик не работает.
Прерывание, разумеется, должно произойти, когда буфер (transmit holding register) опустошится, т.е. после закидывания первого байта, если очередь не равна нулю, а потом (после заполнения очереди) с периодом передачи байтиков?
Еще я заметил, что СОМпорт "нежная" вещь. Припаял провода (~3м) к сигналам готовности. Подаю сигнал на один - и во втором тоже сигнал появлялся. Распрямил (скрученные колечком) провода и разнес друг от друга - наводка пропала.
Ты похоже не совсем правильно понял23.09.03 15:32 Автор: amirul <Serge> Статус: The Elderman
> > Запросто. Когда я говорил, что фифо не будет работать > я > > имел в виду ИМЕННО фифо. То есть порт будет работать > как > > старый 16450 (или как его так, у которого фифо вообще > нет). > > Дык почему мне приходится ИИР пулить, если фифо > по-умолчанию выключено? После загрузки голого ДОСа > запускается только моя прога - никто ФИФО не включает. Приоритеты прерываний не имеют вообще никакого отношения к фифо и были, кажется еще в первых UART-ах. А то, что одновременно может несколько прерываний пендиться - могут не обязательно приходить одни и те же прерывания (в частности прерывание "готовы данные"). А если все таки фифо включается, то скорее всего его включает досовский дривер ком порта (устройства COM1:-COM4:, LPT:, AUX: и пр. даже не требуют ничего прописывать в config.sys). Для выключения просто запиши ноль в FCR.
А вообще это не должно тебе мешать - при уже пришедшем прерывании в любом случае нужно читать IIR пока не включится указанный флаг (бит 0). А если так, то включено FIFO или нет, для тебя все будет происходить прозрачно.
> Что же у меня в очередь вставало? Я то ФИФО не трогал. Могут прийти сразу много прерываний, например есть данные и готов к отправке.
> Прерывание, разумеется, должно произойти, когда буфер > (transmit holding register) опустошится, т.е. после > закидывания первого байта, если очередь не равна нулю, а > потом (после заполнения очереди) с периодом передачи > байтиков? В случае с FIFO все иначе. Там есть такая штука как порог срабатывания прерывания. То есть все данные, пришедшие/посылаемые в/из UART-а по прежнему попадают в очередь. Но в зависимости от установки прерывание может происходить когда в очереди 1, 4, 8 и 14 байт.
> Еще я заметил, что СОМпорт "нежная" вещь. Припаял провода > (~3м) к сигналам готовности. Подаю сигнал на один - и во > втором тоже сигнал появлялся. Распрямил (скрученные > колечком) провода и разнес друг от друга - наводка пропала. Ну это уже железные проблемы. Я свой провод не паял никогда, благо продается куча заводских.
Не то,ч тобы не совсем правильно, но не полностью.26.09.03 10:44 Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman Отредактировано 26.09.03 10:46 Количество правок: 1
> В случае с FIFO все иначе. Там есть такая штука как порог > срабатывания прерывания. То есть все данные, > пришедшие/посылаемые в/из UART-а по прежнему попадают в > очередь. Но в зависимости от установки прерывание может > происходить когда в очереди 1, 4, 8 и 14 байт.
А ФИФО что, только на прием/передачу работает? Я-то думал, что все прерывания/события встают в очередь, когда обработчик занят обработкой предыдущего события. Или, скажем, процессор временно запретил прерывания (cli), или обрабатывает другое прерывание, или прерывание от того же СОМпорта. В это время изменяется состояние модемных сингалов. Потом оно меняется на первоначальное. Потом разрешаются прерывания от СОМпорта. Вопрос: прерывания не произойдут, потому, что модемные линии вернулись в исходное состояние? прерывание будет, но обработчик ничего не "увидит" в модемных линиях? прерывание будет, но обработчик "узнает" о том ,что линии изменились в одно из состояний? прерывание будет, и опросами портов обработчик "узнает" об обоих изменениях линий?
Похоже24.09.03 09:56 Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
> Приоритеты прерываний не имеют вообще никакого отношения к > фифо и были, кажется еще в первых UART-ах. А то, что > одновременно может несколько прерываний пендиться - могут > не обязательно приходить одни и те же прерывания (в > частности прерывание "готовы данные"). А если все таки фифо > включается, то скорее всего его включает досовский дривер > ком порта (устройства COM1:-COM4:, LPT:, AUX: и пр. даже не > требуют ничего прописывать в config.sys). Для выключения > просто запиши ноль в FCR.
Адрес портика ФЦР какой?
> Могут прийти сразу много прерываний, например есть данные и > готов к отправке.
Да я, в общем-то, только CTS/DSR дергал...
> В случае с FIFO все иначе. Там есть такая штука как порог > срабатывания прерывания. То есть все данные, > пришедшие/посылаемые в/из UART-а по прежнему попадают в > очередь. Но в зависимости от установки прерывание может > происходить когда в очереди 1, 4, 8 и 14 байт.
Обалдеть... Получается, если длина очереди больше 1, то при приходе одного байтика обработчик об этом и не узнает.
> Ну это уже железные проблемы. Я свой провод не паял > никогда, благо продается куча заводских.
Мне-то для своей железяки заводской не подходит.
ntddk/src/kernel/serial/serial.h24.09.03 11:30 Автор: amirul <Serge> Статус: The Elderman
> > просто запиши ноль в FCR. > > Адрес портика ФЦР какой?
// Offsets from the base register address of the
// various registers for the 8250 family of UARTS.
//
#define RECEIVE_BUFFER_REGISTER ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
#define TRANSMIT_HOLDING_REGISTER ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
#define INTERRUPT_ENABLE_REGISTER ((ULONG)((0x01)*SERIAL_REGISTER_STRIDE))
#define INTERRUPT_IDENT_REGISTER ((ULONG)((0x02)*SERIAL_REGISTER_STRIDE))
#define FIFO_CONTROL_REGISTER ((ULONG)((0x02)*SERIAL_REGISTER_STRIDE))
#define LINE_CONTROL_REGISTER ((ULONG)((0x03)*SERIAL_REGISTER_STRIDE))
#define MODEM_CONTROL_REGISTER ((ULONG)((0x04)*SERIAL_REGISTER_STRIDE))
#define LINE_STATUS_REGISTER ((ULONG)((0x05)*SERIAL_REGISTER_STRIDE))
#define MODEM_STATUS_REGISTER ((ULONG)((0x06)*SERIAL_REGISTER_STRIDE))
#define DIVISOR_LATCH_LSB ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
#define DIVISOR_LATCH_MSB ((ULONG)((0x01)*SERIAL_REGISTER_STRIDE))
#define SERIAL_REGISTER_SPAN ((ULONG)(7*SERIAL_REGISTER_STRIDE))
---
Смещение 2 короче. То бишь на чтение это IIR, на запись - FCR.
> > происходить когда в очереди 1, 4, 8 и 14 байт. > > Обалдеть... Получается, если длина очереди больше 1, то при > приходе одного байтика обработчик об этом и не узнает. Именно. И кстати это хорошо. При пороге в 14 байт сработает одно прерывание на 14 пришедших символов, которое быстренько выгребет их из очереди (а пока обработчик разгребает очередь может прийти и еще символ другой). А при пороге в 1 байт - будет 14 прерываний (со всеми вытекающими: сохранение контекста с последующим восстановлением, причем в защищенном режиме он больше) - оверхед аднака. Хотя и не такой уж большой.
Хорошо то хорошо, да ничего хорошего.24.09.03 14:07 Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
> Смещение 2 короче. То бишь на чтение это IIR, на запись - FCR.
Спасобо.
> Именно. И кстати это хорошо. При пороге в 14 байт сработает > одно прерывание на 14 пришедших символов, которое > быстренько выгребет их из очереди (а пока обработчик > разгребает очередь может прийти и еще символ другой). А при > пороге в 1 байт - будет 14 прерываний (со всеми > вытекающими: сохранение контекста с последующим > восстановлением, причем в защищенном режиме он больше) - > оверхед аднака. Хотя и не такой уж большой.
Это только для скорости хорошо, правда при частоте в 2-3 гигагерца ловить 11520 прерываний в секунду - мелочи.
А, вот, если надо передать один байтик, и, чтоб, принимающий комп на него СРАЗУ ЖЕ ответил... Байтик упадет в очередь, а обработчик об этом не узнает и не ответит, а компьюер приемник будет ждать. Или при длине пакета не кратного длине очереди. Точнее, если длина пакета больше 2 байт (например, 3), то при длине очереди 2, 4, 8 и 14 эта бяка произойдет.
Все еще немного хуже...24.09.03 16:05 Автор: leo <Леонид Юрьев> Статус: Elderman
> Это только для скорости хорошо, правда при частоте в 2-3 > гигагерца ловить 11520 прерываний в секунду - мелочи. > А, вот, если надо передать один байтик, и, чтоб, > принимающий комп на него СРАЗУ ЖЕ ответил... Байтик упадет > в очередь, а обработчик об этом не узнает и не ответит, а > компьюер приемник будет ждать. Или при длине пакета не > кратного длине очереди. Точнее, если длина пакета больше 2 > байт (например, 3), то при длине очереди 2, 4, 8 и 14 эта > бяка произойдет.
Это не совсем так, при включеном FIFO и паузе в передаче, прерывание будет сгенерированно даже при незаполненном FIFO. Этот "таймаут" равет удвоенному времени передачи одного символа (если я не ошибаюсь).
На многих новых чипсетах FIFO отключается только "слегка". Варианты самые разные. Например на передачу "в очередь" можно поставить больше одного байта, даже если FIFO выключено.
При приеме тоже возможны "хитрости", например если вовремя не вычитать данные то будет overrun в статусе линии, но при этом из регистра данных приемника можно считывать принятые и не "затерные" overrun-ом байты. И в некоторых случаях (на некоторых чипах) приемник "не видит" одного принятого байта до таймаута, либо до стартовых битов следующей посылки.
С прерываниями по статусу модема все еще хуже. Почти все чипы допускают "потерю" прерывания по статусу модема, если одновременно с этим возникает еще какое-либо событие (прерывание).
> Это не совсем так, при включеном FIFO и паузе в передаче, > прерывание будет сгенерированно даже при незаполненном > FIFO. Этот "таймаут" равет удвоенному времени передачи > одного символа (если я не ошибаюсь). Это радует.
Я просто хотел "таймер" на порте организовать: после передачи байтика "в никуда" в обработчике еще один туда же запихнуть.
> На многих новых чипсетах FIFO отключается только "слегка". > Варианты самые разные. Например на передачу "в очередь" > можно поставить больше одного байта, даже если FIFO > выключено. > С прерываниями по статусу модема все еще хуже. Почти все > чипы допускают "потерю" прерывания по статусу модема, если > одновременно с этим возникает еще какое-либо событие > (прерывание). Прерывания модемные, надеюсь.
А вот это очень неприятно, если это действительно так. Не хочется события терять.