|
свой драйвер АЦП, два пути |
|
|
|
 |
Ответов
|
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
|
|
|
|
|
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
|
|
|
|
Сообщений в этой теме
TigerSHARC свой драйвер АЦП Jun 13 2013, 11:29 DASM Ну вообще доступ к регистрам можно и из пользовате... Jun 13 2013, 12:21 TigerSHARC Цитата(DASM @ Jun 13 2013, 16:21) Ну вооб... Jun 13 2013, 13:39 DASM Не, так делать не надо. Но можно.. Мне если лень д... Jun 13 2013, 14:37  DASM Цитата(Муравей @ Jul 12 2013, 14:47) Тоже... Aug 6 2013, 02:47 Idle Цитата(TigerSHARC @ Jun 13 2013, 15:29) В... Jun 18 2013, 03:57 Ya_Mike Как-то пользовался драйвером АЦП для at91-adc, для... Jun 28 2013, 13:13 denyslb Цитата(Ya_Mike @ Jun 28 2013, 16:13) Как-... Jun 29 2013, 01:38  Ya_Mike Цитата(denyslb @ Jun 29 2013, 05:38) Мне ... Jul 4 2013, 13:24   sasamy Цитата(Ya_Mike @ Jul 4 2013, 17:24) Можно... Jul 4 2013, 14:52   denyslb Цитата(Ya_Mike @ Jul 4 2013, 16:24) Откры... Jul 26 2013, 09:22 vshemm В ядре (хоть и в staging) есть специальный фреймво... Jul 5 2013, 11:44 sasamy Цитата(vshemm @ Jul 5 2013, 15:44) В ядре... Jul 5 2013, 19:29 Tarbal в /sys драйвер появится усилиями операционной сист... Aug 22 2013, 15:14 Dubov Цитата(Tarbal @ Aug 22 2013, 19:14) в /sy... Aug 26 2013, 13:38  Tarbal Цитата(Dubov @ Aug 26 2013, 17:38) интере... Aug 26 2013, 14:34 Dubov Ну а кроме устарелости моей практики, что можно ск... Aug 26 2013, 15:16 Tarbal Цитата(Dubov @ Aug 26 2013, 19:16) Ну а к... Aug 27 2013, 01:25 Hoodwin В новой модели драйверов тоже есть свои неудобства... Aug 27 2013, 14:17 Tarbal Цитата(Hoodwin @ Aug 27 2013, 18:17) В но... Aug 27 2013, 22:50  Tarbal Цитата(Tarbal @ Aug 28 2013, 02:50) Это н... Aug 28 2013, 13:08   A. Fig Lee Цитата(Tarbal @ Aug 28 2013, 09:08) А как... Aug 29 2013, 00:26    Tarbal Цитата(A. Fig Lee @ Aug 29 2013, 04:26) Н... Aug 29 2013, 19:57     A. Fig Lee Цитата(Tarbal @ Aug 29 2013, 15:57) What ... Aug 29 2013, 22:20      Tarbal Цитата(A. Fig Lee @ Aug 30 2013, 02:20) h... Aug 30 2013, 11:21       A. Fig Lee Цитата(Tarbal @ Aug 30 2013, 07:21) Если ... Aug 30 2013, 16:04        Tarbal Цитата(A. Fig Lee @ Aug 30 2013, 20:04) ... Aug 30 2013, 22:08         A. Fig Lee Цитата(Tarbal @ Aug 30 2013, 18:08) Это н... Aug 30 2013, 23:57 A. Fig Lee Цитата(Hoodwin @ Aug 27 2013, 10:17) В но... Aug 28 2013, 02:28 psL Драйвер АЦП, имхо, по простому - это символьное у... Aug 30 2013, 15:33 Tarbal Цитата(psL @ Aug 30 2013, 19:33) Драйвер ... Aug 30 2013, 16:21  psL Цитата(Tarbal @ Aug 30 2013, 20:21) V4L э... Aug 30 2013, 20:09   Tarbal Цитата(psL @ Aug 31 2013, 00:09) по повод... Aug 31 2013, 17:11    sasamy ЦитатаНо если вы настаиваете, то имея ПДП фифо не ... Aug 31 2013, 17:37     Tarbal Цитата(sasamy @ Aug 31 2013, 21:37) Скоро... Aug 31 2013, 17:57      sasamy Цитата(Tarbal @ Aug 31 2013, 21:57) Был в... Aug 31 2013, 18:17       Tarbal Цитата(sasamy @ Aug 31 2013, 22:17) Приме... Aug 31 2013, 19:51        sasamy Цитата(Tarbal @ Aug 31 2013, 23:51) я не ... Sep 2 2013, 14:07         Tarbal Цитата(sasamy @ Aug 31 2013, 18:07) Кольц... Sep 3 2013, 13:29          sasamy Цитата(Tarbal @ Sep 3 2013, 17:29) Я пола... Sep 3 2013, 16:14           Tarbal ЦитатаУ процессора может и не быть ПДП к АЦП. Тогд... Sep 3 2013, 16:24            sasamy Цитата(Tarbal @ Sep 3 2013, 20:24) самое ... Sep 3 2013, 17:46    psL Цитата(Tarbal @ Aug 31 2013, 21:11) имея ... Sep 2 2013, 16:48 Tarbal Интересно стало: есть ли здесь кто-нибудь кто писа... Sep 4 2013, 17:26 sasamy Цитата(Tarbal @ Sep 4 2013, 21:26) Интере... Sep 5 2013, 06:58 vshemm Есть, писали
Comedi самый старый фреймворк, для ... Sep 5 2013, 07:30 sasamy Цитата(vshemm @ Sep 5 2013, 11:30) Comedi... Sep 5 2013, 11:11 Tarbal Теперь такая проблема. У меня ЦПУ Freescale Cortex... Sep 5 2013, 12:26 vshemm Цитата(Tarbal @ Sep 5 2013, 16:26) Теперь... Sep 5 2013, 13:00  Tarbal Цитата(vshemm @ Sep 5 2013, 17:00) Так, к... Sep 5 2013, 13:29   vshemm Цитата(Tarbal @ Sep 5 2013, 17:29) И чем ... Sep 5 2013, 14:32 Tarbal Моя проблема в том, что в ссылке, что вы дали под ... Sep 5 2013, 15:01 vshemm Цитата(Tarbal @ Sep 5 2013, 19:01) Моя пр... Sep 5 2013, 15:25  Tarbal TigerShark если у вас будут вопросы по реализации ... Sep 5 2013, 19:08 sasamy Цитата(Tarbal @ Sep 5 2013, 19:01) Кстати... Sep 6 2013, 07:49 Tarbal Вопрос знатокам.
В данный момент я делаю драйвер e... Sep 6 2013, 11:04 vshemm Цитата(Tarbal @ Sep 6 2013, 15:04) Вопрос... Sep 7 2013, 17:27  Tarbal Цитата(vshemm @ Sep 7 2013, 21:27) Выбор ... Sep 8 2013, 21:11   sasamy Цитата(Tarbal @ Sep 9 2013, 01:11) Kак сд... Sep 9 2013, 05:44    Tarbal Цитата(sasamy @ Sep 9 2013, 09:44) Ваш во... Sep 9 2013, 11:50
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|