Указывает, что ядро должно отследить, сколько раз данное прерывание было маскировано. Это приводит к несколько большей загрузке ядра, но это необходимо для корректного демаскирования источника прерываний при завершении потока или процесса.
Обработчик прерывания
Давайте рассмотрим собственно обработчик прерывания. В первом примере применим
В продолжение примера приведем функцию
/*
* int1.c
*/
#include
#include
#define REG_RX 0
#define REG_II 2
#define REG_LS 5
#define REG_MS 6
#define IIR_MASK 0x07
#define IIR_MSR 0x00
#define IIR_THE 0x02
#define IIR_RX 0x04
#define IIR_LSR 0x06
#define IIR_MASK 0x07
volatile int serial_msr; // Сохраненное значение
// регистра состояния модема
volatile int serial_rx; // Сохраненное значение
// регистра приема
volatile int serial_lsr; // Сохраненное значение
// регистра состояния линии
static int base_reg = 0x2f8;
const struct sigevent* intHandler(void *arg, int id) {
int iir;
struct sigevent *event = (struct sigevent*)arg;
/*
* Определить (и очистить) источник прерывания
* чтением регистра идентификации прерывания
*/
iir = in8(base_reg + REG_II) & IIR_MASK;
/* Нет прерывания? */
if (iir & 1) {
/* Значит, нет и события */
return (NULL);
}
/*
* Выяснить, что вызвало прерывание, и определить, надо ли
* потоку что-нибудь с этим делать.
* (Константы основаны на строении регистра
* идентификации прерывания 8250.)
*/
switch (iir) {
case IIR_MSR:
serial_msr = in8(base_reg + REG_MS);
/* Разбудить поток */
return (event);
break;
case IIR_THE:
/* Ничего не делать */
break;
case IIR_RX:
/* Считать символ */
serial_rx = in8(base_reg + REG_RX);
break;
case IIR_LSR:
/* Сохранить регистр состояния линии */
serial_lsr = in8(base_reg + REG_LS);
break;
default:
break;
}
/* Никого не беспокоить */
return (NULL);
}
Первое, что бросается в глаза, — что все переменные, к которым обращается ISR, должны быть объявлены как volatile
С помощью ключевого слова volatile
Следующее, на что мы обращаем внимание — это прототип самого обработчика прерывания. Он обозначен как const struct sigevent*
struct sigevent
. Это стандарт для всех подпрограмм обработки прерываний.Наконец, обратите внимание на то, что решение, передавать или не передавать событие потоку, принимает сам обработчик. Здесь мы генерируем событие только в случае прерывания по изменению регистра состояния модема (MSR) (событие определяется переменной
Бьерн Страуструп , Бьёрн Страуструп , Валерий Федорович Альмухаметов , Ирина Сергеевна Козлова
Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT