|
свой драйвер АЦП, два пути |
|
|
|
 |
Ответов
(1 - 61)
|
Jun 13 2013, 21:50
|
Знающий
   
Группа: Участник
Сообщений: 881
Регистрация: 21-03-10
Из: _// \\_
Пользователь №: 56 107

|
С sysfs пробовал немного, все же это не совсем файловая система, это скорее некая обертка для kernel objects. А с procfs все достаточно просто. Сначала нужно в своем модуле в методе init зарегистрировать драйвер устройства. Проще всего это сделать для platform_bus, так как для этой шины правило соответствия довольно простое - одинаковые имена у драйвера и устройства. Итого: Код static int __init my_driver_init(void) { int rc;
my_proc_dir = proc_mkdir("my_dir", 0); if (!my_proc_dir) bail_out...
rc = platform_driver_register(&my_driver); if (rc!=0) bail_out...
// тут же можно зарегистрировать и само устройство, если нет более подходящего места. // вообще говоря, LDM подразумевает, что устройство регистрируется на шине неким сканером шины // для реализации механизма plug and play, но это необязательно.
return 0; } В данном коде все довольно просто, системе зарегистрировали базовый каталог в proc и драйвер для устройства. Драйвер устройства теперь будет проверяться всякий раз, когда в системе происходят изменения на шине platform_bus. Если драйвер найдет устройство, то будет вызван метод probe драйвера, где он сможет устройство взять под свой контроль. Там же происходит инициализация рабочих структур управления устройством: выделение памяти, ремаппинг адресного пространства ввода-вывода, назначение irq, а также регистрация в procfs файлов для управления устройством из пользовательского приложения. Вот примерно так: Код static int my_driver_probe(struct platform_device *pdev) { struct resource *r_mem, *r_irq; my_device_t *ctx; int rc;
pdev_info(pdev, "starting device...\n");
r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); r_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!r_mem || !r_irq) return -EINVAL;
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM;
platform_set_drvdata(pdev, ctx); ctx->pdev = pdev;
/* check the resources */ ctx->irq = r_irq->start; ctx->mem_base = r_mem->start; ctx->mem_size = r_mem->end - r_mem->start + 1;
/* registering module base directory */ snprintf(ctx->name_base, sizeof(ctx->name_base), "%u", pdev->id); ctx->proc_base = proc_mkdir(ctx->name_base, my_proc_dir); if (!ctx->proc_base) { rc = -ENOMEM; goto fail_proc_base; }
/* registering interface to work with ADC */ ctx->proc_adc = create_proc_entry("adc_data", 0644, ctx->proc_base); if (!ctx->proc_adc) { rc = -ENOMEM; goto fail_proc_adc; } else { /* fill in the table of registers operations */ extern struct file_operations mors8_registers_fops;
ctx->proc_regs->data = ctx; ctx->proc_regs->size = 256; // размер файла АЦП, если имеет смысл ctx->proc_regs->proc_fops = &my_adc_fops; atomic_set(&ctx->open_adc, 0); }
// аналогично создаем прочие файловые интерфейсы к драйверу ...
/* now register irq handler */ rc = request_irq(ctx->irq, my_interrupt_handler, IRQF_SHARED, "my_adc", ctx); if (rc) { pdev_err(pdev, "unable to set up irq %d, error %d\n", ctx->irq, rc ); goto fail_irq; } else { /* setup interrupt enable for the device */ }
return 0;
fail_irq: fail_proc_adc: remove_proc_entry(ctx->name_base, my_proc_base); fail_proc_base: return rc; }
static int my_driver_remove(struct platform_device *pdev) { my_device_t *ctx;
ctx = platform_get_drvdata(pdev);
pdev_info(pdev, "stopping device...\n");
/* removing interrupt handler */ free_irq(ctx->irq, ctx); /* free handler */
/* removing file adc_data */ if (ctx->proc_adc) remove_proc_entry("adc_data", ctx->proc_base);
return 0; } Дальше нужно описать файловый интерфейс управления АЦП. Приведу лишь только процедуру чтения и структуру дескриптора: Код static int fops_adc_read(struct file *f, char __user *buf, size_t n, loff_t *pos) { my_device_t *ctx = (my_device_t *) f->private_data; loff_t offs = (*pos) & ~3; size_t total = 0;
if (offs >= ctx->proc_adc->size) return 0;
if (offs + n >= ctx->proc_adc->size ) n = ctx->proc_adc->size - offs;
n &= ~3;
while(n > 0) { u32 data; int rc;
rc = my_read_adc (ctx, &data); if (rc) break;
// copy data to user copy_to_user(buf, &data, 4);
// take next word buf += 4; offs += 4; total += 4; n -= 4; }
*pos = offs;
return total; }
struct file_operations my_adc_fops = { .owner = THIS_MODULE, .open = fops_adc_open, .release = fops_adc_close, .read = fops_adc_read, .write = fops_adc_write, .ioctl = fops_adc_ioctl, .llseek = fops_adc_seek, }; Собственно и все. После insmod такого драйвера в системе появится "файл" в пути /proc/my_dir/0/adc_data, который можно открыть и читать любыми средствами, доступными в линукс. Например, можно сделать dd if=/proc/my_dir/0/adc_data of=/mnt/nfs/test bs=512 count=1, и тогда можно скинуть в файлик на NFS результаты АЦП, и потом их глазками быстро посмотреть, скажем в mc или через QUI.
Сообщение отредактировал Hoodwin - Jun 14 2013, 06:58
|
|
|
|
|
Jun 18 2013, 03:57
|
Местный
  
Группа: Участник
Сообщений: 351
Регистрация: 5-04-05
Пользователь №: 3 874

|
Цитата(TigerSHARC @ Jun 13 2013, 15:29)  Вижу что устройства "по-хорошему" регистрируются в sysfs, а вот этот путь не совсем понятен. "По-хорошему" для АЦП скорее всего есть уже есть отдельная подсистема в которой надо зарегистироваться и реализовать методы и sysfs будет "из коробки". Здесь Dubov создавал несколько тем про драйвер АЦП.
|
|
|
|
|
Jun 28 2013, 13:13
|
Участник

Группа: Участник
Сообщений: 21
Регистрация: 18-05-10
Из: Ярославль
Пользователь №: 57 355

|
Как-то пользовался драйвером АЦП для at91-adc, для его 4-х каналов, для arm926-го (at91sam9m10g45ek). В этом драйвере есть и регистрация файлов в sysfs с чтением и записью для созданного misc-устройства, реализованы системные вызовы open/read/write/poll/close, используется dma. Выложил патч, добавляющий этот драйвер в ядро, на pastebin - может быть пригодится. Да, драйвер проверенный и рабочий. А так procfs - да, проще в реализации, можно работать с ней откуда угодно, не тянет за собой ничего ( например). Именно поэтому procfs в любой рабочей системе уже стала похожа на винегрет "из всего, что только в системе есть". Драйверы для spi-ных АЦП тоже имеются (например, для AD7887). Может быть даже готовый есть для нужного АЦП.
|
|
|
|
|
Jun 29 2013, 01:38
|
Частый гость
 
Группа: Свой
Сообщений: 111
Регистрация: 5-05-10
Из: Lebanon, Beirut
Пользователь №: 57 093

|
Цитата(Ya_Mike @ Jun 28 2013, 16:13)  Как-то пользовался драйвером АЦП для at91-adc, для его 4-х каналов, для arm926-го (at91sam9m10g45ek). В этом драйвере есть и регистрация файлов в sysfs с чтением и записью для созданного misc-устройства, реализованы системные вызовы open/read/write/poll/close, используется dma. Выложил патч, добавляющий этот драйвер в ядро, на pastebin - может быть пригодится. Да, драйвер проверенный и рабочий. А так procfs - да, проще в реализации, можно работать с ней откуда угодно, не тянет за собой ничего ( например). Именно поэтому procfs в любой рабочей системе уже стала похожа на винегрет "из всего, что только в системе есть". Драйверы для spi-ных АЦП тоже имеются (например, для AD7887). Может быть даже готовый есть для нужного АЦП. Мне кажется procfs/sysfs не лучшие интерфейсы для большого обьема данных или данных которые идут непрерывно и слишком быстро. Большой оверхед на открытие-закрытие и syscall вызовы. IMHO удобнее mmap с каким-нить ring buffer, которое удобно обрабатывать через readv.
|
|
|
|
|
Jul 4 2013, 13:24
|
Участник

Группа: Участник
Сообщений: 21
Регистрация: 18-05-10
Из: Ярославль
Пользователь №: 57 355

|
Цитата(denyslb @ Jun 29 2013, 05:38)  Мне кажется procfs/sysfs не лучшие интерфейсы для большого обьема данных или данных которые идут непрерывно и слишком быстро. Большой оверхед на открытие-закрытие и syscall вызовы. IMHO удобнее mmap с каким-нить ring buffer, которое удобно обрабатывать через readv. Открытие-закрытие можно делать только один раз - расходы на них сокращаются в ноль по сравнению с временем работы. В приведенном по ссылке драйвере - имеется двойная буферизация с поочередным дма-заполнением каждого, а скорость считывания такова, что системный вызов будет "срабатывать" раз в несколько десятков мс. Накладные расходы - нивелируются. Ко всему - с mmap, наверное, будет не очень удобно реализовывать блокирующее чтение, которое есть в этом драйвере. К тому же - при больших частотах дискретизации возможны потери данных, если читать малыми порциями через опрос регистров. Выигрыш mmap кажется сомнительным. В добавок, в драйвер можно удобно вставить предобработку данных с АЦП без пересборки приложения (например, скользящее среднее, медиана). Может я не совсем уловил высказанную идею и её преимущества. Можно описать подробней, какая связка mmap-а, ring-buffer-a и readv имеется ввиду? В целом, конечно, приличней работать через какое-нибудь символьное устройство в devfs, но не уверен, что по скорости работа через него будет отличаться, например, от sysfs (те же copy_{to,from}_user(..)).
|
|
|
|
|
Jul 12 2013, 10:47
|

Участник

Группа: Участник
Сообщений: 52
Регистрация: 30-11-11
Пользователь №: 68 593

|
Цитата(Hoodwin @ Jun 14 2013, 01:50)  Собственно и все. После insmod такого драйвера в системе появится "файл" в пути /proc/my_dir/0/adc_data, который можно открыть и читать любыми средствами, доступными в линукс. Например, можно сделать dd if=/proc/my_dir/0/adc_data of=/mnt/nfs/test bs=512 count=1, и тогда можно скинуть в файлик на NFS результаты АЦП, и потом их глазками быстро посмотреть, скажем в mc или через QUI. Тоже задумался над написанием драйвера , который будет принимать поток с 8 каналов АЦП по msasp в режиме tdm на пладе Beaglebone. Вроде бы понятно как создать устройство в /proc, создать файловый интерфейс для записи чтения. Предполагаю, что из буфера DMA буду пихать данные в большой промежуточный циклический буфер, а при вызове read() брать сколько есть, но не более чем указанное количество значений из буфера. Остался один не понятный момент, как внутри драйвера организовать функцию, в которой постоянно будет проверяться сколько в буфере DMA есть данных . Как в драйвере можно организовать функцию, в которую гарантированно буду попадать не реже ~10 ms? Какие есть стандартные средства для этого? И ещё вопрос. Возможен ли такой вариант: в драйвере заряжаю DMA на определённую область памяти и уже из USER_SPACE получаю доступ к ней. А информацию по поводу по какому адресу делать mmap зачитаваю из файла устройства в /proc. Так же из файлов читаю текущее положение кольцевых указателей. Заранее спасибо за ответы.
Сообщение отредактировал Муравей - Jul 12 2013, 11:27
|
|
|
|
|
Jul 26 2013, 09:22
|
Частый гость
 
Группа: Свой
Сообщений: 111
Регистрация: 5-05-10
Из: Lebanon, Beirut
Пользователь №: 57 093

|
Цитата(Ya_Mike @ Jul 4 2013, 16:24)  Открытие-закрытие можно делать только один раз - расходы на них сокращаются в ноль по сравнению с временем работы. В приведенном по ссылке драйвере - имеется двойная буферизация с поочередным дма-заполнением каждого, а скорость считывания такова, что системный вызов будет "срабатывать" раз в несколько десятков мс. Накладные расходы - нивелируются. Ко всему - с mmap, наверное, будет не очень удобно реализовывать блокирующее чтение, которое есть в этом драйвере. К тому же - при больших частотах дискретизации возможны потери данных, если читать малыми порциями через опрос регистров. Выигрыш mmap кажется сомнительным. В добавок, в драйвер можно удобно вставить предобработку данных с АЦП без пересборки приложения (например, скользящее среднее, медиана). Может я не совсем уловил высказанную идею и её преимущества. Можно описать подробней, какая связка mmap-а, ring-buffer-a и readv имеется ввиду? В целом, конечно, приличней работать через какое-нибудь символьное устройство в devfs, но не уверен, что по скорости работа через него будет отличаться, например, от sysfs (те же copy_{to,from}_user(..)). Если читать единственное значение, то да, sysfs/procfs может и подойдет. А если скажем ADC с определенной частотой дискретизации заполняет буфер и программе иногда приходится вычитывать несколько значений сразу? Тогда скорее всего это будет много структур { time, value }, возможно метка состояния структуры/флаг (кому сейчас принадлежит, ядру или userspace процессу) и т.п. Принцип работы приблизительно описан в V4L, или сложнее - в PF_RING. Почитайте тут: http://www.linuxjournal.com/article/6345 , относительно кратко расписано. Хотя в чем-то с вами согласен, можно сделать и через read, но мне кажется накладных расходов больше (если судить по статье).
|
|
|
|
|
Aug 6 2013, 02:47
|
Гуру
     
Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493

|
Цитата(Муравей @ Jul 12 2013, 14:47)  Тоже задумался над написанием драйвера , который будет принимать поток с 8 каналов АЦП по msasp в режиме tdm на пладе Beaglebone. Вроде бы понятно как создать устройство в /proc, создать файловый интерфейс для записи чтения. Предполагаю, что из буфера DMA буду пихать данные в большой промежуточный циклический буфер, а при вызове read() брать сколько есть, но не более чем указанное количество значений из буфера. Остался один не понятный момент, как внутри драйвера организовать функцию, в которой постоянно будет проверяться сколько в буфере DMA есть данных . Как в драйвере можно организовать функцию, в которую гарантированно буду попадать не реже ~10 ms? Какие есть стандартные средства для этого?
И ещё вопрос. Возможен ли такой вариант: в драйвере заряжаю DMA на определённую область памяти и уже из USER_SPACE получаю доступ к ней. А информацию по поводу по какому адресу делать mmap зачитаваю из файла устройства в /proc. Так же из файлов читаю текущее положение кольцевых указателей.
Заранее спасибо за ответы. Господа, вам охота время терять, или просто хотите убедиться, что Линукс не дураками писан. V4L - есть там все это. И не надо циклических буферов . " в драйвере заряжаю DMA на определённую область памяти и уже из USER_SPACE получаю доступ к ней. " - это называется io_user_ptr , как-то так, большинство того, с чем я имел дело - с этим не работают. Чем вам mmap не по душе ? Накладных - ноль. ноль. Память выделять должен драйвер, имхо. Память для DMA вызывается по dma_alloc_coherent, непрерывным цельным куском, но это функция ядра. Из пользовательского режима если подсовывать свою память - честно скажу не пробовал, мне и рабочие драйвера не попадались такие, обычно все проще, просишь драйвер создать буфер, просишь заполнить, просишь отдать. Достаточно прозрачно. А вот про user ptr обычно вижу только // TODO Хотя возможно я вас не так понял, заряжать драйвер на память вы собрались именно внутри драйвера. Тогда зачем вам /proc вообще ? Короче как-то сложно выходит, через ioctl прекрасно работает. Я несколько сумбурно говорю, но и ваша идея тоже сумбурна. Да и непонятно зачем нужна. Рекомендованной статье 10 лет, потрасируйте через GDB традиционный вариант mmap - там на деле zero copy и выходит
|
|
|
|
|
Aug 22 2013, 15:14
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
в /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
Сообщение отредактировал Tarbal - Aug 22 2013, 15:17
|
|
|
|
|
Aug 26 2013, 13:38
|
Местный
  
Группа: Участник
Сообщений: 408
Регистрация: 28-05-12
Пользователь №: 72 052

|
Цитата(Tarbal @ Aug 22 2013, 19:14)  в /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 Зачем мудрить с шинами и файловыми системами драйверов. Разве что как дань моде... может быть я не прав.
|
|
|
|
|
Aug 27 2013, 01:25
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
Цитата(Dubov @ Aug 26 2013, 19:16)  Ну а кроме устарелости моей практики, что можно сказать о новой? Она просто систематизирует устройства? или есть какие-то неоспоримые плюсы? Если драйвер написан правильно и есть необходимость, чтобы устройство было доступно через /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
Сообщение отредактировал Tarbal - Aug 27 2013, 01:46
|
|
|
|
|
Aug 28 2013, 13:08
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
Цитата(Tarbal @ Aug 28 2013, 02:50)  Это не относится к новой или старой модели. Просто драйверы принадлежат шинам. Новое это как делать 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. Так что надо прояснить то, что мы называем драйвером и как оно соотносится с тем как это понятие соответствует понятию, использованную в системе. Грустно, что индусы каждое слово хватают, а мы норовим каждый по своему сделать. Цитата(A. Fig Lee @ Aug 28 2013, 06:28)  А вот в V4L эта проблема решена А какие шины там используются? Мне кажется, что только platform. Ссылку на код можешь дать?
|
|
|
|
|
Aug 29 2013, 00:26
|

Знающий
   
Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467

|
Цитата(Tarbal @ Aug 28 2013, 09:08)  А какие шины там используются? Мне кажется, что только 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
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
Aug 29 2013, 19:57
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
Цитата(A. Fig Lee @ Aug 29 2013, 04:26)  Ну я вот ковыряю 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.?
|
|
|
|
|
Aug 30 2013, 15:33
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
Драйвер АЦП, имхо, по простому - это символьное устройство: данные накапливаются в fifo, размер которого превышает максимальное время опроса. Метка времени отсчетам не нужна, потому что если частота дискретизации постоянная, время отсчета можно узнать по номеру отсчета в буфере, относительно последнего. Если АЦП является неотьемлемой частью системы, т.е. подключен в течение всего времени работы устройства, udev не нужен, потому что при этом драйвер включается на шину при старте ядра в MACHINE_START. udev нужен только при p&p. Регистрация устройства в /dev производится последовательностью вызовов register_chrdev, class_create, device_create при probe драйвера. После того как драйвер поднимется ядром при старте, ему доступны зарегистрированные в file_operations вызовы. Что касается sysfs, это просто интерфейс между драйвером и юзерспейсом, можно пользовать, а можно и нет. Как альтернатива, например, вызов ioctl драйвера. Кроме того, sysfs удобен с т.з. настройки устройства, выдачи статистики драйвера и т.п. поскольку позволяет работать c устройством через echo/cat из консоли. Что касается встраивания устройства в различные фреймфорки (v4l) это, имхо, имеет смысл в случае, когда необходимо типовое использование устройства в основном в сторонних программах, в случае специфической подсистемы видимо это избыточно.
|
|
|
|
|
Aug 30 2013, 16:04
|

Знающий
   
Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467

|
Цитата(Tarbal @ Aug 30 2013, 07:21)  Если хочешь обсудить проблемы, то может откроем новый топик? Да проблемы там больше не линуксовые. Послать правильные данные хочется. Както оно все не то, что виндоус посылает. Пример я просто привел как показатель использования разных шин
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
Aug 30 2013, 16:21
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
Цитата(psL @ Aug 30 2013, 19:33)  Драйвер АЦП, имхо, по простому - это символьное устройство: данные накапливаются в fifo, размер которого превышает максимальное время опроса. Метка времени отсчетам не нужна, потому что если частота дискретизации постоянная, время отсчета можно узнать по номеру отсчета в буфере, относительно последнего. Если АЦП является неотьемлемой частью системы, т.е. подключен в течение всего времени работы устройства, udev не нужен, потому что при этом драйвер включается на шину при старте ядра в MACHINE_START. udev нужен только при p&p. Регистрация устройства в /dev производится последовательностью вызовов register_chrdev, class_create, device_create при probe драйвера. После того как драйвер поднимется ядром при старте, ему доступны зарегистрированные в file_operations вызовы. Что касается sysfs, это просто интерфейс между драйвером и юзерспейсом, можно пользовать, а можно и нет. Как альтернатива, например, вызов ioctl драйвера. Кроме того, sysfs удобен с т.з. настройки устройства, выдачи статистики драйвера и т.п. поскольку позволяет работать c устройством через echo/cat из консоли. Что касается встраивания устройства в различные фреймфорки (v4l) это, имхо, имеет смысл в случае, когда необходимо типовое использование устройства в основном в сторонних программах, в случае специфической подсистемы видимо это избыточно. Нет желания спорить по всем пунктам, по которым не согласен. Лишь о главном. V4L это video for Linux. Я не вижу никакого смысла делать драйвер АЦП в видео системе. Кстати уже давно используется новая версия V4L2. То что вы называете fifo, используется не только в видео фор линукс, но и в сетевых драйверах, USB драйверах, фрейм буферах и т.д.. Это называется ПДП (DMA). Зачем надо усложнять драйвер ненужными наворотами из видео системы, когда можно написать простой с использованием ПДП? посмотите что такое udev и как он создает пайпы для всех устройств, а не только PnP http://www.iredale.net/p/by-title/introduc...tion-latest.pdf
|
|
|
|
|
Aug 30 2013, 20:09
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
Цитата(Tarbal @ Aug 30 2013, 20:21)  V4L это video for Linux. Я не вижу никакого смысла делать драйвер АЦП в видео системе. Кстати уже давно используется новая версия V4L2. То что вы называете fifo, используется не только в видео фор линукс, но и в сетевых драйверах, USB драйверах, фрейм буферах и т.д.. Это называется ПДП (DMA). Зачем надо усложнять драйвер ненужными наворотами из видео системы, когда можно написать простой с использованием ПДП? посмотите что такое udev и как он создает пайпы для всех устройств, а не только PnP http://www.iredale.net/p/by-title/introduc...tion-latest.pdfНе нужно путать мягкое с мокрым. FIFO - это способ организации памяти по принципу первый вошел, первый вышел, а ПДП - механизм обмена периферии с памятью на прямую, без участия процессора. При том, что fifo можно заполнять хоть по полингу, а ПДП м.б. к одному адресу памяти  udev для встраиваемых систем вообще избыточен, поскольку состав подключаемого оборудования известен заранее и находится уже на борту. Обычно используют mdev из bb Хотя может вы про adc на usb или pci шине. V4L (про 2 в курсе  ) приведен как пример (было в предыдущих постах), по поводу АЦП в V4L - во-первых, видеосигналы и АЦП бывают разные, во-вторых, аудиопоток в видео никто не отменял
|
|
|
|
|
Aug 30 2013, 22:08
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
Цитата(A. Fig Lee @ Aug 30 2013, 20:04)  Да проблемы там больше не линуксовые. Послать правильные данные хочется. Както оно все не то, что виндоус посылает. Пример я просто привел как показатель использования разных шин Это не противоречит тому, что я сказал. Там несколько драйверов и несколько устройств создаётся. В разных шинах. Каждому драйверу создается хотя бы одно устройство. На I2C один драйвер, на USB другой, на Video третий и не удивлюсь если это не предел.
|
|
|
|
|
Aug 31 2013, 17:11
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
Цитата(psL @ Aug 31 2013, 00:09)  по поводу АЦП в V4L - во-первых, видеосигналы и АЦП бывают разные, во-вторых, аудиопоток в видео никто не отменял Вы о чем? Вопрос стоит как проще сделать драйвер для АЦП, а не о способах использования АЦП в муьтимедиа даже если для вас это наиболее удобный способ подключить АЦП. Цитата(psL @ Aug 31 2013, 00:09)  Не нужно путать мягкое с мокрым. FIFO - это способ организации памяти по принципу первый вошел, первый вышел, а ПДП - механизм обмена периферии с памятью на прямую, без участия процессора. При том, что fifo можно заполнять хоть по полингу, а ПДП м.б. к одному адресу памятиwink.gif ПДП может - скопировать блок памяти в другое место - пересылать значение из фиксированного адреса в инкрементируемый поинтер (назовем так для краткости изложения) - пересылать из инкрементируемого адреса в фиксированный. Я натянул второй метод на фифо, хотя он гораздо удобнее -- он сразу доставит данные. Но если вы настаиваете, то имея ПДП фифо не нужен как страшный сон. Цитата(psL @ Aug 31 2013, 00:09)  udev для встраиваемых систем вообще избыточен, поскольку состав подключаемого оборудования известен заранее и находится уже на борту. Обычно используют mdev из bb Это уже придирка. Я имел ввиду udev как концепцию в противовес методу делать пайпы вручную.
Сообщение отредактировал Tarbal - Aug 31 2013, 17:15
|
|
|
|
|
Aug 31 2013, 17:37
|
Знающий
   
Группа: Участник
Сообщений: 783
Регистрация: 22-11-08
Пользователь №: 41 858

|
Цитата Но если вы настаиваете, то имея ПДП фифо не нужен как страшный сон. Скоростная периферия работает не с контроллером DMA а сама является bus master и фифо там нужен чтобы смягчить нагрузку на шину. Периферии попроще - тоже самое, только чтобы упростить жизнь контроллеру DMA у которого каналов до и более. Без фифо любит делать атмел - кривейшая периферия наверно из того с чем встречался. Хотя я вас возможно неправильно понял (тут вы сами виноваты) и имеется ввиду фифо в общей памяти а не локальная память периферийных устройств, так без буферов для DMA которые в очередь как фифо выстраиваются ни одна нормальная ОС не обходится.
Сообщение отредактировал sasamy - Aug 31 2013, 18:07
|
|
|
|
|
Aug 31 2013, 17:57
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
Цитата(sasamy @ Aug 31 2013, 21:37)  Скоростная периферия работает не с контроллером DMA а сама является bus master и фифо там нужен чтобы смягчить нагрузку на шину. Периферии попроще - тоже самое, только чтобы упростить жизнь контроллеру DMA у которого каналов до и более. Без фифо любит делать атмел - кривейшая периферия наверно из того с чем встречался. Я с этим не спорю. Разве вопрос стоит о том как устроена скоростная периферия? Давайте не будем уходить в теорию в то время, когда человеку надо решить его конкретную проблему. Был вопрос как проще сделать драйвер для АЦП и каким способом сделать это правильно, чтобы /sys был заполнен необходимыми псевфо файлами. Я предложил как это сделать. Что имеется ввиду под фифо в контексте данной задачи я смутно себе представляю. Надо поставить какой-то дополнительный чип? Или как? Исполнить его программно в интеррапте? В то же время процессор имеет немерянное число каналов ПДП, один из которых прекрасно справится с работой. В то же время использование мультимедиа драйверов в качестве прототипа я считаю не лучшим подходом.
|
|
|
|
|
Aug 31 2013, 18:17
|
Знающий
   
Группа: Участник
Сообщений: 783
Регистрация: 22-11-08
Пользователь №: 41 858

|
Цитата(Tarbal @ Aug 31 2013, 21:57)  Был вопрос как проще сделать драйвер для АЦП и каким способом сделать это правильно Пример V4l2 - это как можно не напрягая мозг использовать фреймворк у которого есть готовые средства для управления памятью ( буфер DMA + метаинформация) буферы отображаются в памяти пользовательского процесса и позволяют избежать лишнего копирования за счет CPU которе неизбежно будет при использовании read/write (copy_to_user()/copy_from_user() ) Цитата Что имеется ввиду под фифо в контексте данной задачи Кольцевая очередь (циклический двусвязный список) из этих буферов (вернее их там две). Кто и по какому интерфейсу заполняет буферы - вообще не важно, хоть за счет ЦПУ. Цитата В то же время использование мультимедиа драйверов в качестве прототипа я считаю не лучшим подходом. Естественно, есть готовые фреймворки, но ТС непременно хочет _свой_, он так и написал.
Сообщение отредактировал sasamy - Aug 31 2013, 19:08
|
|
|
|
|
Aug 31 2013, 19:51
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
Цитата(sasamy @ Aug 31 2013, 22:17)  Пример V4l2 - это как можно не напрягая мозг использовать фреймворк у которого есть готовые средства для управления памятью ( буфер DMA + метаинформация) буферы отображаются в памяти пользовательского процесса и позволяют избежать лишнего копирования за счет CPU которе неизбежно будет при использовании read/write (copy_to_user()/copy_from_user() ) Кому как. Мне так легче сделать как требуется. Я так привык. Цитата(sasamy @ Aug 31 2013, 22:17)  Кольцевая очередь (циклический двусвязный список) из этих буферов (вернее их там две). Кто и по какому интерфейсу заполняет буферы - вообще не важно, хоть за счет ЦПУ. Как закоренелый реалтаймщик я не принимаю решений за счет ЦПУ, когда есть хардвер, которуй не только для этой задачи предназначен, но и сделает работу эффективнее. Я не спорю насчет мультимедиа, потому как не делал таких драйверовm, а код ковырять просто для поиска доказательств лень, однако в драйвере фрейм буфера используется ПДП. Подозреваю, что если копнуть, то и в мултимедиа фифо буферами оперирует, которые на низком уровне заполнены при помощи ПДП. Цитата(sasamy @ Aug 31 2013, 22:17)  Естественно, есть готовые фреймворки, но ТС непременно хочет _свой_, он так и написал. На мой взгляд он абсолютно прав. Надо делать так как надо, а не так как получится.
Сообщение отредактировал Tarbal - Aug 31 2013, 19:57
|
|
|
|
|
Sep 2 2013, 14:07
|
Знающий
   
Группа: Участник
Сообщений: 783
Регистрация: 22-11-08
Пользователь №: 41 858

|
Цитата(Tarbal @ Aug 31 2013, 23:51)  я не принимаю решений за счет ЦПУ При чем тут ЦПУ ? вы похоже ни слова не поняли из того что я написал. Цитата На мой взгляд он абсолютно прав. Надо делать так как надо, а не так как получится. Рекомендую эти два поста прочитать и сходить по ссылкам которые там http://electronix.ru/forum/index.php?showt...t&p=1175040если делать правильно о таких вещах которые вы тут про ноды и шины описываете вообще не надо думать, за это отвечает общий код для класса соотвествующих устройств, вы пишете только код специфичный для вашего устройства - ага ООП стиль во все поля. Даже если приспичило велосипед изобрести - есть специальный класс misc device http://lxr.free-electrons.com/source/drivers/char/misc.c
Сообщение отредактировал sasamy - Sep 2 2013, 14:26
|
|
|
|
|
Sep 2 2013, 16:48
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
Цитата(Tarbal @ Aug 31 2013, 21:11)  имея ПДП фифо не нужен как страшный сон. Fifo работает так: ПДП заполняет блок памяти, после чего вызывает прерывание или каким-то другим образом сигнализирует процессору, что блок заполнился, и начинает заполнять следующий блок памяти. Логично, чтобы эти блоки следовали непрерывно. С точки зрения процессора память, разбитая для ПДП на блоки, непрерывна и представляет собой FIFO или циклический буфер. Допустим данные добавляются в хвост. Процессор, получив прерывание или флаг, смещает указатель хвоста на размер блока, что соответствует push в fifo. При вызове read читаются n байт, и голова смещается на эти n байт. Что соответствует pop из fifo. Голова сравнялась с хвостом - данных нет, ждем нового прерывания в ядре, блокируем дескриптор устройства и т.д. Без fifo придется читать данные блоками только фиксированного размера, а после чтения как-то переключать указатель на следующий блок. Т.е. вообще говоря будет какой-то кольцевой буфер указателей опять же. Получается что используя ПДП в чистом виде, без fifo, можно читать только один блок, непосредственно принятый ПДП, а если не успели? У процессора может и не быть ПДП к АЦП. Тогда FIFO драйвера может заполняться по прерыванию или полингу. Т.е. это к тому, что FIFO все равно есть, а вот ПДП уже отсутствует. По поводу udev, задумался о своем), не учел, что это тема про линукс в общем, а не только про драйверы встроенной периферии.
|
|
|
|
|
Sep 3 2013, 13:29
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
Цитата(sasamy @ Aug 31 2013, 18:07)  Кольцевая очередь (циклический двусвязный список) из этих буферов (вернее их там две). Кто и по какому интерфейсу заполняет буферы - вообще не важно, хоть за счет ЦПУ. Цитата(sasamy @ Sep 2 2013, 18:07)  При чем тут ЦПУ ? вы похоже ни слова не поняли из того что я написал. Я полагаю вы и сами не поняли что написали. Цитата(psL @ Sep 2 2013, 20:48)  Fifo работает так: ПДП заполняет блок памяти, после чего вызывает прерывание или каким-то другим образом сигнализирует процессору, что блок заполнился, и начинает заполнять следующий блок памяти. Логично, чтобы эти блоки следовали непрерывно. С точки зрения процессора память, разбитая для ПДП на блоки, непрерывна и представляет собой FIFO или циклический буфер. Допустим данные добавляются в хвост. Процессор, получив прерывание или флаг, смещает указатель хвоста на размер блока, что соответствует push в fifo. При вызове read читаются n байт, и голова смещается на эти n байт. Что соответствует pop из fifo. Голова сравнялась с хвостом - данных нет, ждем нового прерывания в ядре, блокируем дескриптор устройства и т.д. Без fifo придется читать данные блоками только фиксированного размера, а после чтения как-то переключать указатель на следующий блок. Т.е. вообще говоря будет какой-то кольцевой буфер указателей опять же. Получается что используя ПДП в чистом виде, без fifo, можно читать только один блок, непосредственно принятый ПДП, а если не успели? У процессора может и не быть ПДП к АЦП. Тогда FIFO драйвера может заполняться по прерыванию или полингу. Т.е. это к тому, что FIFO все равно есть, а вот ПДП уже отсутствует.
По поводу udev, задумался о своем), не учел, что это тема про линукс в общем, а не только про драйверы встроенной периферии. Можно сказать, мы с вами что пришли к консенсусу по поводу ПДП и фифо?  Делать на Линуксе устройство быстрого обмена без ПДП стремно, а зачастую и невозможно. Здесь меня поддержит A.Fig Lee. Мы с ним недавно обсуждали эту тему на другой площадке.
Сообщение отредактировал Tarbal - Sep 3 2013, 13:39
|
|
|
|
|
Sep 3 2013, 16:14
|
Знающий
   
