Студопедия — Теоретические положения
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Теоретические положения






Несмотря на то, что обработка прерываний является ключевой особенностью ОСРВ, во многих традиционных операционных системах обработка прерываний реализована очень неуклюже. Но только не в QNX. Как будет показано ниже, обработка прерываний в QNX тривиальна: из-за быстрого времени переключения состояния процессора в QNX большая часть работы по обработки прерываний, обычно проводимая обработчиком прерываний, производится внутри потока.

Рассмотрим функции QNX по обработке прерываний.

1. Подключение и отключение от каналов прерываний.

Чтобы установить обработчик прерываний, основная программа должна сообщить ОС о том, что требуется связать обработчик прерываний с некоторым источником прерываний. На платформе x86 обычно существуют 16 аппаратных линий запросов на прерывания (IRQ) и несколько источников программных прерываний. На платформах MIPS и PPC фактическое число прерываний зависит от конфигурации аппаратного обеспечения, поставляемого производителем материнской платы. В любом случае, поток определяет, какой источник прерывания ему требуется связать с каким обработчиком прерываний, используя вызовы к функциям InterruptAttach() или InterruptAttachEvent().

Когда программа желает отключить обработчик прерываний от источника прерываний, она может вызвать InterruptDetach():

#define IRQ3 3

// прототип обработчика прерываний:

extern const sigevent *serint (void *, int);

...

/* связать обработчик прерываний "serint"

* с IRQ 3, т.е. с COM2: */

ThreadCtl(_NTO_TCTL_IO, 0);

id = InterruptAttach (IRQ3, serint, NULL, 0, 0);

...

// сделав работу, отключиться от источника прерываний:

InterruptDetach (id);

Так как обработчик прерываний может потенциально получить контроль над ЭВМ, то связывать источник прерывания с обработчиком позволено не каждому потоку. Поток должен иметь флаг I/O Privity для того, чтобы иметь возможность манипулировать портами ввода/вывода и изменять флаг разрешения прерываний процессором (т.е. следующими командами платформы x86: in, ins, out, outs, cli, и sti).

На текущий момент только пользователь «root» может получить привилегию I/O Privity.

2. Обработчик прерываний.

В приведенном выше примере, функция serint() является обработчиком прерываний. Обычно обработчик прерываний отвечает за:

§ определение аппаратного обеспечения, требующего обслуживания, если такое имеется;

§ проведение некоторого обслуживание данной аппаратуры (что обычно делается просто чтением и/или записью в аппаратные регистры);

§ обновление некоторых структур, общих между обработчиком прерываний и некоторыми потоками функционирующего приложения;

§ сообщение приложению того, что некоторое событие произошло.

В зависимости от сложности аппаратного устройства, обработчика прерываний и приложения, некоторые из приведенных выше пунктов могут быть опущены.

Рассмотрим данные пункты подробнее.

3. Определение источника прерываний

В зависимости от аппаратной конфигурации оборудования, фактически может существовать много источников, связанных с одним прерыванием. В таком случае, при наличии хорошего стиля программирования, можно гарантированно определить какой источник прерываний действительно вызвал прерывание.

Многие программируемые контроллеры прерываний (ПКП, PIC) могут быть запрограммированы на отработку прерываний в режиме, чувствительном только к фронту сигнала, или в режиме прерываний по уровню сигнала. В зависимости от этого, прерывания могут быть совместными (см. рис.2).

Рис.2 – Обработка прерываний от нескольких источников

В показанном на рис.2 случае, если ПКП функционирует в режиме прерываний по уровню сигнала, активным является тот запрос на прерывание (IRQ), который имеет наивысший уровень. Тогда второй запрос на прерывание (см. шаг 2 на рис.2) не вызовет нового прерывания. Прерывание будет активным, даже после того, как оригинальное прерывание убрано (шаг 3), до тех пор, пока последний запрос не убран (шаг 4).

В режиме, чувствительном только к фронту сигнала, прерывание запрашивается только один раз – на шаге 1. Только после того, как линия запроса на прерывание освободится, и появится новый запрос, ПКП будет считать, что появилось новое прерывание.

