Решено: базовый адрес PCI плат

Модератор: Модераторы разделов

drifterlom
Сообщения: 34

Решено: базовый адрес PCI плат

Сообщение drifterlom »

Как определить базовый адрес I/O. В документации на платы расписаны все адреса относительно базового.
Спасибо сказали:
voidius
Сообщения: 59
ОС: Arch Linux

Re: Решено: базовый адрес PCI плат

Сообщение voidius »

а в /proc/ioports нету?
Спасибо сказали:
drifterlom
Сообщения: 34

Re: Решено: базовый адрес PCI плат

Сообщение drifterlom »

Там что-то есть, но понять сложно. Перед тем как кидать сюда куски из файла.
Я пытаюсь настроить управление механизмом из Линукс через PCI платы ЦАП и АЦП.
Скачал РТ-ядро и врубил его. Как писать модули для него научисля. Теперь задача научиться общаться с платами. Сначала хочу из-под стандартного ядра Линукс хоть что-нибудь прочитать и записать в порты плат.
В документации расписаны адреса смещений для всех каналов но относительно базового.
Теперь мне нужно программно найти этот базовый адрес и все должно полететь.
Вот и спросил. Скажите что еще рассказать чтобы надеяться на помощь
Заранее благодарю
Спасибо сказали:
Аватара пользователя
deadhead
Сообщения: 1913
Статус: zzz..z

Re: Решено: базовый адрес PCI плат

Сообщение deadhead »

[x] close
Спасибо сказали:
voidius
Сообщения: 59
ОС: Arch Linux

Re: Решено: базовый адрес PCI плат

Сообщение voidius »

тогда может быть здесь? 6 глава про PCI и там что-то про Base Address есть...

А, ну вторая ссылка по ссылке от deadhead оно и есть )
Спасибо сказали:
Аватара пользователя
Alxn1
Сообщения: 402
Статус: Красноглазик со стажем
ОС: Mavericks

Re: Решено: базовый адрес PCI плат

Сообщение Alxn1 »

http://ru.wikipedia.org/wiki/PCI_configuration_space

Смотреть Base Address Registers. Перед непосредсвенным использованием сначало надо проинициализировать устройство (что бы оно на ввод-вывод по портам начало реагировать) и отобразить эти регистры в память (хотя, многие драйвера в Linux через in/out с этим делом работают, я видел. С другой стороны, такой мапинг и не каждое устройство, вроде, умеет, но в любом случае, через in/out порты станут доступны). Все это делается с помощью функций с префиксами pci_* в ядре, если я ничего не путаю.
Спасибо сказали:
drifterlom
Сообщения: 34

Re: Решено: базовый адрес PCI плат

Сообщение drifterlom »

voidius и Alxn1 спасибо.
deadhead спасибо, теперь я научился пользоваться ранее неизвестным сайтом www.google.ru. Неоценимая помощь.
Спасибо сказали:
ssh
Сообщения: 78
ОС: Debian

Re: Решено: базовый адрес PCI плат

Сообщение ssh »

если неизбежно писать модуль ядра - то так:

Код: Выделить всё

#include <linux/pci.h>
PCI_card = pci_find_device( pci_vendor, pci_device, NULL );
pci_enable_device( PCI_card );
pci_read_config_byte( PCI_card, PCI_INTERRUPT_LINE, &b );
                                                         DEV_irq = b;
pci_read_config_word( PCI_card, PCI_BASE_ADDRESS_1, &w );
                               if( w & 1 ) w ^= 1;  DEV_port = w;
pci_read_config_word( PCI_card, PCI_BASE_ADDRESS_2, &w );
                                   if( w & 1 ) w ^= 1;  DEV_port1 = w;



а в user-space'е так:

Код: Выделить всё

FILE *f = fopen( "/proc/bus/pci/devices", "r");

int ident, base;

ident = PCI_VENDOR;
ident <<= 16;
ident |= PCI_ID;