Группа: Участник
Сообщений: 783
Регистрация: 22-11-08
Пользователь №: 41 858

|
Цитата(Tarbal @ Sep 3 2013, 17:29)  Я полагаю вы и сами не поняли что написали. Цитата фреймворк у которого есть готовые средства для управления памятью ( буфер DMA + метаинформация) буферы отображаются в памяти пользовательского процесса странно что после этого описания вы так и не поняли о чем речь и продолжаете капитанить Цитата Делать на Линуксе устройство быстрого обмена без ПДП стремно самое смешное что именно для этого весь пост и был - как при использовании DMA иметь одновременно быстрый доступ к данным из пользовательского процесса. Можно конечно списать на то что вы иностранец, но я больше склоняюсь что житель крайнего севера.
|
|
|
|
|
Sep 3 2013, 16:24
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
Цитата У процессора может и не быть ПДП к АЦП. Тогда FIFO драйвера может заполняться по прерыванию или полингу. Т.е. это к тому, что FIFO все равно есть, а вот ПДП уже отсутствует. Цитата(sasamy @ Sep 3 2013, 20:14)  самое смешное что именно для этого весь пост и был - как при использовании DMA иметь одновременно быстрый доступ к данным из пользовательского процесса. Можно конечно списать на то что вы иностранец, но я больше склоняюсь что житель крайнего севера. самое смешное, что вы постингов не читаете на которые были ответы. Кстати заодно перечитайте самый первый постинг для освежения памяти. Вам я больше отвечать не буду.
|
|
|
|
|
Sep 3 2013, 17:46
|
Знающий
   
