Первое правило программирования встраиваемых систем:
Никогда, никогда, никогда никогда , не делайте никаких работ с ISR.
ISR работают в действительно странных режимах процессора, и вы не можете получить доступ к службам операционной системы из них. Вы, конечно, не можете делать ничего, что блокирует их (например, доступ к диску). Единственная вещь, которую большинство ОС разрешают вам делать, это публиковать события и выпускать семафоры.
Обычный способ структурировать такую проблему - это создать обычную задачу в пользовательском пространстве, которая ожидает семафор. Когда прерывание приходит в ISR, он освобождает семафор и завершает работу; задача станет работоспособной, а затем станет просто кодом пользовательского пространства.
isr()
{
clear_interrupt_condition(); // to avoid the interrupt being retriggered
post(semaphore);
}
task()
{
for (;;)
{
wait(semaphore);
sync();
}
}
В зависимости от ОС у вас может быть конкретная помощь для выполнения подобных действий. Я использовал операционные системы, которые сделали все вышеперечисленное автоматически, если вы об этом попросили. Или они позволили бы вам структурировать его как механизм событий, где ISR будет отправлять сообщение в очередь, и работа будет выполняться из обработчика событий.
Между прочим, sync()
не (или, по крайней мере, не должен) просто помечать страницы как грязные; Posix указывает, что он не должен возвращаться до тех пор, пока данные не будут сброшены на диск (поскольку ядро может).