Обработка IRQ из пользовательского пространства Linux

Пишу драйвер для синтезированного устройства на ПЛИС. Устройство имеет несколько IRQ и запросило их в моем драйвере:

irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
rc = request_irq(irq, &Custom_driver_handler,IRQF_TRIGGER_RISING , DRIVER_NAME, base_addr);

Моя проблема в том, что я хочу, чтобы irq_handler вызывал функцию приложения пользовательского пространства. Есть ли способ вызвать мое приложение пользовательского пространства из irq_handler драйвера в пространстве ядра??

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

заранее спасибо


person eps_712    schedule 13.03.2017    source источник
comment
Почти двадцать лет назад в ядре Linux это называлось upcall: lkml. iu.edu/hypermail/linux/kernel/9809.3/0922.html. Десять лет назад была опубликована статья lwn.net/Articles/127698 Обработка прерываний в пространстве пользователя. И теперь есть структура UIO: UIO (пользовательский ввод-вывод) unix.stackexchange.com/questions/136274/ lwn.net/Articles/232575 yurovsky.github.io/2014/10/10/linux-uio-gpio-interrupt osadl.org/fileadmin/dam/rtlws/12/Koch.pdf hep.by/gnu/kernel/uio-howto   -  person osgx    schedule 13.03.2017
comment
Насколько я понимаю, обнаружение прерывания с помощью драйвера UIO делает опрос в направлении памяти. Не так ли?? Пример использования драйвера UIO: int32_t irq_count; int fd = open(/dev/uio0, O_RDWR); void map_addr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); / Всегда читайте ровно 4 байта! */ while (read(fd, &irq_count, 4) == 4) { printf(Номер прерывания %d\n, irq_count); }   -  person eps_712    schedule 14.03.2017
comment
нет, вы понимаете, что это не полное: это чтение не вернет управление обратно пользовательской программе, если нет прерывания: lwn. net/Articles/232575 Драйвер пользовательского пространства откроет устройство (/dev/uio0). Чтение устройства возвращает значение int, которое представляет собой количество событий (количество прерываний), наблюдаемых устройством; если с момента последнего чтения не поступило ни одного прерывания, операция будет заблокирована до тех пор, пока не произойдет прерывание (хотя неблокирующая операция поддерживается и обычным способом).< /я>   -  person osgx    schedule 14.03.2017
comment
Возможный дубликат обработки прерываний Linux в пользовательском пространстве   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 15.06.2017


Ответы (1)


Существует несколько способов вызова функций пользовательского пространства из ядра, обычно называемых upcall: http://lkml.iu.edu/hypermail/linux/kernel/9809.3/0922.html; проверьте также https://lwn.net/Articles/127698/ "Обработка прерываний в пространстве пользователя" и обзор http://wiki.tldp.org/kernel_user_space_howto за 2008 г., часть "Отправка сигналов из ядра в пространство пользователя".

Чтобы упростить написание драйверов, в ядре теперь есть структура UIO: linux-userspace">https://unix.stackexchange.com/questions/136274/can-i-achieve-functionality-similar-to-interrupts-in-linux-userspace https://lwn.net/Articles/232575/ https://yurovsky.github.io/2014/10/10/linux-uio-gpio-interrupt/ https://www.osadl.org/fileadmin/dam/rtlws/12/Koch.pdf http://www.hep.by/gnu/kernel/uio-howto/

С помощью UIO вы можете заблокировать или опросить специальный файловый дескриптор для ожидания прерывания (блокировка с помощью системного вызова read(); опрос с помощью системного вызова poll): https://lwn.net/Articles/232575/

Со стороны пользовательского пространства первое устройство, обрабатываемое UIO, будет отображаться как /dev/uio0 (при обычной настройке udev). Драйвер пространства пользователя откроет устройство. Чтение устройства возвращает значение int, которое представляет собой количество событий (количество прерываний), наблюдаемых устройством; если с момента последнего чтения не поступило никаких прерываний, операция будет заблокирована до тех пор, пока не произойдет прерывание (хотя неблокирующая операция поддерживается и обычным способом). Дескриптор файла можно передать в функцию poll().

include/linux/uio_driver.h доступен в ядре Linux уже много лет, он здесь для 3. и 4. версии ядра.

person osgx    schedule 14.03.2017