Группа: Участник
Сообщений: 783
Регистрация: 22-11-08
Пользователь №: 41 858

|
Цитата(Tarbal @ Sep 3 2013, 20:24)  самое смешное, что вы постингов не читаете на которые были ответы. Почему же не читаю - читаю Цитата Кстати заодно перечитайте самый первый постинг для освежения памяти. Вот мой ответ на исходный пост http://lxr.free-electrons.com/ident?i=misc_registerгуглится в 3 сек. Я вообще не хотел в эту ветку влезать с таким изначально простым вопросом, но увидел ваши фееричные рассуждения про FIFO  не смог пройти мимо Цитата Вам я больше отвечать не буду. да сколько угодно
|
|
|
|
|
Sep 5 2013, 06:58
|
Знающий
   
Группа: Участник
Сообщений: 783
Регистрация: 22-11-08
Пользователь №: 41 858

|
Цитата(Tarbal @ Sep 4 2013, 21:26)  Интересно стало: есть ли здесь кто-нибудь кто писал драйвер для фреймворка и отладил его? Под фреймворком я имею ввиду что-нибудь из COMEDI, IIO или ZIO. В IIO полно готовых драйверов в ванильном ядре даже в основной ветке а не в staging , для того же атмеловского ADC есть готовые драйверы и триггер аппартаный на TCB он поддерживает. Проблема в этом http://electronix.ru/forum/index.php?showt...t&p=1085092то что хотел ТС не сделать с ядерными драйверами SPI например на at91, нужно все по-своему настраивать.
|
|
|
|
|
Sep 5 2013, 07:30
|
Частый гость
 
