25.3.1 USB串口驱动
USB串口驱动关键是向内核注册串口设备结构,并且设置串口的操作。下面是一个典型的USB设备驱动分析。
1.驱动初始化函数
usb_serial_init()函数是一个典型的USB设备驱动初始化函数,定义如下:
static int __init usb_serial_init(void)
{
int i;
int result;
usb_tty_driver = alloc_tty_driver(SERIAL_TTY_MINORS); // 申请tty设备驱动描述
if (!usb_tty_driver)
return - ENOMEM;
result = bus_register(&usb_serial_bus_type); // 注册总线
if (result)
{
err("Regist bus driver failed");
goto exit_bus;
}
/* 初始化串口驱动描述 */
usb_tty_driver->owner = THIS_MODULE;
usb_tty_driver->driver_name = "usbserial"; // 串口驱动名称
usb_tty_driver->devfs_name = "usb/tts/"; // 设备文件系统存放路径
usb_tty_driver->name = "ttyUSB"; // 串口设备名称
usb_tty_driver->major = SERIAL_TTY_MAJOR; // 串口设备主设备号
usb_tty_driver->minor_start = 0; // 串口设备从设备号起始ID
usb_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; // 设备类型
usb_tty_driver->subtype = SERIAL_TYPE_NORMAL; // 设备子类型
usb_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; // 设备初始化标志
usb_tty_driver->init_termios = tty_std_termios; // 串口设备描述
usb_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; // 串口设备初始化参数
tty_set_operations(usb_tty_driver, &serial_ops); // 串口设备操作函数
result = tty_register_driver(usb_tty_driver); // 注册串口驱动
if (result)
{
err("Regist tty driver failed");
goto exit_reg_driver;
}
result = usb_register(&usb_serial_driver); // 注册USB驱动
if (result < 0)
{
err("Register driver failed");
goto exit_tty;
}
return result;
/* 失败处理 */
exit_generic:
usb_deregister(&usb_serial_driver); // 注销串口设备
exit_tty:
tty_unregister_driver(usb_tty_driver); // 注销USB串口设备
exit_reg_driver:
bus_unregister(&usb_serial_bus_type); // 注销总线
exit_bus:
err("Error Code: %d", result);
put_tty_driver(usb_tty_driver);
return result;
}
函数首先调用alloc_tty_driver()函数分配一个串口驱动描述符;然后设置串口驱动的属性,包括驱动的主从设备号、设备类型、串口初始化参数等;串口驱动描述符设置完毕后,调用usb_register()函数注册USB串口设备。
2.驱动释放函数
驱动释放函数用来释放USB串口设备驱动申请的内核资源,函数定义如下:
static void _ _exit usb_serial_exit(void)
{
usb_serial_console_exit();
usb_serial_generic_deregister();
usb_deregister(&usb_serial_driver); //注销USB设备驱动
tty_unregister_driver(usb_tty_driver); //注销串口设备
put_tty_driver(usb_tty_driver); //减少引用计数
bus_unregister(&usb_serial_bus_type); //注销总线
}
3.串口操作函数
USB串口设备驱动使用了一个tty_operations类型的结构,该结构包含了串口的所有操作,定义如下:
static struct tty_operations serial_ops =
{
.open = serial_open, // 打开串口
.close = serial_close, // 关闭串口
.write = serial_write, // 串口写操作
.write_room = serial_write_room,
.ioctl = serial_ioctl, // I/O控制操作
.set_termios = serial_set_termios, // 设置串口参数
.throttle = serial_throttle,
.unthrottle = serial_unthrottle,
.break_ctl = serial_break, // break信号处理
.chars_in_buffer = serial_chars_in_buffer, // 缓冲处理
.read_proc = serial_read_proc, // 串口读操作
.tiocmget = serial_tiocmget, // 获取I/O控制参数
.tiocmset = serial_tiocmset, // 设置I/O控制参数
};
serial_ops结构变量设置的所有串口操作函数,均使用内核USB核心提供的标准函数,定义在drivers/usb/serial/generic.c文件中。