현재 다음에서 제공되는 Linux USB UART 드라이버를 컴파일하려고 합니다. http://www.exar.com/connectivity/uart-and-bridging-solutions/usb-uarts/xr21v1410
드라이버는 2개의 헤더 파일과 1개의 대형 C 파일로 구성됩니다. Makefile의 내용은 다음과 같습니다.
obj-m := vizzini.o
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
EXTRA_CFLAGS := -DDEBUG=0
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD)
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions vtty
make를 실행할 때 컴파일러에서 발생하는 오류는 다음과 같습니다.
[sj755@localhost xr21v141x-lnx-2.6.35-pak]$ make
make -C /lib/modules/3.4.9-2.fc16.x86_64/build M=/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak
make[1]: Entering directory `/usr/src/kernels/3.4.9-2.fc16.x86_64'
LD /home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/built-in.o
CC [M] /home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.o
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c:1643:9: warning: initialization from incompatible pointer type [enabled by default]
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c:1643:9: warning: (near initialization for ‘vizzini_device.ioctl’) [enabled by default]
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c:1646:9: warning: initialization from incompatible pointer type [enabled by default]
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c:1646:9: warning: (near initialization for ‘vizzini_device.tiocmget’) [enabled by default]
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c:1647:9: warning: initialization from incompatible pointer type [enabled by default]
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c:1647:9: warning: (near initialization for ‘vizzini_device.tiocmset’) [enabled by default]
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c: In function ‘vizzini_init’:
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c:1663:9: error: implicit declaration of function ‘usb_serial_register’ [-Werror=implicit-function-declaration]
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c:1677:9: error: implicit declaration of function ‘usb_serial_deregister’ [-Werror=implicit-function-declaration]
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c: In function ‘__check_debug’:
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c:1698:83: warning: return from incompatible pointer type [enabled by default]
cc1: some warnings being treated as errors
make[2]: *** [/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.o] Error 1
make[1]: *** [_module_/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak] Error 2
make[1]: Leaving directory `/usr/src/kernels/3.4.9-2.fc16.x86_64'
make: *** [all] Error 2
다음은 기본 C 소스 파일에 포함된 헤더입니다.
#include <linux/kernel.h>
#include <linux/jiffies.h>
#include <linux/errno.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include <linux/serial.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
#include <asm/uaccess.h>
#include <linux/usb/cdc.h>
#ifndef CDC_DATA_INTERFACE_TYPE
#define CDC_DATA_INTERFACE_TYPE 0x0a
#endif
#ifndef USB_RT_ACM
#define USB_RT_ACM (USB_TYPE_CLASS | USB_RECIP_INTERFACE)
#define ACM_CTRL_DTR 0x01
#define ACM_CTRL_RTS 0x02
#define ACM_CTRL_DCD 0x01
#define ACM_CTRL_DSR 0x02
#define ACM_CTRL_BRK 0x04
#define ACM_CTRL_RI 0x08
#define ACM_CTRL_FRAMING 0x10
#define ACM_CTRL_PARITY 0x20
#define ACM_CTRL_OVERRUN 0x40
#endif
#include "linux/version.h"
#include "vizzini.h"
Linux 커널 3.4.9-2.fc16.x86_64 실행
오류를 해결하는 데 도움을 주시면 매우 감사하겠습니다.
답변1
최신 버전의 Linux 커널에서는 usb_serial_register
및 usb_serial_deregister
기능이 정적으로 만들어졌습니다. 따라서 이러한 함수는 커널 개체 파일에 텍스트 형식으로만 존재합니다. 대신 및 를 사용할 수 있습니다 usb_serial_register_drivers
.usb_serial_deregister_drivers
다음은 두 가지 함수 집합에 대한 정의입니다.
int usb_serial_register(struct usb_serial_driver *driver);
void usb_serial_deregister(struct usb_serial_driver *device);
int usb_serial_register_drivers(struct usb_driver *udriver,
struct usb_serial_driver * const serial_drivers[]);
void usb_serial_deregister_drivers(struct usb_driver *udriver,
struct usb_serial_driver * const serial_drivers[]);
usb_serial_register_drivers
등록할 USB 직렬 드라이버와 장치/인터페이스와 일치하는 usb_driver에 대한 NULL로 끝나는 포인터 배열입니다. 두 기능 세트에 대한 자세한 내용은 여기에서 확인할 수 있습니다.
http://lxr.free-electrons.com/source/drivers/usb/serial/usb-serial.c?v=3.4#L1379
http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/drivers/usb/serial/usb-serial.c#L1337
드라이버의 소스 코드에서 다음과 같은 줄이 있습니다.
retval = usb_serial_register(&vizzini_device);
다음으로 대체됩니다:
struct usb_serial_driver *serial_drivers[2] = {&vizzini_device,NULL};
retval = usb_serial_register_drivers(&vizzini_driver,serial_drivers);
vizzini_driver 및 vizzini_device는 다음과 같이 코드의 다른 곳에서 정의됩니다.
static struct usb_driver vizzini_driver = {
.name = "vizzini",
.probe = usb_serial_probe,
.disconnect = vizzini_disconnect,
.id_table = id_table,
.no_dynamic_id = 1,
};
static struct usb_serial_driver vizzini_device = {
.driver = {
.owner = THIS_MODULE,
.name = "vizzini",
},
.usb_driver = &vizzini_driver,
.description = "Vizzini USB serial port",
.id_table = id_table,
.calc_num_ports = vizzini_calc_num_ports,
.probe = vizzini_probe,
.open = vizzini_open,
.close = vizzini_close,
.write = vizzini_write,
.write_room = vizzini_write_room,
.ioctl = vizzini_ioctl,
.set_termios = vizzini_set_termios,
.break_ctl = vizzini_break_ctl,
.tiocmget = vizzini_tiocmget,
.tiocmset = vizzini_tiocmset,
.attach = vizzini_attach,
.disconnect = vizzini_serial_disconnect,
.release = vizzini_serial_release,
.read_int_callback = vizzini_int_callback,
};
답변2
커널 내부의 API는 안정적이지 않으므로 드라이버가 커널 소스와 거의 동일하지 않으면 작동하지 않습니다(그리고 사용자가 제공한 경고/오류 메시지는 정확한 방향을 가리킵니다). 대부분의 트리 외부 드라이버는 형편없는 코드이므로 가볍게 받아들이십시오. 현재 커널이 공식적으로 또는 임시 드라이버에서 이를 지원하는지 확인하십시오. 확인하다리눅스-USB, 거기에서 몇 가지 지침을 찾을 수 있습니다.