Группа: Участник
Сообщений: 167
Регистрация: 15-08-07
Пользователь №: 29 803

|
Есть, писали  Comedi самый старый фреймворк, для него больше всего драйверов. К тому же, он поддерживает RTAI, что делает его весьма популярным (у буржуев, во всяком случае). Также он поддерживает все виды обмена - read/write, mmap, polling, triggering etc. Поэтому я и назвал его стандартом де-факто. Еще полезно посмотреть обсуждения в мейлистах как самого COMEDI, так и RTAI - там обсуждались почти все сценарии использования.
|
|
|
|
|
Sep 5 2013, 11:11
|
Знающий
   
Группа: Участник
Сообщений: 783
Регистрация: 22-11-08
Пользователь №: 41 858

|
Цитата(vshemm @ Sep 5 2013, 11:30)  Comedi самый старый фреймворк, для него больше всего драйверов. К тому же, он поддерживает RTAI, что делает его весьма популярным RTAI конечно решает часть проблем, но опять же драйвер SPI надо переписывать под него, к тому же все эти "тонкие" ядра и виртуализация все менее актуальны когда появляются гибридные SoC http://www.freescale.com/webapp/sps/site/p....jsp?code=VF6xxи есть готовые решения для коммуникаций https://linuxlink.timesys.com/docs/wiki/eng...uide_vybrid_mcc
|
|
|
|
|
Sep 5 2013, 13:00
|
Частый гость
 
Группа: Участник
Сообщений: 167
Регистрация: 15-08-07
Пользователь №: 29 803

|
Цитата(Tarbal @ Sep 5 2013, 16:26)  Теперь такая проблема. У меня ЦПУ Freescale Cortex A8 -- iMX53. Насколько легко подогнать драйвер от Фреймворка к моим нуждам? Скажем драйвер параллельного АЦП. Мне надо настроить ДМА и прерывания. Ну и порт надо настроить, ведь я не буду использивать PCI, а подключу АЦП прямо к одному из портов ЦПУ. .. Так, как указано здесь http://www.comedi.org/doc/driverwriting.htmlТ.е. берете скелетон драйвера и имплементируете все необходимые функции (attach, read/write etc). БОльшая часть работы по подгонке - это работа с железом.
|
|
|
|
|
Sep 5 2013, 13:29
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
Цитата(vshemm @ Sep 5 2013, 17:00)  Так, как указано здесь http://www.comedi.org/doc/driverwriting.htmlТ.е. берете скелетон драйвера и имплементируете все необходимые функции (attach, read/write etc). БОльшая часть работы по подгонке - это работа с железом. И чем это лучше чем написать стандартный Линукс драйвер, кторый не будет зависеть от Фреймворка, требовать установки фреймворковских библиотек и изучения фреймворковских требований и ограничений? Тем более, что Линукс драйвер похожего устройства можно найти в кернеле. Разве что не требуется понимания реал-тайм проблем. Все спрятано во фреймворке. Меня реал-тайм проблемы не остановят
Сообщение отредактировал Tarbal - Sep 5 2013, 13:33
|
|
|
|
|
Sep 5 2013, 14:32
|
Частый гость
 
