|
|
|
|
Настройка на управляемый прерываниями последовательный ввод/вывод
После получения базового адреса порта из области данных BIOS
Вы должны настроить последовательный порт и установить обработчик
прерываний перед началом управляемого прерываниями последовательного ввода/вывода. Номер прерывания и IRQ прерывания последовательного порта
зависит от того, какой порт используется, COM1 или
COM2. Как только Вы получили номер прерывания, Вы должны получить
адрес текущего обработчика и сохранить его. Таким образом, после
выхода из программы Вы можете восстановить первоначальное значение вектора прерываний. Функции MS-DOS 35h и 25h, соответственно,
получают и устанавливают обработчики для заданных номеров прерываний. Для этой цели Microsoft C предоставляет подпрограммы
_dos_getvect и _dos_setvect. Используя язык Си Вы можете проделать
это следующим образом:
short int_number; /* номер прерывания для связного порта */
void interrupt far s_inthndlr(void);
/* установить обработчик */
static void (interrupt far *old_handler)()
/* место для прежнего */
.
.
.
/* получить вектор прежнего прерывания и сохранить его */
old_handler = _dos_getvect(int_number);
/* установить новый обработчик с именем s_inthndlr
* запретить прерывания во время замены обработчика
*/
_disaple();
_dos_setvect(int_number, s_inthndlr);
_enable();
|
В приведенном примере мы представили обработчик как функцию
типа interrupt, которая является новым ключевым словом, содержащимся в Microsoft C 5.0. В следующем разделе продемонстрировано,
каким образом атрибут interrupt позволяет Вам писать обработчик
прерываний непосредственно в Microsoft C 5.0 (Turbo C 1.5 имеет
такую же возможность).
Следует обратить внимание на использование функций _disable и
_enable. Эти две функции соответствуют ассемблерным командам STI
и CLI. Таким образом, мы выключаем прерывания во время перехода
от одного обработчика последовательных прерываний к другому. С
другой стороны, прерывание, поступающее во время переключения,
может привести к тому, что может произойти сбой центрального процессора, так как вектор прерывания не являлся адресом какого-либо
действующего обработчика.
После того, как обработчик прерываний займет свое место, Вы
можете установить коммуникационные параметры и разрешить последовательному порту генерировать прерывания. Вы также должны разрешить распознавание
этих прерываний контроллером 8259A. Еще раз Вы
должны запретить прерывания до тех пор, пока порт и 8259A не будут готовы. Вот как мы можем проделать это с использованием
Microsoft C 5.0.
/* разрешает маску, зависящую от порта */
short intmask, int_enable_mask;
.
.
.
/* включает прерывания коммуникационного порта.
* устанавливает 8259A
*/
_disable();
/* устанавливает регистр управления модемом (порт = MCR) */
outp(MCR, MCRALL);
/* разрешает все прерывания последовательной платы
* (порт = IER)
*/
outp(IER, IERALL);
/* считывает регистр маски прерывания 8259A и записывает его
* обратно после логического умножения с _int_enable_mask
*/
intmask = inp(P8259_1) & int_enable_mask;
outp(P8259_1, intmask);
_enable();
|
С этой точки зрения последовательный порт начнет работать в
управляемом прерываниями режиме. Происходящие события зависят от
обработчика прерываний, который мы сейчас рассмотрим.
|
|