LINUX.ORG.RU

Сообщения Aleksis_92

 

Прерывания DMA в Linux

Форум — Linux-hardware

Добрый день!

Коллеги, подскажите пожалуйста, интересует следующий вопрос.

Вот, например, если мне нужно задать обработчик прерывания для gpio, которых у меня в системе за сотню, а прерываний от него реальных хорошо если наберется десяток, то линукс предлагает мне т.н. виртуальные прерывания, номер которых я могу запросить функцией gpio_to_irq. И в /proc/interrupts уже не существует прерываний gpio, номера которых указаны в документации, там показываются только виртуальные, которые заданы в системе. То есть все операции по считыванию флагов прерываний ось берет на себя, мне надо лишь в драйвере (модуле ядра) узнать номер прерывания(gpio_to_irq) и запросить его (request_irq). И тут возникла задача провернуть нечто аналогичное для dma - есть у меня в системе 64 dma канала, прерываний выведено само собой 1 штука. Его можно посмотреть в /proc/interrupts, счетчик увеличивается при срабатывании прерывания на любом из 64 каналов. Могу ли я не залезая в ядро и не извращаясь как-нибудь повесить обработчик прерывания на конкретный канал, не отменяя при этом уже заданные прерывания, аналогично тому, как оно происходит с gpio? Кто нибудь сталкивался с таким, может знает как это реализуется?

 ,

Aleksis_92
()

UDP датаграммы приходят не на тот ip адрес

Форум — Admin

Добрый день! Подскажите пожалуйста, как быть с такой проблемой. Требуется осуществить обмен данными через протокол UDP. Имеется обычный компьютер и плата с процом и кучей ethernet контроллеров (5 штук), и там и там стоит линукс. Если отправляю с платы на компьютер через любой ethernet, то вопросов никаких, все отрабатывает четко. А вот если наоборот... Вообщем независимо от того, на какой ip отправляется пакет, дойти он может на любой. Вот ifconfig на плате:

eth0      Link encap:Ethernet  HWaddr ea:8b:91:8f:9c:c3  
          inet addr:192.9.200.1  Bcast:192.9.200.255  Mask:255.255.255.0
          inet6 addr: fe80::e88b:91ff:fe8f:9cc3/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:347318 errors:0 dropped:0 overruns:0 frame:0
          TX packets:47376 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:297398853 (283.6 MiB)  TX bytes:7030948 (6.7 MiB)

eth1      Link encap:Ethernet  HWaddr 3e:a3:fa:68:08:a6  
          inet addr:192.9.200.2  Bcast:192.9.200.255  Mask:255.255.255.0
          inet6 addr: fe80::3ca3:faff:fe68:8a6/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:142316 errors:0 dropped:0 overruns:0 frame:0
          TX packets:74 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:40318502 (38.4 MiB)  TX bytes:9582 (9.3 KiB)

eth2      Link encap:Ethernet  HWaddr a6:72:cf:db:d5:d1  
          inet addr:192.9.200.3  Bcast:192.9.200.255  Mask:255.255.255.0
          inet6 addr: fe80::a472:cfff:fedb:d5d1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:104902 errors:0 dropped:0 overruns:0 frame:0
          TX packets:72 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:16243422 (15.4 MiB)  TX bytes:9420 (9.1 KiB)

eth3      Link encap:Ethernet  HWaddr 86:12:6d:95:6c:7e  
          inet addr:192.9.200.4  Bcast:192.9.200.255  Mask:255.255.255.0
          inet6 addr: fe80::8412:6dff:fe95:6c7e/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:129954 errors:0 dropped:0 overruns:0 frame:0
          TX packets:74 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:42846621 (40.8 MiB)  TX bytes:9546 (9.3 KiB)

eth4      Link encap:Ethernet  HWaddr 54:4a:16:cd:6e:cc  
          inet addr:192.9.200.5  Bcast:192.9.200.255  Mask:255.255.255.0
          inet6 addr: fe80::564a:16ff:fecd:6ecc/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:289203 errors:0 dropped:3012 overruns:0 frame:0
          TX packets:57 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:246783569 (235.3 MiB)  TX bytes:8209 (8.0 KiB)
          Interrupt:40

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:112572 errors:0 dropped:0 overruns:0 frame:0
          TX packets:112572 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:50659608 (48.3 MiB)  TX bytes:50659608 (48.3 MiB) 

eth 0..3 - однотипные контроллеры, eth4 - другой.

Соответственно с компа отправляю сообщения таким кодом:

#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <pthread.h>

char bufT[8];
FILE *temp;
int end = 0;

void * int_thread (void *arg){ 
    sleep(5);
    end = 1;
}

int main()
{
    int sock_us, sock_pc;
    struct sockaddr_in addr_us;
    struct sockaddr_in addr_pc;
    char buf[16384];
    int bytes_read;
    FILE *test;
    char message[] = "Hello there!\n";
    double var;
    int a, b = 0, c = 0;

/*--  Открытие соккета --*/
    sock_pc = socket(AF_INET, SOCK_DGRAM, 0);
    if(sock_pc < 0)
    {
        perror("socket");
    }


/*--  Настройка соккета --*/
    addr_us.sin_family = AF_INET;
    addr_us.sin_port = htons(35000);
    addr_us.sin_addr.s_addr = inet_addr("192.9.200.2");

/*--  Настройка второго соккета --*/
    addr_pc.sin_family = AF_INET;
    addr_pc.sin_addr.s_addr = htonl(INADDR_ANY);
    addr_pc.sin_addr.s_addr = inet_addr("192.9.200.150");
    b = bind(sock_pc, (struct sockaddr *)&addr_pc, sizeof(addr_pc));

if (b<0)
{
      perror("bind");
}else printf("bind = %d\n", b);
sleep(2);

    pthread_t thread;
      pthread_create (&thread, NULL, int_thread, NULL);
    int bytes, bytes_trans;
int i0 = 0,i1 = 0,i2 = 0;
    while(end == 0){
        i0++;
        if (i0 == 256){
            i0 = 0;
            i1++;
        }
        if (i1 == 256){
            i2++;i1=0;
        }
        buf[0] = i0;
        buf[1] = i1;
        buf[2] = i2;
       
        bytes_trans = sendto(sock_pc, buf, 2048, 0, (struct sockaddr *)&addr_us, sizeof(addr_us));
        bytes = bytes + bytes_trans;
        printf("buf = %x %x %x %x %x %x %x \n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6]);
        printf("send %d bytes\n", bytes);
        usleep(1000);
    }
    return 0;
}

В коде есть некоторые излишки, например bind и другие, потому как перепробовал кучу вариантов и с ними и без них. Чаще всего сообщения адресованные eth0..4 попадают на eth0, но не обязательно, сообщение может придти на любой порт. Куда оно пришло проверяю с помощью ifconfig и проверяю где в поле Rx появились доп мегабайты.

 ,

Aleksis_92
()

Device tree. строка compatible=«***»; ведет себя странно

Форум — Linux-hardware

Добрый день! Подскажите пожалуйста кто знает. Работаю с модулем beaglebone black, debian (kernel 3.8). Недавно запустил на нем ethernet микросхему wiznet w5300. Изначально была проблема в том, что драйвер не начинал даже запускаться. В device tree была прописана строка compatible = «wiznet,w5300»;, однако в логах ядра быбло четко видно что gpmc на котором висит данная микросхема успешно запущен, а вот драйвер даже не начинает загрузку. (Что бы убедиться в этом перекомпилировал ядро добавив в драйвер w5300 в начало функции probe prink(«Текст»);. Данная проблема была решена путем изменения в драйвере w5300 следующих строк

Было:

static SIMPLE_DEV_PM_OPS(w5300_pm_ops, w5300_suspend, w5300_resume);


static struct platform_driver w5300_driver = {
	.driver		= {
		.name	= DRV_NAME,
		.owner	= THIS_MODULE,
		.pm	= &w5300_pm_ops,
	},
	.probe		= w5300_probe,
	.remove		= w5300_remove,
};

module_platform_driver(w5300_driver);

Стало

static SIMPLE_DEV_PM_OPS(w5300_pm_ops, w5300_suspend, w5300_resume);

static const struct of_device_id w5300_dt_ids[] = {
	{ .compatible = "wiznet,w5300" },
	{ .compatible = "w5300" },
	{  }
};

MODULE_DEVICE_TABLE (of, w5300_dt_ids);

static struct platform_driver w5300_driver = {
	.driver		= {
		.name	= DRV_NAME,
		.owner	= THIS_MODULE,
		.pm	= &w5300_pm_ops,
		.of_match_table	= w5300_dt_ids,
	},
	.probe		= w5300_probe,
	.remove		= w5300_remove,
};

module_platform_driver(w5300_driver);

В итоге после ещё некоторых извращений удалось таки успешно запустить микросхему. После чего встала задача аналогичным образом запустить микросхему w5100, которая отличается тем, что висит на spi а не на параллельной шине. Однако, драйвер микросхемы не запускается, и аналогичное изменение драйвера не помогло. В device tree считаю что принципиальных ошибок, из за которых может не грузиться драйвер нет, так как стоит заменить в copmatible w5100 на другую микросхему, как в части случаев все работает, в части нет. Кто знает, из-за чего можетне запускаться драйвер, прописанный в compatible?

 

Aleksis_92
()

Драйвера устройств linux (Beaglebone)

Форум — Linux-hardware

Добрый день! Помогите пожалуйста с таким вопросом. Как, собственно говоря, работать с перифирийными устройствами на линукс, какой общий алгоритм? Работаю с процессорныи модулем beaglebone, процессор arm, linux debian, ядро 3,8. Первый раз меня интересовал датчик температуры i2c. С ним не возникло ровно никаких проблем - загрузил модуль драйвера, в каталоге /sys/class/ появилась нужная папка в которой все было интуитивно понятно. Далее потребовалось подключить железки посложнее, а именно wiznet w5300 (ethernet контроллер) и max14830 (spi-uart converter). Предпринял следующие шаги: 1) поставил драйвера (пробовал и встроенные в ядро и модули - разницы никакой) 2) добавил информацию об устройствам в device tree (возможно допустил ошибку, так как конкретных примеров не нашел на эти устройства под имеющуюся версию device tree, поэтому делал по аналогии) 3) в случае с ethernet контроллером добавил информацию о нем в файл /etc/network/interfaces. Что делать далее не понятно, команда ifconfig про новое устройство ничего не знает, в устройствах ничего не появилось, в каталоге созданном драйвером есть только ообщая информация об устройстве и bind, unbind и uevent, с которыми так и не нашел в интернете что делать и надо ли что либо делать. 4) в случае с max14830 - он появился в /proc/device-tree/osp.3/481a0000spi/.., могу посмотреть по нему общую информацию в каталоге, созданном драйвером, однако, опять же, никаких новых устройств, никаких папок\файлов для ввода вывода информации в каталоге драйвера - ничего нет.

