передача аргументов в обработчике прерываний - PullRequest
2 голосов
/ 07 декабря 2010

учтите, что мы пишем прошивку для базового MCU, т.е. без ОС.Мне сказали, что невозможно (незаконно?) Передавать аргументы в функцию обработки прерывания?

Я не могу точно понять, почему это так?Что с этим не так?

PS.это можно сделать в некоторых ОСРВ, встроенном Linux и т. д., или это в корне неправильно?

Ответы [ 6 ]

5 голосов
/ 07 декабря 2010

Прерывание. сделать это ... прервать. Представьте себе дверной звонок в вашем доме, который прерывает вас в любое случайное время дня или ночи. Можно ли ожидать, что в любой момент в вашей руке будут все нужные предметы для любого конкретного прерывания, которое может произойти. Вы должны быть в состоянии приготовить ужин, принять душ, сложить белье, но только ДО звонка в дверной звонок у вас должны быть точно правильные предметы в обеих руках, в зависимости от того, кто звонит в звонок, без какого-либо способа узнать, что они есть или находятся. Приходите или собираетесь позвонить в звонок. Не совсем возможно. То же самое здесь, прерывания приходят в любое конкретное время, для большинства процессоров сразу после выполняемой в данный момент инструкции вызывается обработчик прерываний, что означает, что каждая отдельная инструкция должна будет пытаться выполнить приложение переднего плана, сохраняя все параметры для прерывания. обработчик, и сделайте все это за один раз.

Теперь то, что возможно, это с операционной системой, или rtos, или назовите это как хотите, каким-то слоем. Чтобы иметь реальный обработчик прерываний, который ничего не знает и должен это выяснить, как только он выяснит, что именно прерывание собирается для сбора информации, а затем вызывает высокоуровневый обработчик прерываний, который передает параметры. Конечно, возможно, и большинство / многие операционные системы делают это таким образом.

4 голосов
/ 07 декабря 2010

Никакие параметры не могут быть явно переданы обработчику прерываний, потому что он предназначен для вызова аппаратным обеспечением.Каждая архитектура налагает определенный кадр стека при его вызове, обычно включая сохраненное состояние ЦП.

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

3 голосов
/ 07 декабря 2010

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

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

Например, в процессорах ARM ищите «SWI» или «SVC», в зависимости от вашей архитектуры. Я полагаю, что с помощью инструкции SWI младшие 8 бит не являются частью кода операции - вы можете заполнить все, что захотите, и передать значение от 0 до 255 (память здесь немного нечеткая).

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

3 голосов
/ 07 декабря 2010

Обработчик прерываний вызывается оборудованием. Он «передается» какими бы «аргументами» аппаратные средства не проходили.

Это все, что есть.

0 голосов
/ 04 июня 2011

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

например:

volatile enum
{
    DO_NOTHING,
    DO_A,
    DO_B,
    DO_C

} isr_action ;

__interrupt (SOME_IRQ) myISR()
{
    switch isr_action
    {
        case DO_A :
        {
            // A
        }
        break ;

        case DO_B :
        {
            // B
        }
        break ;

        case DO_C :
        {
            // C
        }
        break ;
    }
}

int main()
{
    // Make ISR do A on next SOME_IRQ
    isr_action = DO_A ;

    for(;;)
    {
        // wait for interrupt
    }
}
0 голосов
/ 04 июня 2011

когда вы устанавливаете обработчик прерываний с помощью вызова ниже, похоже, что обработчик прерываний принимает некоторые аргументы и возвращает irqreturn_t. Разве это не тот же обработчик прерываний, о котором говорит OP?

int request_irq(unsigned int irq,
                irqreturn_t (*handler)(int, void *, struct pt_regs *),
                unsigned long flags, 
                const char *dev_name,
                void *dev_id);
...