#c #linux #linux-kernel #interrupt-handling
#c #linux #linux-ядро #обработка прерываний
Вопрос:
Я готовлю презентацию о том, как ядро Linux обрабатывает прерывания, основываясь на книге Понимание ядра Linux ny Bovet amp; Cesati. На обложке указано, что она охватывает версию 2.6. Однако я не совсем понимаю, как должна работать данная функция __do_IRQ(). Хотя я немного (базово) программировал на C, я не могу понять некоторые инструкции.
spin_lock(amp;(irq_desc[irq].lock));
irq_desc[irq].handler->ack(irq);
irq_desc[irq].status amp;= ~(IRQ_REPLAY | IRQ_WAITING);
irq_desc[irq].status |= IRQ_PENDING;
if (!(irq_desc[irq].status amp; (IRQ_DISABLED | IRQ_INPROGRESS)) amp;amp; irq_desc[irq].action){
irq_desc[irq].status |= IRQ_INPROGRESS;
do{
irq_desc[irq].status amp;= ~IRQ_PENDING;
spin_unlock(amp;(irq_desc[irq].lock));
handle_IRQ_event(irq,regs,irq_desc[irq].action);
spin_lock(amp;(irq_desc[irq].lock));
}while (irq_desc[irq].status amp; IRQ_PENDING);
irq_desc[irq].status amp;= ~IRQ_INPROGRESS;
}
irq_desc[irq].handler->end(irq);
spin_unlock(amp;(irq_desc[irq].lock));
Мои вопросы заключаются в следующем:
-
Как работает присвоение .status ? В книге говорится, что это набор флагов. Я понимаю, что флаги являются переменными в верхнем регистре, но как к ним получить доступ в этом сценарии? Разве это не должно быть .status.IRQ_SOMETHING или что-то в этом роде?
-
Что означает единственное «amp;» в условии выражения if?
Комментарии:
1. Разве этот вопрос не просто задает вопрос «что такое операторы в C»?
2. Прочитайте это руководство по битовым манипуляциям в C или выполните поиск в Google по этой теме.
Ответ №1:
Я собираюсь ответить в обратном порядке.
amp;
Это оператор «побитовое И»; точно так |
же, как и оператор «побитовое ИЛИ». Учитывая целочисленную переменную x
, выражение:
x |= (1U << n);
Устанавливает бит n
x
в 1
значение . Наоборот:
x amp;= ~(1U << n);
Очищает бит n
x
, устанавливая его 0
равным .
Получив представление об этом операторе, вы можете увидеть, как .status
работает поле — это целочисленное поле, и различные флаги включаются и выключаются с помощью упомянутых выше операторов. Флаги проверяются с помощью amp;
оператора:
irq_desc[irq].status amp; (IRQ_DISABLED | IRQ_INPROGRESS)
Выдает истинный результат, когда IRQ_DISABLED
IRQ_INPROGRESS
в поле установлен любой из битов или .status
.