Подскажите пожаоуйста что делаю не так, в чем ошибка.

 ,

Aleksis_92
()

FTDI преобразователь uart-usb отзеркаливает данные

Форум — Linux-hardware

Добрый день! Подскажите пожалуйста, возникла следующая проблема. Есть компьютер и есть микропроцессорный модуль на линукс. Так же есть FTDI преобразователь uart-usb. Когда по данному преобразователю подключал uart процессорного модуля к usb компьютера - данные шли туда и обратно без каких либо проблем, все четко (писал на си). Затем встала задача сделать петлю - подключить через преобразователь uart-usb uart процессорного модуля к его же usb. В итоге когда отправляю или принимаю данные через /dev/ttyO0 (uart) - все работает. Когда принимаю по /dev/ttyUSB0 (usb) - тоже. А вот когда отправляю по /dev/ttyUSB0, то данные доходят до адресата, но то что отправил тут же возвращается и приходит и на сам /dev/ttyUSB0. Если просто отправлять данные, при этом не принимать их с другой стороны - такой проблемы не возникает. Подскажите пожалуйста, с чем это может быть связано. Выложу кусок кода, который отвечает за передачу (в отдельном потоке)

int res_send;
while (1){
    if (send1 == 1){
      res_send = write(fd, buf_send, PACKAGE + 1 );
    }
      usleep(10000);
}