QNX позволяет нескольким обработчикам прерываний быть связанным с одной и той же линией запросов прерываний (IRQ). Тогда каждый обработчик в цепи обработчиков одного и тог же IRQ должен опрашивать связанное устройство, и выяснять запрашивало ли оно прерывание. Такая организация надежно работает в режиме прерываний по уровню сигнала, а не в режиме, чувствительном только к фронту сигнала.

4. Обслуживание аппаратного обеспечения

В режиме прерываний по уровню сигнала ваш обработчик прерываний должен очищать источник прерываний (или, по крайней мере, маскировать его через InterruptMask()) до завершения обработки прерывания, иначе будет выполняться бесконечный цикл обработки одного и того же прерывания.

В режиме, чувствительном только к фронту сигнала, нет таких ограничений.

Таким образом, чтобы обработать прерывание, ваш обработчик должен сделать очень мало: очистить (замаскировать) источник прерывания и затем фактически передать всю работу по обработки прерывания потоку.

Такой подход рекомендуется по следующим причинам:

· время переключения между обработчиком прерываний и потоком очень мало – обычно порядка нескольких микросекунд;

· из тела функции – обработчика прерываний – возможно вызвать только 7 функций ядра QNX;

· обработчик прерываний выполняется со значительно более высоким приоритетом, чем любая другая программы в ОС, таким образом, обработчик прерываний потребляет значительную часть процессорного времени, что отрицательно сказывается на работе ОС в реальном времени.

5. Функции, вызываемые из обработчика прерываний

Из тела функции – обработчика прерываний – невозможно вызывать ни одну функцию, кроме следующих 7 функций ядра QNX и функций str*() и mem*() (таких как strcpy() и memcpy()), кроме strdup():

· InterruptEnable()

· InterruptDisable()

· InterruptLock()

· InterruptUnlock()

· InterruptMask()

· InterruptUnmask()

Для предотвращения прерывания друг друга потоком и обработчиком прерывания, необходимо сообщить ядру об отключении на это время прерываний. На однопроцессорной системе для этого необходимо вызвать функцию InterruptDisable(). Но на многопроцессорной системе необходимо вызвать InterruptLock() (и для включения прерываний – InterruptUnlock()).

Для расширения портируемости кода рекомендуется и на однопроцессорных системах пользоваться функциями InterruptLock() и InterruptUnlock().

Функции InterruptMask() и InterruptUnmask() отключают и включают распознавание указанной линии запроса на прерывание в ПКП.

Пример реализации обработчика прерываний:

main ()

{

// произвести инициализацию и проч.

...

// запустить выделенный поток обработки прерываний:

pthread_create (NULL, NULL, int_thread, NULL);

...

// произвести дальнейшие действия

...

}

 

// выделенный поток обработки прерываний:

void *int_thread (void *arg)

{

// включить доступ к регистрам аппаратуры:

ThreadCtl (_NTO_TCTL_IO, NULL);

...

// инициализировать аппаратуру:

...

// связать обработчик прерываний с IRQ 3:

InterruptAttach (IRQ3, isr_handler, NULL, 0, 0);

...

// возможно, увеличить приоритет потока здесь

...

// произвести обслуживание аппаратуры, когда

// обработчик прерываний нам об этом сообщаит:

while (1)

{

InterruptWait (NULL, NULL);

// здесь обработчик прерываний сообщил о том,

// что оборудование вызвало прерывание и требует

// обслуживания

...

// произвести обслуживание

...

// Если в обработчике прерываний isr_handler

// была вызвана функция InterruptMask, то

// вызвать InterruptUnmask

}

}

// обработчик прерываний

const struct sigevent * isr_handler (void *arg, int id)

{

// проверяет, вызвало ли оборудование прерывание,

// если нет, то просто возвращает (NULL);

...

// в режиме прерываний по уровню сигнала следует

// очистить источник прерываний или вызвать

// InterruptMask

...

// возвратить указатель на структуру event,

// инициализированную в main значением SIGEV_INTR,

// это позволит функции InterruptWait в

// "int_thread" разблокироваться:

return (&event);

}