Группа: Участник
Сообщений: 167
Регистрация: 15-08-07
Пользователь №: 29 803

|
Цитата(Tarbal @ Sep 5 2013, 17:29)  И чем это лучше чем написать стандартный Линукс драйвер, кторый не будет зависеть от Фреймворка, требовать установки фреймворковских библиотек и изучения фреймворковских требований и ограничений? Тем более, что Линукс драйвер похожего устройства можно найти в кернеле. Это тоже кернельный фреймворк  Преимущества как и у любого фреймворка - дополнительный слой абстракции. Т.е. там уже есть понятия как девайсы, сабдевайсы, каналы, диапазоны измерений, ADC, DAC и т.п. с которыми работать удобнее, чем с read/write абстрактого драйвера. Зачем изобретать свой велосипед, если уже есть неплохой. Плюс, под камеди написано много софта (некоторый можно использовать как тесты). Плюс, в linux любят менять интерфейсы ядра, поэтому свой драйвер придется допиливать под разные версии; в камеди же этим занимаются мейнтейнеры и низкоуровневая часть (ваша) меняться не будет. Плата за это - раздутие кода, хоть в данном случае и небольшое. Изучать там не больше, чем изучать другие интерфейсы с ядром. В любом случае решать вам, может, действительно тупой драйвер будет лучше. Цитата Разве что не требуется понимания реал-тайм проблем. Все спрятано во фреймворке. Меня реал-тайм проблемы не остановят  Риалтайм проблемы тут не причем, RTAI отдельная песня, позволяющая виртуализировать ядро linux. Так вот, в камеди есть интерфейс для сообщения с этим супервизором. Фактически, это уже не линуксовый драйвер получится, а RTAI-шный (но умеющий общаться с программами в linux).
|
|
|
|
|
Sep 5 2013, 15:01
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
Моя проблема в том, что в ссылке, что вы дали под линком: How to use DMA and interrupts? Вот такая страничка. http://www.comedi.org/doc/drivercallbacks.htmlМне мало информации, чтобы понять как это работает, а о том как писать драйверы под кернел и куча книг и в интернете полно информации. Про ПДП в нарушение обещания данного в названии ссылки ни слова не нашел. Вы сами драйвер писали? Для нового устройства. Так чтобы там ДМА контроллер был специфический. Я подозреваю, что там начнется песня с пляской. Вот сейчас мы работаем со стандартной Линукс библиотекой OPAL она нужна для организации видео телефонных звонков через интернет. Автор легко добавил необходимые нам свойства и оно легко заработало на х86 железе. А дальше начались сюрпризы с портингом на iMX53. И это заметьте все в пространстве пользователя происходит. Ни строчки из кернела не затронуто. Автор библиотеки уже два месяца бьётся над решением возникающих проблем. Вы поймите, я не против использования фреймворка, мне интересно разобраться если оно мне надо. Кстати ZIO должна быть серьёзной системой, но самое смешное, что там нужно знать ту информацию, которую я давал. Вот выдержка из manual: 3 The Bus Abstraction The ZIO core module is called zio.ko and it creates a new bus item in Linux. A bus is a software abstraction for kernel-related software modules; it splits the role of the device from the role of the driver. In order to have a new peripheral working in your system you thus need both items: the driver is in charge of any device that appears in the system, while the device is a data structure that describes the parameters of the specific hardware instance. The two structures are bound by calling a match function, which is at the core of the bus abstraction. If the device and the driver match, the driver is asked to manage the new device instance. Цитата(vshemm @ Sep 5 2013, 18:32)  тупой драйвер будет лучше. Метод бритвы Оккама призывает делать вещи проще. Цитата(vshemm @ Sep 5 2013, 18:32)  с которыми работать удобнее, чем с read/write абстрактого драйвера зачем read/write драйверы содержат IOCTL функции для этой цели, Второй метод через procfs.
Сообщение отредактировал Tarbal - Sep 5 2013, 15:08
|
|
|
|
|
Sep 5 2013, 15:25
|
Частый гость
 
Группа: Участник
Сообщений: 167
Регистрация: 15-08-07
Пользователь №: 29 803

|
Цитата(Tarbal @ Sep 5 2013, 19:01)  Моя проблема в том, что в ссылке, что вы дали под линком: How to use DMA and interrupts? Вот такая страничка. http://www.comedi.org/doc/drivercallbacks.htmlМне мало информации, чтобы понять как это работает, а о том как писать драйверы под кернел и куча книг и в интернете полно информации. А вы в \comedi\drivers\skel.c заглядывали? Там половина текста - комментарии что и как и зачем и когда реализовывать. И это актуальная инфа. В отличие от "книг по..". Так или иначе разбираться с этим придется, и чтение кода просто необходимо. Это нормально для инженера, перестаньте слушать маркетинговую чушь  Ок, опишу свои действия, если бы мне поставили подобную задачу (при условии, что я такого раньше не делал). Первое - это провести исследование на предмет решения подобных проблем. Т.е. сразу же появляются варианты - raw driver, comedi, IIO, ZIO... Это пара часов. Далее, я бы изучил за и против данных подходов с точки зрения реальной задачи (для чего этот драйвер пишется, сроки, бюджет, кому он нужен, требования, срок жизни, стоимость поддержки и т.п.). Это день, максимум, два. В результате у меня на руках была бы _аргументированная_ точка зрения, почему я выбрал то и то. Все, далее согласование (если нужно) и кодирование. Профит. Конечно, это по-хорошему должны делать архитекты/техлиды или хотя бы сеньоры. А кодировать можно уже поручить и кодеру. А вы хотите, чтобы на форуме телепаты сказали как _вам_ лучше? Не бывает такого. А если и бывает, то либо лгут, либо ораторы идиоты, либо банальщина полная. Так что вперед, изучайте доки и код, направление задано. Это единственный путь  З.Ы. Доки пошаговые есть, код есть, мейллисты (списки рассылки есть) - это не недостаток информации, а избыток
Сообщение отредактировал vshemm - Sep 5 2013, 15:26
|
|
|
|
|
Sep 6 2013, 07:49
|
Знающий
   
