Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: свой драйвер АЦП
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > Linux
Страницы: 1, 2
TigerSHARC
Надобно написать драйвер(модуль ядра) АЦП.

Прочитав Linux Device Drevers вижу очевидный путь: пишу модуль ядра, который представляет собой standalone программу, принимающую данные от АЦП поп рерыванию от АЦП(сигнал когда данные готовы), и оформленную как собственно модуль/драйвер для Linux (благо доступ к регистрам есть из пространства ядра)

Но! Вижу что устройства "по-хорошему" регистрируются в sysfs, а вот этот путь не совсем понятен.

Вопрос: чем чреват первый путь и и как писать для второго(статейки может какие есть с примерами...)?
DASM
Ну вообще доступ к регистрам можно и из пользовательского режима получить, с mmap. Что вы называете "standalone" программой которая к тому же модуль ядра ? Драйве - он и в Африке драйвер. Даете драйверу пулы памяти, делаете нужный ioctl и пусть драйвер заполняет данными буфера, и возвращает их. Вобщем-то лучше бы он их и выделял. Все эти /proc и sysfs - линуксоиды сами с ними разобраться не могут, я по старинке через mknod и файл устройства работаю. Геммора меньше, да и Техасовские дрова так и написаны (и не только они). Что-то вызывающее ясность есть например тут http://www.linuxdevcenter.com/pub/a/linux/...nder-linux.html
TigerSHARC
Цитата(DASM @ Jun 13 2013, 16:21) *
Ну вообще доступ к регистрам можно и из пользовательского режима получить, с mmap...[/url]



нет, ну зачем же тогда драйвер? в драйвере я по прерыванию заполняю буфер, настраиваю порт (в частности SPI) - и это всё работая через макросы регистров. Разве в юзерспейс так можно? (и с той же скоростью...)
DASM
Не, так делать не надо. Но можно.. Мне если лень драйвер компилить на очередном проце, а надо понять, что делает тот или иной регистр - делаю так. А вы пишите драйвер. Вообще посмотрите лучше реализацию v4l video 4 linux - там capture drivers - они ж тоже самое делают. Модифицировать их как надо, и дело в шляпе.
Hoodwin
С 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.
Idle
Цитата(TigerSHARC @ Jun 13 2013, 15:29) *
Вижу что устройства "по-хорошему" регистрируются в sysfs, а вот этот путь не совсем понятен.

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

Мне кажется procfs/sysfs не лучшие интерфейсы для большого обьема данных или данных которые идут непрерывно и слишком быстро. Большой оверхед на открытие-закрытие и syscall вызовы.
IMHO удобнее mmap с каким-нить ring buffer, которое удобно обрабатывать через readv.
Ya_Mike
Цитата(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(..)).
sasamy
Цитата(Ya_Mike @ Jul 4 2013, 17:24) *
Можно описать подробней, какая связка mmap-а, ring-buffer-a и readv имеется ввиду?


Например как написал DASM - v4l2 streaming
http://lwn.net/Articles/240667/

vshemm
В ядре (хоть и в staging) есть специальный фреймворк для подобных девайсов, ставший уже стандартом де-факто: http://www.comedi.org/doc/index.html
sasamy
Цитата(vshemm @ Jul 5 2013, 15:44) *
В ядре (хоть и в staging) есть специальный фреймворк для подобных девайсов, ставший уже стандартом де-факто: http://www.comedi.org/doc/index.html


Для АЦП ближе тогда уж
http://wiki.analog.com/software/linux/docs/iio/iio

вот еще есть интересный фреймворк
http://www.ohwr.org/projects/zio