while( 1 )
  {
   char s[ 1000 ];

   if( fgets( s, sizeof( s ), f ) == NULL )
    {
     ident = 0;
     return ENODEV;
    }
    else
    {
      int a = 0, b = 0;
          sscanf( s,"%x%x%x%x%x%x", &a, &b, &a, &a, &a, &base );
      if( b == ident )
       {
         base |= 1; base ^= 1;
             break;
       }
    }
Спасибо сказали:
drifterlom
Сообщения: 34

Re: Решено: базовый адрес PCI плат

Сообщение drifterlom »

Написал (точнее списал) такую вот прогу из под user space дабы выдать хоть что-нибудь на плату

Код: Выделить всё

#include <stdio.h>
#include <sys/io.h>

int main(void)
{

FILE *f = fopen( "/proc/bus/pci/devices", "r");
int ident, base, sig_out;

ident = 0x10b5;
ident <<= 16;
ident |= 0x9054;

while( 1 )
  {
   char s[ 1000 ];

   if( fgets( s, sizeof( s ), f ) == NULL )
    {
     ident = 0;
     return 0;
    }
    else
    {
      int a = 0, b = 0;
          sscanf( s,"%x%x%x%x%x%x", &a, &b, &a, &a, &a, &base );
      if( b == ident )
       {
         base |= 1; base ^= 1;
         printf("base=%x\n",base);
         printf("b=%x\n",b);
             break;
       }
    }
sig_out=1000;
while(1)
 {
 outl(base+0x0E, sig_out);
 sleep(1);
 }

}
return 0;
}


адрес он определяет правильно, т.е то же самое что и lspci -v -d vendor:id
но при попытке записи туда значения пишет

Код: Выделить всё

Segmentation fault

В мануале на плату написано как то так
 Offset CPCI/PCI-           cPCI/PCI-
                  PCI-6216V
Address  6208V               6208A
 0x00      V0         V0     V0 / A0
 0x02      V1         V1     V1 / A1
 0x04      V2         V2     V2 / A2
 0x06      V3         V3     V3 / A3
 0x08      V4         V4     V4 / A4
 0x0A      V5         V5     V5 / A5
 0x0C      V6         V6     V6 / A6
 0x0E      V7         V7     V7 / A7
 0x10      --         V8       --
 0x12      --         V9       --
 0x14      --        V10       --
 0x16      --        V11       --
 0x18      --        V12       --
 0x1A      --        V13       --
 0x1C      --        V14       --
 0x1E      --        V15       --


т.е.я так понял что для канала V0 смещения нет
не понимаю почему не работает =(
Спасибо сказали:
Аватара пользователя
Alxn1
Сообщения: 402
Статус: Красноглазик со стажем
ОС: Mavericks

Re: Решено: базовый адрес PCI плат

Сообщение Alxn1 »

http://linux.die.net/man/2/outl - видимо, прав нет. Попробуйте от рута стартануть программу. Хотя я хз, я в userspace ничего такого никогда не делал.
Спасибо сказали:
ssh
Сообщения: 78
ОС: Debian

Re: Решено: базовый адрес PCI плат

Сообщение ssh »

Так, вопрос-то был только про определение адреса )

А если что-то в PCI и писать хотим, тогда при инициализации программы (скажем, после того как плату нашли, но до первой попытки с нею общения) надо вставить что-то типа

Код: Выделить всё

 if( iopl( 3 ) )
  {
   return errno;
  }


Дальше, к базовому адресу прибавляем указанное в документации смещение и общаемся с платой командами типа inb/outb и им подобными; опять же, под руководством документации. (Для этого заголовках не забываем #include <sys/io.h>). Ну и все это запускаться должно, действительно, от имени root'а.
Спасибо сказали:
drifterlom
Сообщения: 34

Re: Решено: базовый адрес PCI плат

Сообщение drifterlom »

Так ничего и не вышло
различными способами находит два базовых адреса. И как описано ssh из модуля ядра и из user's space.
в мануале написано нулевое смещение для первого канала.
Попытка outw(base+0x00, 0x4000) ничего не дает.
0х4000 это величина соответствующая +5 В на выходе.

iopl (3) вызывал. до этого писал ошибка сигментации, теперь перестал но все равно эффекта нет.

скажите, из модуля ядра как правильно общаться с адресами ввода/вывода. мож из модуля чего получится
Спасибо сказали:
drifterlom
Сообщения: 34

Re: Решено: базовый адрес PCI плат

Сообщение drifterlom »

все, работает. пишите решено

P.S. ssh - спасибо большое , полезность советов стопроцентная.
Спасибо сказали: