Jump to content

    

свой драйвер АЦП

в /sys драйвер появится усилиями операционной системы. Никаких усилий прилагать к этому не надо.

 

Маленький ликбез.

Драйвер в ОС Линукс.

 

Драйверы в Линуксе построены на "дереве". Ветки называются шинами (bus). Причем поначалу они соответствовали физическим шинам, а потом осталось только название. Название зачастую вносит путаницу в понимание вопроса. Запомнить нужно одно шина в Линуксе это просто название и ничего больше.

список шин вы можете посмотреть в /sys/bus:

acpi i2c mdio_bus mmc pci pci_express platform pnp scsi sdio serio spi usb virtio

 

Шина определяет тип драйвера и соответствующие типу методы. например метод найти соответствие (match). Вообще-то все рассказы про драйверы надо начинать с того, что создаются две субстанции драйвер и устройство. Осутствие одной из них не даст нужного результата. В каждой из них есть поле идентификации. Так вот поле идентификации в драйвере и устройстве должны совпадать. Какя идентификация используется и как определить если поля совпадают зависит от шины в PCI или USB это vendor_id:product_id. Для шины platform это поле имени (name). К шине platform принадлежат все устройства, которые нельзя отнести к другим шинам. АЦП принадлежит к шине platform.

 

При создании устройства оно регистрируется в шине к которой и принадлежит. Драйвер может быть создан как модуль и при загрузке модуля он тоже регистрируется в шине.

Шина имеет два списка один для драйверов, другой для устройств. При загрузке модуля, регистрация его вызовет просмотр всего списка устройств в шине. match метод шины проверит идентификационного поле устройств и только в случае соответствия поля драйвера полю устройства драйвер будет подключен (вызовется метод probe). Все необходимые псевдофайлы появятся в sys.

 

Вместо вышеизложенного метода можно сделать модуль и работать через procfs, однако это неправильно.

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

Если есть вопросы по теме -- постараюсь помочь найти ответ. К сожалению сам не все знаю. Только то с чем приходилось работать.

 

 

Вот лучшаее руководство из тех что я знаю по написанию модулей:

http://www.tldp.org/LDP/lkmpg/2.6/lkmpg.pdf

Edited by Tarbal

Share this post


Link to post
Share on other sites
в /sys драйвер появится усилиями операционной системы. Никаких усилий прилагать к этому не надо.

 

Маленький ликбез.

Драйвер в ОС Линукс.

 

Драйверы в Линуксе построены на "дереве". Ветки называются шинами (bus). Причем поначалу они соответствовали физическим шинам, а потом осталось только название. Название зачастую вносит путаницу в понимание вопроса. Запомнить нужно одно шина в Линуксе это просто название и ничего больше.

список шин вы можете посмотреть в /sys/bus:

acpi i2c mdio_bus mmc pci pci_express platform pnp scsi sdio serio spi usb virtio

 

Шина определяет тип драйвера и соответствующие типу методы. например метод найти соответствие (match). Вообще-то все рассказы про драйверы надо начинать с того, что создаются две субстанции драйвер и устройство. Осутствие одной из них не даст нужного результата. В каждой из них есть поле идентификации. Так вот поле идентификации в драйвере и устройстве должны совпадать. Какя идентификация используется и как определить если поля совпадают зависит от шины в PCI или USB это vendor_id:product_id. Для шины platform это поле имени (name). К шине platform принадлежат все устройства, которые нельзя отнести к другим шинам. АЦП принадлежит к шине platform.

 

При создании устройства оно регистрируется в шине к которой и принадлежит. Драйвер может быть создан как модуль и при загрузке модуля он тоже регистрируется в шине.

Шина имеет два списка один для драйверов, другой для устройств. При загрузке модуля, регистрация его вызовет просмотр всего списка устройств в шине. match метод шины проверит идентификационного поле устройств и только в случае соответствия поля драйвера полю устройства драйвер будет подключен (вызовется метод probe). Все необходимые псевдофайлы появятся в sys.

 

Вместо вышеизложенного метода можно сделать модуль и работать через procfs, однако это неправильно.

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

Если есть вопросы по теме -- постараюсь помочь найти ответ. К сожалению сам не все знаю. Только то с чем приходилось работать.

 

 

Вот лучшаее руководство из тех что я знаю по написанию модулей:

http://www.tldp.org/LDP/lkmpg/2.6/lkmpg.pdf

 

интересно, а не проще ли написать модуль и просто создать файл устройства символьного в /dev

 

и работать себе приспокойно через файл в /dev/my_device

Зачем мудрить с шинами и файловыми системами драйверов. Разве что как дань моде...

 

может быть я не прав.

Share this post


Link to post
Share on other sites
интересно, а не проще ли написать модуль и просто создать файл устройства символьного в /dev

 

и работать себе приспокойно через файл в /dev/my_device

Зачем мудрить с шинами и файловыми системами драйверов. Разве что как дань моде...

 

может быть я не прав.

 

Я рассказал как правильно работать с драйвером в Линуксе. И вопрос был о том как получить записи о драйвере в sysfs. К тому же в /dev драйвер pipe появится сам если все правильно делать.

Проблема с вашим подходом в том, что это устаревшая практика. Сегодня устройства в /dev появляются усилиями системы udev.

Edited by Tarbal

Share this post


Link to post
Share on other sites

Ну а кроме устарелости моей практики, что можно сказать о новой? Она просто систематизирует устройства? или есть какие-то неоспоримые плюсы?

Share this post


Link to post
Share on other sites
Ну а кроме устарелости моей практики, что можно сказать о новой? Она просто систематизирует устройства? или есть какие-то неоспоримые плюсы?

 

Если драйвер написан правильно и есть необходимость, чтобы устройство было доступно через /dev, то оно там появится посредством стандартного механизма, а не будет пальцем сделано по старинке.

Дело в том, что от создания pipes в /dev при помощи mknod как это делалось раньше возникает масса проблем от системы к системе. Какие надо создавать драйвер pipes, а какие не нужны за отсутствием драйвера зачастую не так очевидно и создать скрипты, которые будут создавать pipes в /dev без ошибок практически невозможно. Поэтому была разработана другая система udev.

Но разумеется будет работать если сделать нестандартно, но я не вижу этому объяснения кроме того, что лень разбираться как сделать правильно. Мол и так сойдет. Разумеется сойдет, однако кто-то еще сделает нестандартно что-нибудь, потом кто-то еще и в какой-то момент получится что-то несуразное, к чему и подойти будет страшно.

Мне приходилось работать в больших проектах, где много программистов пишут код. Так в стандартном подходе не всегда все очевидно, а как попадется умелец, который делает не так как надо, а так как сумеет, то очень трудно становится жить.

В общем это вопрос культуры. делать как положено или как получится.

 

Вот например при загрузке этого драйвера создастся четыре pipes устройств:

/dev/ttyHS0

/dev/ttyHS1

/dev/ttyHS2

/dev/ttyHS3

http://lxr.free-electrons.com/source/drivers/net/usb/hso.c

На самом деле внутри создано четыре устройства с разными минор значениями.

 

Таинство происходит при регистрации устройств и драйвера. Поэтому обратите внимание на функции содержащие слово register

 

Edited by Tarbal

Share this post


Link to post
Share on other sites

В новой модели драйверов тоже есть свои неудобства. Например, можно взять стандартный UART 16550. Это довольно распространенный контроллер, для которого существует много вариантов сопряжения с основным процессором: через ISA, PCI, наконец в современных системах на кристалле это вариант platform_device. Мне вот пришлось делать подобное для "новой" шины VLYNQ. Так вот проблема в том, что программно интерфейс для всех реализаций самого 16550 одинаковый, но приходится писать разные драйверы и регистрировать их в разных шинах. Получается вместо повторного использования кода его дублирование.

Share this post


Link to post
Share on other sites
В новой модели драйверов тоже есть свои неудобства. Например, можно взять стандартный UART 16550. Это довольно распространенный контроллер, для которого существует много вариантов сопряжения с основным процессором: через ISA, PCI, наконец в современных системах на кристалле это вариант platform_device. Мне вот пришлось делать подобное для "новой" шины VLYNQ. Так вот проблема в том, что программно интерфейс для всех реализаций самого 16550 одинаковый, но приходится писать разные драйверы и регистрировать их в разных шинах. Получается вместо повторного использования кода его дублирование.

Это не относится к новой или старой модели. Просто драйверы принадлежат шинам.

Новое это как делать pipes в /dev. При помощи скрипта или система сама сделает посредством udev.

Share this post


Link to post
Share on other sites
В новой модели драйверов тоже есть свои неудобства. Например, можно взять стандартный UART 16550. Это довольно распространенный контроллер, для которого существует много вариантов сопряжения с основным процессором: через ISA, PCI, наконец в современных системах на кристалле это вариант platform_device. Мне вот пришлось делать подобное для "новой" шины VLYNQ. Так вот проблема в том, что программно интерфейс для всех реализаций самого 16550 одинаковый, но приходится писать разные драйверы и регистрировать их в разных шинах. Получается вместо повторного использования кода его дублирование.

А вот в V4L эта проблема решена

Share this post


Link to post
Share on other sites
Это не относится к новой или старой модели. Просто драйверы принадлежат шинам.

Новое это как делать pipes в /dev. При помощи скрипта или система сама сделает посредством udev.

 

У меня есть несколько книг по Линукс драйверам. Не скажу за все, но три, которые самые крутые (на мой взгляд) написаны как справочники. Из них трудно получить информацию о том, чего не знаешь. Я описал вам самый сокровенный механизм установки драйвера. Будете вы создавать pipe или нет неважно. Устройство создавать обязательно надо, иначе драйвер не встанет. Ну разве что если работать через procfs. Но зачем делать через одно место? Есть вспомогательный механизм доступа, но он не основной и использовать его вместо основного неправильно. Вот как то, что я описал описывается в довольно завуалированной форме в Библии драйверов Линукса:

 

Add a Driver

A PCI driver is added to the PCI core when it calls the pci_register_driverfunction.

This function merely initializes the struct device_driver structure that is contained

within the struct pci_driver structure,as previously mentioned in the section

