Поток управления при использовании
Ядро знает, что выполнялся «Поток 1», и что ISR не сказал ему что-либо сделать, поэтому после прерывания оно может смело вернуть управление «Потоку 1».
Для справки: вот что делает функция
// «Внутренний» обработчик
static const struct sigevent*
internalHandler(void *arg, int id) {
struct sigevent *event = arg;
InterruptMask(intr, id);
return (arg);
}
int InterruptAttachEvent(int intr,
const struct sigevent *event, unsigned flags) {
static struct sigevent static_event;
memcpy(&static_event, event, sizeof(static_event));
return
(InterruptAttach(intr, internalHandler, &static_event,
sizeof(*event), flags));
}
Так какую функцию применять? От редко возникающих прерываний почти всегда можно отмахнуться применением
При выборе функции для более часто возникающих прерываний требуется учесть множество факторов:
• Ненужные прерывания — если их число будет существенным, лучше применять
• Время реакции — если ваши аппаратные средства чувствительны к интервалу времени от момента выставления запроса на прерывание до отработки ISR, вам следует использовать
• Буферизация — если ваша аппаратура имеет встроенные средства буферизации, вы можете обойтись функцией
Функции, которые может вызывать ISR
Следующий вопрос, за который следует взяться, — это список функций, которые может вызывать ISR.
Небольшое отступление. Исторически, причина основных затруднений при написании обработчиков прерываний заключалась (и в большинстве других операционных систем до сих пор заключается) в том, что ISR работают в особом окружении.
Одна из конкретных причин, усложняющих написание ISR, состоит в том, что с точки зрения ядра ISR на самом деле не является «полноправным» потоком. С позиции ядра это, если хотите, такой таинственный «аппаратный» поток. Это означает, что ISR не имеет права делать никаких манипуляций «на уровне потока» — таких как, например, обмен сообщениями, синхронизация, системные вызовы, дисковый ввод/вывод, и т.д.
Не усложняет ли это написание ISR? Конечно. И поэтому решение заключается в том, чтобы в самом теле обработчика выполнять минимум работы, а все остальное делать уже на уровне потока, где есть доступ ко всем сервисам.
Ваши цели при написании ISR должны заключаться в следующем:
• считать переменчивую (в оригинале было «transient» —
• очистить источник прерывания;
• возможно, запланировать поток, который сделает реальную работу.