Linux驱动程序--串口
文章摘要: 本文主要描述了基于串口驱动程序框架下,新建虚拟串口设备,不涉及硬件内容。
内核版本: Linux-3.8.13
注册串口驱动
// 串口驱动结构
static struct uart_driver serial_driver = {
.owner = THIS_MODULE,
.driver_name = DRIVER_NAME, // 驱动程序名称
.dev_name = DEV_NAME, // 设备文件称 ttyVn
.nr = 20, // 驱动程序支持串口的最大数量
//.cons = &serial_console, // 关连控制台
};
// 声明端口列表:端口列表应该放在设备私有数据中,
// 这里为了简单说明,采用了全局变量,
// 实际应用中不建议这么干
// 否则当多个驱动多个设备时,会出现严重问题。
static uart_port port[4];
// 注册串口驱动
ret = uart_register_driver(&serial_driver);
// 添加多个端口,port->line来表示端口号,端口号不能重复,
// 几个相同设备共用一个驱动时,这里需注意调整;
for(i = 0; i < 4; i++)
{
port.line = i; // 端口号
port.ops = serial_port_ops; // 端口操作回调列表(后面详细说明)
port.type = PORT_EFMUART; // 端口类型
port.iotype = UPIO_MEM32; // 32bit寄存器
port.fifosize = 128; // 发送FIFO深度
port.flags = UPF_BOOT_AUTOCONF; // 标志
// 添加端口(正常情况下返回0)
ret = uart_add_one_port(&serial_driver, &port[i]);
}
此步操作后,将可以在设备目录下看到生成的4个串口设备。
移除设备
// 删除端口
for(i = 0; i < 4; i++)
{
uart_remove_one_port(&serial_driver, &port[i]);
}
// 注销串口驱动
uart_unregister_driver(&serial_driver);
端口操作回调函数说明:
static struct uart_ops serial_port_ops = {
.tx_empty = is_tx_empty, // 测试发送FOFI是否空
.set_mctrl = serial_set_mctrl, // 硬件握手用
.get_mctrl = serial_get_mctrl, // 硬件握手用
.stop_tx = serial_stop_tx, // 函数调用
.start_tx = serial_start_tx, // write时调用
.stop_rx = serial_stop_rx, //
.enable_ms = serial_enable_ms,
.break_ctl = serial_break_ctl,
.startup = serial_startup, // open时调用
.shutdown = serial_shutdown, // close时调用
.set_termios = serial_set_termios, // 设置参数,open时第2步调用
.type = serial_type,
.release_port = serial_release_port,// 移除端口时调用
.request_port = serial_request_port,
.config_port = serial_config_port, // 超级重要
.verify_port = serial_verify_port,
};
/*
* 非常重要,添加端口后,自动调用的第一个回调函数
* 如果不这里设置的值,则串口不会正常工作
*/
static void serial_config_port(struct uart_port *port, int type)
{
port->type = PORT_EFMUART;
}