2013-09-26 1 views
2

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

текущий поток последовательный драйвер FIFO -> DMA -> TTY слой -> пространство пользователя (данные в TTY слой очищается от DMA по истечении таймера)

То, что я хочу, чтобы достичь is

серийный драйвер FIFO -> DMA -> пользовательское пространство. (Я согласен с использованием таймера для отправки данных в пространство пользователя, если есть лучший способ, дайте мне знать)

Также модуль ядра, обрабатывающий serialFIFO-> DMA, не является символьным устройством. Я хотел бы полностью обходить слой tty. Каков наилучший способ достичь этого?

Любые указатели/фрагменты кода будут оценены по достоинству.

+0

Я лично начал искать драйвер для другого устройства с общими сопоставимыми требованиями, например, что-то для синхронного последовательного канала во встроенной системе (просто убедитесь, что он предназначен для обычного Linux, а не для ядра uClinux, где определенные ярлыки могут быть приняты). –

+0

Привет, Крис, спасибо за ваши комментарии, Это для встроенного linux на основе MontaVista (2.6.32). Я искал такой пример, но не нашел. Любые мысли об использовании драйвера mmap для передачи данных в пространство пользователя. Я думал о следующем пути. Драйвер скопирует данные в DMA и из DMA данные будут скопированы (memcpy) в память на основе mmap, из которой программа пользовательского пространства может считывать данные. Я также обеспокоен некоторыми проблемами с этим подходом. например, как уведомить пользовательское пространство о новых данных и избежать перезаписывания/повреждения данных DMA. – user1867459

+2

* «не является символьным устройством» * - Тогда это должно быть устройство ** block **, что не имеет смысла. * "... и передает его в DMA" * - DMA - это метод передачи данных, а не пункт назначения для копирования. Пожалуйста, объясните, что вы думаете о преимуществах обхода слоя tty. И вы понимаете, что вы сдаете, например. * tc [gs] etattr() * и друзья? Вероятно, это проблема XY. Вы пытаетесь уменьшить задержку? См. Этот [вопрос] (http://stackoverflow.com/questions/4667141/high-delay-in-rs232-communication-on-a-pxa270), который разрешен с использованием ** ASYNC_LOW_LATENCY ** – sawdust

ответ

2

В> = 3.10.5 «серийный FIFO», который вы называете, называется uart_port. Они определены в drivers/tty/serial.

Я предполагаю, что вы хотите скопировать драйвер для вашего UART в новый файл, вместо того, чтобы использовать uart_insert_char для вставки символов из UIF RX FIFO, вы хотите вставить символы в буфер, который вы может получить доступ из пользовательского пространства.

Способ сделать это, чтобы создать второй драйвер, драйвер устройства с misc класса, который имеет операции с файлами, в том числе mmap, и выделяет память ядра, mmap файл функции операция связывает водителя с памятью отображается в пространстве пользователя. Для этого написан Maxix Ripard код good example. Этот пример был написан для устройства, обработанного FIQ, но вы можете использовать только вызов программы dma_zalloc_coherent и процедуру mmap, с ее вызовом remap_pfn_range, чтобы сделать трюк, то есть связать пространство пользователя mmap с файлом устройства misc с выделенной памятью.

Вам необходимо подключить память, вы выделенная в вашем misc драйвере в буфер, который записывается в драйвере UART, используя либо глобальный пустой указатель, либо с помощью экспортируемого символа, если ваш драйвер misc является модулем , Инициализируйте указатель на известное недопустимое значение в драйвере UART и протестируйте его, чтобы убедиться, что драйвер misc назначил его, прежде чем пытаться вставить символы в адрес, на который он указывает.

Обратите внимание, что вы не можете добавить функцию mmap к драйверу UART напрямую, потому что класс драйвера UART не поддерживает работу с файлом mmap. Он поддерживает только операции, определенные в include/linux/serial_core.hstruct uart_ops.

Правды это неуклюжее решение - два драйверов устройств, но альтернатива, чтобы написать новый класс устройств, в УАППАХ устройство, которое имеет mmap операцию, и это было бы очень много работы по сравнению с указанным выше раствором хотя это было бы элегантно. Никто не сделал это на сегодняшний день, потому что, как говорит Джонатан Корбет, "...not every device lends itself to the mmap abstraction; it makes no sense, for instance, for serial ports and other stream-oriented devices", хотя это именно то, о чем вы просите.

Я реализовал это решение для режима UART для опроса, основанного на коде mxs-auart.c и примере Maxime. Это было нетривиальное усилие, но главным образом потому, что я использую обработчик FIQ для таймера опроса.Вы должны разрешить две-три недели, чтобы все заработало.

Аспект DMA вашего вопроса зависит от того, поддерживает ли UART режим передачи DMA. Если это так, то вы должны установить его с помощью серийного номера flags. Первичная плата i.MX28 поддерживает передачу DMA, но для моего приложения не было преимуществ перед простое чтение байтов непосредственно из UART RX FIFO.

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