так что стандартом comedi сложно назвать
Муравей
Цитата(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. Так же из файлов читаю текущее положение кольцевых указателей.

Заранее спасибо за ответы.
denyslb
Цитата(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, но мне кажется накладных расходов больше (если судить по статье).
DASM
Цитата(Муравей @ 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 и выходит
Tarbal
в /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
Dubov
Цитата(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
Зачем мудрить с шинами и файловыми системами драйверов. Разве что как дань моде...

может быть я не прав.
Tarbal
Цитата(Dubov @ Aug 26 2013, 17:38) *
интересно, а не проще ли написать модуль и просто создать файл устройства символьного в /dev

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

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


Я рассказал как правильно работать с драйвером в Линуксе. И вопрос был о том как получить записи о драйвере в sysfs. К тому же в /dev драйвер pipe появится сам если все правильно делать.
Проблема с вашим подходом в том, что это устаревшая практика. Сегодня устройства в /dev появляются усилиями системы udev.
Dubov
Ну а кроме устарелости моей практики, что можно сказать о новой? Она просто систематизирует устройства? или есть какие-то неоспоримые плюсы?
Tarbal
Цитата(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
Hoodwin
В новой модели драйверов тоже есть свои неудобства. Например, можно взять стандартный UART 16550. Это довольно распространенный контроллер, для которого существует много вариантов сопряжения с основным процессором: через ISA, PCI, наконец в современных системах на кристалле это вариант platform_device. Мне вот пришлось делать подобное для "новой" шины VLYNQ. Так вот проблема в том, что программно интерфейс для всех реализаций самого 16550 одинаковый, но приходится писать разные драйверы и регистрировать их в разных шинах. Получается вместо повторного использования кода его дублирование.
Tarbal
Цитата(Hoodwin @ Aug 27 2013, 18:17) *
В новой модели драйверов тоже есть свои неудобства. Например, можно взять стандартный UART 16550. Это довольно распространенный контроллер, для которого существует много вариантов сопряжения с основным процессором: через ISA, PCI, наконец в современных системах на кристалле это вариант platform_device. Мне вот пришлось делать подобное для "новой" шины VLYNQ. Так вот проблема в том, что программно интерфейс для всех реализаций самого 16550 одинаковый, но приходится писать разные драйверы и регистрировать их в разных шинах. Получается вместо повторного использования кода его дублирование.

Это не относится к новой или старой модели. Просто драйверы принадлежат шинам.
Новое это как делать pipes в /dev. При помощи скрипта или система сама сделает посредством udev.
A. Fig Lee
Цитата(Hoodwin @ Aug 27 2013, 10:17) *
В новой модели драйверов тоже есть свои неудобства. Например, можно взять стандартный UART 16550. Это довольно распространенный контроллер, для которого существует много вариантов сопряжения с основным процессором: через ISA, PCI, наконец в современных системах на кристалле это вариант platform_device. Мне вот пришлось делать подобное для "новой" шины VLYNQ. Так вот проблема в том, что программно интерфейс для всех реализаций самого 16550 одинаковый, но приходится писать разные драйверы и регистрировать их в разных шинах. Получается вместо повторного использования кода его дублирование.

А вот в V4L эта проблема решена
Tarbal
Цитата(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.
Ссылку на код можешь дать?
A. Fig Lee
Цитата(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
Tarbal
Цитата(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.?
A. Fig Lee
Цитата(Tarbal @ Aug 29 2013, 15:57) *
What is КWorld UB-435 ver 2.?

http://www.linuxtv.org/wiki/index.php/KWor...B_ATSC_TV_Stick
Tarbal
Цитата(A. Fig Lee @ Aug 30 2013, 02:20) *


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

bb-offtopic.gif
Да проблемы там больше не линуксовые.
Послать правильные данные хочется. Както оно все не то, что виндоус посылает.

bb-offtopic.gif
Пример я просто привел как показатель использования разных шин
Tarbal
Цитата(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
psL
Цитата(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 можно заполнять хоть по полингу, а ПДП м.б. к одному адресу памятиwink.gif
udev для встраиваемых систем вообще избыточен, поскольку состав подключаемого оборудования известен заранее и находится уже на борту. Обычно используют mdev из bb
Хотя может вы про adc на usb или pci шине.
V4L (про 2 в курсеsm.gif) приведен как пример (было в предыдущих постах), по поводу АЦП в V4L - во-первых, видеосигналы и АЦП бывают разные, во-вторых, аудиопоток в видео никто не отменял
Tarbal
Цитата(A. Fig Lee @ Aug 30 2013, 20:04) *
bb-offtopic.gif
Да проблемы там больше не линуксовые.
Послать правильные данные хочется. Както оно все не то, что виндоус посылает.

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


Это не противоречит тому, что я сказал. Там несколько драйверов и несколько устройств создаётся. В разных шинах. Каждому драйверу создается хотя бы одно устройство.
На I2C один драйвер, на USB другой, на Video третий и не удивлюсь если это не предел.
A. Fig Lee
Цитата(Tarbal @ Aug 30 2013, 18:08) *
Это не противоречит тому, что я сказал. Там несколько драйверов и несколько устройств создаётся. В разных шинах. Каждому драйверу создается хотя бы одно устройство.
На I2C один драйвер, на USB другой, на Video третий и не удивлюсь если это не предел.


А кто говорил что противоречит? Я о том и говорил что создаются несколько устройств на разных шинах.
Tarbal
Цитата(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 как концепцию в противовес методу делать пайпы вручную.
sasamy
Цитата
Но если вы настаиваете, то имея ПДП фифо не нужен как страшный сон.


Скоростная периферия работает не с контроллером DMA а сама является bus master и фифо там нужен чтобы смягчить нагрузку на шину. Периферии попроще - тоже самое, только чтобы упростить жизнь контроллеру DMA у которого каналов до и более. Без фифо любит делать атмел - кривейшая периферия наверно из того с чем встречался. Хотя я вас возможно неправильно понял (тут вы сами виноваты) и имеется ввиду фифо в общей памяти а не локальная память периферийных устройств, так без буферов для DMA которые в очередь как фифо выстраиваются ни одна нормальная ОС не обходится.
Tarbal
Цитата(sasamy @ Aug 31 2013, 21:37) *
Скоростная периферия работает не с контроллером DMA а сама является bus master и фифо там нужен чтобы смягчить нагрузку на шину. Периферии попроще - тоже самое, только чтобы упростить жизнь контроллеру DMA у которого каналов до и более. Без фифо любит делать атмел - кривейшая периферия наверно из того с чем встречался.


Я с этим не спорю.
Разве вопрос стоит о том как устроена скоростная периферия?
Давайте не будем уходить в теорию в то время, когда человеку надо решить его конкретную проблему.
Был вопрос как проще сделать драйвер для АЦП и каким способом сделать это правильно, чтобы /sys был заполнен необходимыми псевфо файлами. Я предложил как это сделать. Что имеется ввиду под фифо в контексте данной задачи я смутно себе представляю. Надо поставить какой-то дополнительный чип? Или как? Исполнить его программно в интеррапте? В то же время процессор имеет немерянное число каналов ПДП, один из которых прекрасно справится с работой.
В то же время использование мультимедиа драйверов в качестве прототипа я считаю не лучшим подходом.
sasamy
Цитата(Tarbal @ Aug 31 2013, 21:57) *
Был вопрос как проще сделать драйвер для АЦП и каким способом сделать это правильно


Пример V4l2 - это как можно не напрягая мозг использовать фреймворк у которого есть готовые средства для управления памятью ( буфер DMA + метаинформация) буферы отображаются в памяти пользовательского процесса и позволяют избежать лишнего копирования за счет CPU которе неизбежно будет при использовании read/write (copy_to_user()/copy_from_user() )

Цитата
Что имеется ввиду под фифо в контексте данной задачи


Кольцевая очередь (циклический двусвязный список) из этих буферов (вернее их там две). Кто и по какому интерфейсу заполняет буферы - вообще не важно, хоть за счет ЦПУ.

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


Естественно, есть готовые фреймворки, но ТС непременно хочет _свой_, он так и написал.
Tarbal
Цитата(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) *
Естественно, есть готовые фреймворки, но ТС непременно хочет _свой_, он так и написал.

На мой взгляд он абсолютно прав. Надо делать так как надо, а не так как получится.

sasamy
Цитата(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
psL
Цитата(Tarbal @ Aug 31 2013, 21:11) *
имея ПДП фифо не нужен как страшный сон.

Fifo работает так: ПДП заполняет блок памяти, после чего вызывает прерывание или каким-то другим образом сигнализирует процессору, что блок заполнился, и начинает заполнять следующий блок памяти. Логично, чтобы эти блоки следовали непрерывно. С точки зрения процессора память, разбитая для ПДП на блоки, непрерывна и представляет собой FIFO или циклический буфер.
Допустим данные добавляются в хвост. Процессор, получив прерывание или флаг, смещает указатель хвоста на размер блока, что соответствует push в fifo. При вызове read читаются n байт, и голова смещается на эти n байт. Что соответствует pop из fifo. Голова сравнялась с хвостом - данных нет, ждем нового прерывания в ядре, блокируем дескриптор устройства и т.д.
Без fifo придется читать данные блоками только фиксированного размера, а после чтения как-то переключать указатель на следующий блок. Т.е. вообще говоря будет какой-то кольцевой буфер указателей опять же.
Получается что используя ПДП в чистом виде, без fifo, можно читать только один блок, непосредственно принятый ПДП, а если не успели?
У процессора может и не быть ПДП к АЦП. Тогда FIFO драйвера может заполняться по прерыванию или полингу. Т.е. это к тому, что FIFO все равно есть, а вот ПДП уже отсутствует.

По поводу udev, задумался о своем), не учел, что это тема про линукс в общем, а не только про драйверы встроенной периферии.
Tarbal
Цитата(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, задумался о своем), не учел, что это тема про линукс в общем, а не только про драйверы встроенной периферии.


Можно сказать, мы с вами что пришли к консенсусу по поводу ПДП и фифо? sm.gif

Делать на Линуксе устройство быстрого обмена без ПДП стремно, а зачастую и невозможно. Здесь меня поддержит A.Fig Lee. Мы с ним недавно обсуждали эту тему на другой площадке.
sasamy
Цитата(Tarbal @ Sep 3 2013, 17:29) *
Я полагаю вы и сами не поняли что написали.


Цитата
фреймворк у которого есть готовые средства для управления памятью ( буфер DMA + метаинформация) буферы отображаются в памяти пользовательского процесса


странно что после этого описания вы так и не поняли о чем речь и продолжаете капитанить

Цитата
Делать на Линуксе устройство быстрого обмена без ПДП стремно


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


Цитата(sasamy @ Sep 3 2013, 20:14) *
самое смешное что именно для этого весь пост и был - как при использовании DMA иметь одновременно быстрый доступ к данным из пользовательского процесса. Можно конечно списать на то что вы иностранец, но я больше склоняюсь что житель крайнего севера.


самое смешное, что вы постингов не читаете на которые были ответы. Кстати заодно перечитайте самый первый постинг для освежения памяти.

Вам я больше отвечать не буду.
sasamy
Цитата(Tarbal @ Sep 3 2013, 20:24) *
самое смешное, что вы постингов не читаете на которые были ответы.


Почему же не читаю - читаю

Цитата
Кстати заодно перечитайте самый первый постинг для освежения памяти.


Вот мой ответ на исходный пост
http://lxr.free-electrons.com/ident?i=misc_register
гуглится в 3 сек. Я вообще не хотел в эту ветку влезать с таким изначально простым вопросом, но увидел ваши фееричные рассуждения про FIFO sm.gif не смог пройти мимо


Цитата
Вам я больше отвечать не буду.


да сколько угодно
Tarbal
Интересно стало: есть ли здесь кто-нибудь кто писал драйвер для фреймворка и отладил его? Под фреймворком я имею ввиду что-нибудь из COMEDI, IIO или ZIO.
sasamy
Цитата(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, нужно все по-своему настраивать.
vshemm
Есть, писали sm.gif

Comedi самый старый фреймворк, для него больше всего драйверов. К тому же, он поддерживает RTAI, что делает его весьма популярным (у буржуев, во всяком случае). Также он поддерживает все виды обмена - read/write, mmap, polling, triggering etc. Поэтому я и назвал его стандартом де-факто.

Еще полезно посмотреть обсуждения в мейлистах как самого COMEDI, так и RTAI - там обсуждались почти все сценарии использования.
sasamy
Цитата(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
Tarbal
Теперь такая проблема. У меня ЦПУ Freescale Cortex A8 -- iMX53. Насколько легко подогнать драйвер от Фреймворка к моим нуждам? Скажем драйвер параллельного АЦП. Мне надо настроить ДМА и прерывания.
Ну и порт надо настроить, ведь я не буду использивать PCI, а подключу АЦП прямо к одному из портов ЦПУ.

RTAI не поддерживает этот процессор
http://www.rtai.dk/cgi-bin/gratiswiki.pl?RTAI_On_ARM
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.