Функция InterruptAttach:

int InterruptAttach(int intr,

const struct sigevent * (* handler)(void *, int),

const void * area,

int size,

unsigned flags);

Аргументы:

intr – линия запроса на прерывание, с которой связывается обработчик прерываний;

handler – указатель на функцию – обработчик прерываний;

area – указатель на область обмена данных с основным процессов (если такая существует) или NULL иначе.

size – размер области обмена данных.

flags – флаги, определяющие как следует связать обработчик прерываний.

Функция InterruptMask:

int InterruptMask(int intr, int id);

Аргументы:

intr – маскируемое прерывание.

id – значение, возвращенное InterruptAttach() или InterruptAttachEvent(), или -1, если вы не хотите, чтобы ядро ОС отслеживало маскирование прерываний для каждого обработчика.

Значения аргумента id игнорируется, если вы при связывании обработчика прерываний с прерыванием не указали флаг _NTO_INTR_FLAGS_TRK_MSK.

Функция InterruptUnmask.

int InterruptUnmask(int intr, int id);

Аргументы:

intr – маскируемое прерывание.

id – значение, возвращенное InterruptAttach() или InterruptAttachEvent(), или -1, если вы не хотите, чтобы ядро ОС отслеживало маскирование прерываний для каждого обработчика. Значения аргумента id игнорируется, если вы при связывании обработчика прерываний с прерыванием не указали флаг _NTO_INTR_FLAGS_TRK_MSK.

Функция mmap_device_io – получить доступ к аппаратным регистрам устройства.

uintptr_t mmap_device_io(size_t len, uint64_t io);

Аргументы:

len – число байт памяти ввода/вывода устройства, доступ к которому необходимо получить.

io – адрес области памяти к которой необходимо получить доступ.

Функция out8 – записать 8-битовое значение в порт.

void out8(uintptr_t port, uint8_t val);

Аргументы:

port – порт ввода/вывода, в который необходимо осуществить запись.

val – значение, которое необходимо записать.

Функция clock() – получить время от начала выполнения приложения (его следует поделить на CLOCKS_PER_SEC для получения времени в секундах).

clock_t clock(void);







Дата добавления: 2015-08-31; просмотров: 876. Нарушение авторских прав; Мы поможем в написании вашей работы!



Обзор компонентов Multisim Компоненты – это основа любой схемы, это все элементы, из которых она состоит. Multisim оперирует с двумя категориями...

Композиция из абстрактных геометрических фигур Данная композиция состоит из линий, штриховки, абстрактных геометрических форм...

Важнейшие способы обработки и анализа рядов динамики Не во всех случаях эмпирические данные рядов динамики позволяют определить тенденцию изменения явления во времени...

ТЕОРЕТИЧЕСКАЯ МЕХАНИКА Статика является частью теоретической механики, изучающей условия, при ко­торых тело находится под действием заданной системы сил...

Принципы и методы управления в таможенных органах Под принципами управления понимаются идеи, правила, основные положения и нормы поведения, которыми руководствуются общие, частные и организационно-технологические принципы...

ПРОФЕССИОНАЛЬНОЕ САМОВОСПИТАНИЕ И САМООБРАЗОВАНИЕ ПЕДАГОГА Воспитывать сегодня подрастающее поколение на со­временном уровне требований общества нельзя без по­стоянного обновления и обогащения своего профессио­нального педагогического потенциала...

Эффективность управления. Общие понятия о сущности и критериях эффективности. Эффективность управления – это экономическая категория, отражающая вклад управленческой деятельности в конечный результат работы организации...

Факторы, влияющие на степень электролитической диссоциации Степень диссоциации зависит от природы электролита и растворителя, концентрации раствора, температуры, присутствия одноименного иона и других факторов...

Йодометрия. Характеристика метода Метод йодометрии основан на ОВ-реакциях, связанных с превращением I2 в ионы I- и обратно...

Броматометрия и бромометрия Броматометрический метод основан на окислении вос­становителей броматом калия в кислой среде...

Studopedia.info - Студопедия - 2014-2024 год . (0.013 сек.) русская версия | украинская версия