about adding a device. Then the PCI core calls the driver_register function in the

driver core with a pointer to the struct device_driver structure contained in the

struct pci_driver structure.

The driver_register function initializes a few locks in the struct device_driver structure,and then calls the bus_add_driver function.

This function does the following steps:

• Looks up the bus that the driver is to be associated with. If this bus is not found,

the function instantly returns.

• The driver’s sysfs directory is created based on the name of the driver and the

bus that it is associated with.

• The bus’s internal lock is grabbed,and then all devices that have been registered

with the bus are walked,and the match function is called for them,just like

when a new device is added. If that match function succeeds,then the rest of the

binding process occurs, as described in the previous section.

 

(LINUX DEVICE DRIVERS THIRD EDITION Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman)

 

Тот кто не знает о чем речь скажет, мне надо не PCI, а другой драйвер и читать это не будет, а это ключевой для всех драйверов механизм.

 

 

Для нас главное понимать драйверы так как понимают их те, кто разработал систему -- иначе все встанет криво. Вот я недавно делал аудио драйвер для чипа CX20709-Z21. Вроде драйвер, но в понимании драйвера Линуксом, в нем три драйвера. на все кроме одного в теле "драйвера" созданы устройства, но разработчик системы должен создать еще одно устройство в файле где конкретный борд настраивается. Это вообще I2C driver. Так что надо прояснить то, что мы называем драйвером и как оно соотносится с тем как это понятие соответствует понятию, использованную в системе.

Грустно, что индусы каждое слово хватают, а мы норовим каждый по своему сделать.

 

 

 

А вот в V4L эта проблема решена

 

А какие шины там используются?

Мне кажется, что только platform.

Ссылку на код можешь дать?

 

Share this post


Link to post
Share on other sites
А какие шины там используются?

Мне кажется, что только platform.

Ссылку на код можешь дать?

 

Ну я вот ковыряю em28xx драйвер, хочу добаить поддержку КWorld UB-435 ver 2.

 

USB, I2C шины пользуются, все на каллбэках.

Цеплящешь ем28 как транспорт только.

Там USB транспорт EM2874B, она по I2C болтает с EEPROM, тюнером tda18271 и демюксом

LGDT3305.

Вот, оно все создается и поднимается:

em28xx.ko, em28xx_dvb.ko, lgdt3305.ko, dvb_core.ko ..

 

Создаются под /dev/dvb/ дивайсы и еще под видео по моему,

лень в подвал ковырять к линуху, проверять.

 

Вот он весь v4l в этой директории.

http://lxr.free-electrons.com/source/drivers/media/

 

ем28хх под usb

 

Share this post


Link to post
Share on other sites
Ну я вот ковыряю em28xx драйвер, хочу добаить поддержку КWorld UB-435 ver 2.

 

USB, I2C шины пользуются, все на каллбэках.

Цеплящешь ем28 как транспорт только.

Там USB транспорт EM2874B, она по I2C болтает с EEPROM, тюнером tda18271 и демюксом

LGDT3305.

Вот, оно все создается и поднимается:

em28xx.ko, em28xx_dvb.ko, lgdt3305.ko, dvb_core.ko ..

 

Создаются под /dev/dvb/ дивайсы и еще под видео по моему,

лень в подвал ковырять к линуху, проверять.

 

Вот он весь v4l в этой директории.

http://lxr.free-electrons.com/source/drivers/media/

 

ем28хх под usb

 

What is КWorld UB-435 ver 2.?

Share this post


Link to post
Share on other sites

Драйвер АЦП, имхо, по простому - это символьное устройство: данные накапливаются в fifo, размер которого превышает максимальное время опроса. Метка времени отсчетам не нужна, потому что если частота дискретизации постоянная, время отсчета можно узнать по номеру отсчета в буфере, относительно последнего.

Если АЦП является неотьемлемой частью системы, т.е. подключен в течение всего времени работы устройства, udev не нужен, потому что при этом драйвер включается на шину при старте ядра в MACHINE_START. udev нужен только при p&p.

Регистрация устройства в /dev производится последовательностью вызовов register_chrdev, class_create, device_create при probe драйвера. После того как драйвер поднимется ядром при старте, ему доступны зарегистрированные в file_operations вызовы.

Что касается sysfs, это просто интерфейс между драйвером и юзерспейсом, можно пользовать, а можно и нет. Как альтернатива, например, вызов ioctl драйвера. Кроме того, sysfs удобен с т.з. настройки устройства, выдачи статистики драйвера и т.п. поскольку позволяет работать c устройством через echo/cat из консоли.

Что касается встраивания устройства в различные фреймфорки (v4l) это, имхо, имеет смысл в случае, когда необходимо типовое использование устройства в основном в сторонних программах, в случае специфической подсистемы видимо это избыточно.

Share this post


Link to post
Share on other sites
Если хочешь обсудить проблемы, то может откроем новый топик?

:bb-offtopic:

Да проблемы там больше не линуксовые.

Послать правильные данные хочется. Както оно все не то, что виндоус посылает.

 

:bb-offtopic:

Пример я просто привел как показатель использования разных шин

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now