Группа: Участник
Сообщений: 783
Регистрация: 22-11-08
Пользователь №: 41 858

|
Цитата(Tarbal @ Sep 5 2013, 19:01)  Кстати ZIO должна быть серьёзной системой, но самое смешное, что там нужно знать ту информацию, которую я давал. Вот выдержка из manual: Главное чтобы вы понимали для чего им понадобилась своя абстрактная шина Цитата Even if no physical bus is involved with ZIO, by relying on this software abstraction we are able to deal with several devices of the same type. на то он и фреймворк - это код для целого класса устройств. Теперь подумайте для чего вы все это рассказывали ТС.
|
|
|
|
|
Sep 7 2013, 17:27
|
Частый гость
 
Группа: Участник
Сообщений: 167
Регистрация: 15-08-07
Пользователь №: 29 803

|
Цитата(Tarbal @ Sep 6 2013, 15:04)  Вопрос знатокам. В данный момент я делаю драйвер ethernet порта на KSZ8863 of Micrel. Мне надо, чтобы третий порт был подключен к моему процессору iMX53, а два остальных могли быть использованы для подключения к сети. Причем надо обеспечить сквозное прохождение не предназначенных моему ЦПУ пакетов.
Возникают вопросы: Какой фреймворк мне лучше использовать? Какие примеры смотреть? Выбор там небольшой - network devices отдельный класс устройств, а KSZ8863 вообще phy device (PHY Abstraction Layer). Документация - /Documentation/networking/ MAC драйвер - /drivers/net/ethernet/freescale/ KSZ8863 драйвер - /drivers/net/phy/micrel.c Настройку свича проще всего сделать прошив в EEPROM KSZ8863 нужные настройки через i2c или spi (прямо из юзермода). Если EEPROM или i2c/spi отсутствуют на вашей борде, тогда настройку можно сделать через mdio bus (MII интерфейс) который точно подключен. Ну и может понадобиться пошаманить над /arch/arm/mach-imx для выделения ресурсов.
|
|
|
|
|
Sep 9 2013, 11:50
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
Цитата(sasamy @ Sep 9 2013, 09:44)  Мой вопрос к тому, что если для других драйверов надо знать стандартный подход, то для чего еще делать решения посредством фреймворков? Я вижу два преимущества фреймворков. Разработчику не обязательно вникать в тонкости работы ядра. Не обязательно глубоко понимать реал-тайм. Принимаю, что этого достаточно для широкого применения фреймворков.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|