2012-04-02 4 views
7

Я внедряю пользовательский драйвер последовательной шины для определенной платы на базе ARM (собственно, для UART-драйвера). Этот драйвер должен обеспечивать связь с определенным MCU на другом конце шины через пользовательский протокол. Драйвер не будет (и на самом деле не должен) раскрывает любую из своих функций в пользовательском пространстве, и вообще невозможно реализовать его в пользовательском пространстве (отсюда необходимость использования настраиваемого драйвера вместо использования подсистемы TTY).Реализация правильной межмодульной синхронизации в ядре Linux

Драйвер реализует протокол связи, а UART читает/записывает, и он должен экспортировать набор функций более высокого уровня своим пользователям, чтобы они могли общаться с MCU (например, read_register(), drive_gpios(), все это) , Будет только один пользователь этого модуля.

Вызывающий модуль должен будет дождаться завершения операций (вышеупомянутый read_register() и другие). В настоящее время я рассматриваю использование семафоров: пользовательский модуль вызывает функцию моего драйвера, которая инициирует перенос и ждет семафора; обработчик IRQ моего драйвера отправит запросы в MCU и прочитает ответы, а когда это будет сделано, отправьте сообщение в семафор, таким образом, пробудив вызывающий модуль. Но я не очень хорошо разбираюсь в программировании ядра, и меня озадачивает множество возможных альтернативных реализаций (очереди задач? Очереди ожидания?).

Вопрос в следующем: мой подход, основанный на семафоре, или слишком наивный? Каковы возможные альтернативы? Есть ли какие-то подводные камни, которые я могу потерять?

+3

Семафоры должны выполнять эту работу, исходя из того, что я понимаю, чтобы лучше понять внутренние интерфейсы linux, пожалуйста, обратитесь к хорошей книге «Разработка ядра линейки 1-го издания», которая доступна в виде бесплатного pdf-документа и обновлена ​​(я полагаю, я думаю, что .39 ядро). Эта книга не идет очень глубоко, но она объясняет основные принципы и показывает варианты. Получайте удовольствие от взлома. – AoeAoe

+0

Хорошая книга, спасибо! Если кому-то еще интересно, я бы также предложил получить Linux Drivers Development и Linux Kernel Module Development (обе доступны онлайн бесплатно) –

ответ

5

Традиционно IRQ обработка в Linux осуществляется в двух частях:

  1. Так называемый «верхний половина» является актуальной работой в контексте IRQ (сам обработчик прерываний). Эта часть должна выйти как можно быстрее. Поэтому он в основном проверяет источник прерываний, а затем начинает нижнюю половину.

  2. «Нижняя половина». Он может быть реализован как рабочая очередь. Именно там выполняется фактическая работа. Она работает в нормальном контексте, поэтому он может использовать блокирующие функции и т.д.

Если вы хотите ждать IRQ в вашем рабочем потоке, лучше использовать специальный объект под названием completion. Это точно создано для этой задачи.

Смежные вопросы