Такая ситуация. Есть плата CAN интерфейс CompactPCI - cPCI-7841 (Adlink) Под неё производитель предлагает драйвера для ядра 2.6.25 У меня в системе стоит много сложных плат и они работают с более поздним ядром (3.0-3.5) поэтому проще притянуть cPCI-7841 к более поздней версии. Сам я драйвера под linux не писал и работал только с Qt, а производитель поддержку фактически не осуществляет. Приходится самому окунаться в проблему. Я попытался скомпилировать предоставленные ими драйвер и библиотеку под ядро 3.5.
В результате я получил:
make -C /lib/modules/3.5.0-17-generic/build SUBDIRS=/home/cPCI-7841/drvsrc modules
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-17-generic'
CC [M] /home/cPCI-7841/drvsrc/7841.o
/home/cPCI-7841/drvsrc/7841.c:442:2: error: unknown field 'ioctl' specified in initializer
/home/cPCI-7841/drvsrc/7841.c:442:2: warning: initialization from incompatible pointer type [enabled by default]
/home/cPCI-7841/drvsrc/7841.c:442:2: warning: (near initialization for 'fops.owner') [enabled by default]
make[2]: *** [/home/cPCI-7841/drvsrc/7841.o] Error 1
make[1]: *** [_module_/home/cPCI-7841/drvsrc] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-17-generic'
make: *** [default] Error 2
В строке 442 файла 7841.c я заменил ioctl на unlocked_ioctl. Появилась другая ошибка:
make -C /lib/modules/3.5.0-17-generic/build SUBDIRS=/home/cPCI-7841/drvsrc modules
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-17-generic'
CC [M] /home/cPCI-7841/drvsrc/isrdpc.o
/home/cPCI-7841/drvsrc/isrdpc.c: In function 'adl_kill_fasync':
/home/cPCI-7841/drvsrc/isrdpc.c:265:25: error: 'POLL_IN' undeclared (first use in this function)
/home/cPCI-7841/drvsrc/isrdpc.c:265:25: note: each undeclared identifier is reported only once for each function it appears in
make[2]: *** [/home/cPCI-7841/drvsrc/isrdpc.o] Error 1
make[1]: *** [_module_/home/cPCI-7841/drvsrc] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-17-generic'
make: *** [default] Error 2
Для борьбы с этой ошибкой по совету добавил #include <linux/sched.h> в файл isrdpc.c
В результате все собралось без ошибок. Достаточно ли этих изменений для нормальной работы драйвера?
Дальше я по инструкции инсталлировал библиотеку и устройство:
cpci@cpci-dsp ~/cPCI-7841/driver $ sudo ./7841_inst.pl 1
[sudo] password for cpci:
make character device node '/dev/PCI7841W0' for PCI7841
cpci@cpci-dsp ~/cPCI-7841/lib $ sudo cp libpci_7841.so /usr/lib/
При компиляции кода, тестирующего плату получаю следующее:
cpci@cpci-dsp ~/cPCI-7841/sample $ make clean
rm -f *.o *~ test7841
cpci@cpci-dsp ~/cPCI-7841/sample $ make
gcc -c -Wall -Wstrict-prototypes -I../include test7841.c
gcc -c -Wall -Wstrict-prototypes -I../include conio.c
gcc -o test7841 -lpci_7841 test7841.o conio.o
test7841.o: In function `main':
test7841.c: (.text+0x21): undefined reference to `CanOpenDriver'
test7841.c: (.text+0x5a): undefined reference to `CanOpenDriver'
test7841.c: (.text+0x8b): undefined reference to `CanClearRxBuffer'
test7841.c: (.text+0x97): undefined reference to `CanClearTxBuffer'
test7841.c: (.text+0xa3): undefined reference to `CanClearRxBuffer'
test7841.c: (.text+0xaf): undefined reference to `CanClearTxBuffer'
test7841.c: (.text+0xe4): undefined reference to `CanConfigPort'
test7841.c: (.text+0xf9): undefined reference to `CanConfigPort'
test7841.c: (.text+0x1e7): undefined reference to `CanSendMsg'
test7841.c: (.text+0x20b): undefined reference to `CanSendMsg'
test7841.c: (.text+0x230): undefined reference to `CanGetRcvCnt'
test7841.c: (.text+0x241): undefined reference to `CanGetRcvCnt'
test7841.c: (.text+0x291): undefined reference to `CanRcvMsg'
test7841.c: (.text+0x2dd): undefined reference to `CanRcvMsg'
test7841.c: (.text+0x576): undefined reference to `CanCloseDriver'
test7841.c: (.text+0x583): undefined reference to `CanCloseDriver'
collect2: error: ld returned 1 exit status
make: *** [test7841] Error 1
Линковщик не смог связать функции. То есть по каким то причинам не инсталлировался драйвер при работе 7841_inst.pl или ошибка в другом?