и прием/ответ с другой стороны

fd_set myDescriptors;
	struct timeval tv;
	tv.tv_sec = 2;
	tv.tv_usec = 0;
  int sel;
   while (1)
   {
     FD_ZERO(&myDescriptors);        
     FD_SET(fd, &myDescriptors);  
     sel = select(fp+1, &myDescriptors, 0, 0, &tv);
     if (sel < 1)
        usleep(3000);
     else{
	res = read(fd,buf,256);
   	sum = sum + res; 
        if ((res > 3)&&(buf[0] == 0x35)){// без этого условия все что я отправляю тут же возвращается, 
на это следует ответ, который так же возвращается и тд без остановки. 0x35 это код символа массив 
из которого посылаю сюда, отвечаю уже другим символом
           buf_send[res-1] = 0xA;
           res_send = write(fd, buf_send, res );
           sumSend = sumSend + res;
         }
    }
} 

 ,

Aleksis_92
()

BeagleBone interrupts

Форум — Linux-hardware

Подскажите пожалуйста, стоит следующая задача. Имеется процессорный модуль BeagleBone Bkack, на нем Debian (версия ядра 3.8). Требуется написать приложение на с, с++, которое при возникновении прерывания (пришли данные на uart) выполняет определенные действия (чтение данных). Насколько я понял, для этого требуется библиотека interrupt.h. (опрос состояния регистра в цикле не подходит, низкая надежность и скорость метода). Данной библиотеки, как я понял, в стандартных библиотеках си линукс нет, однако, в linux headers есть linux/interrupt.h, для работы с которой требуется писать модуль ядра. Если писать модуль ядра, не получится использовать стандартные библиотеки. Вопрос, можно ли решить задачу без написания модулей ядра, и если нет, то подскажите пожалуйста, где искать аналоги обычных библиотек для модулей ядра, и возможно ли их найти.

 

Aleksis_92
()

Настройка linux под uSomiq (аналог BeagleBone Black)

Форум — Linux-hardware

Добрый день! Стоит следующая задача, есть uSomiq (практически ничем не отличается от BeagleBone Black - тот же процессор и тд). Необходимо «навесить» на него некоторые устройства, такие как ethernet контроллер, и другие. На данном этапе собрал под него Debian, все работает, промежуточная задача - изменение конфигурации ядра с целью изменения начальной конфигурации светодиодов. То есть изначально из 4 диодов два заняты на мерцание и индикацию mmc, мне надо освободить их от этих «должностей». Из под работающей системы сделать это не проблема, либо через /sys/class/leds, либо на языке си через обращение к регистрам GPIO напрямую. Но эти способы работают до перезагрузки, надо же настроить систему, что бы она при включении знала где что должно быть (в будущем надо каким то образом настроить связь выводов и драйверов различных устройств, которые будут «навешаны»). Добрые люди подсказали перед сборкой ядра поколдовать над файлами в папках /arch/arm/mach-omap2 и /arch/arm/boot/dts. Вот на этом месте хотел спросить совета по поводу какой либо литературы на этот счет, так как в этих папках на самом деле нашел файлы настроек, при изменении которых включаются/отключаются светодиоды по умолчанию, но там все далеко не так прозрачно и понятно, как хотелось бы. Если кто подскажет, где можно про это почитать поподробнее, и желательно нормальным русским языком, буду очень благодарен) ибо даже зная что искать, не получается сформулировать запрос в поисковик что бы получить внятный ответ. Хорошо бы найти какую нибудь книгу где был бы освещен данный вопрос. п.с. ещё насколько я понял может помочь файл uEnv.txt, вроде как в нем тоже можно задать начальные настройки, но опять же нормальных книг/статей не нашел где бы это подробно описывалось.

 ,

Aleksis_92
()

RSS подписка на новые темы