Linux串口驱动程序(3)-打开设备

简介: Linux串口驱动程序(3)-打开设备先来分析一下串口打开的过程:1、用户调用open函数打开串口设备文件;2、在内核中通过tty子系统,把open操作层层传递到串口驱动程序中;3、在串口驱动程序中的xx_open最终实现这个操作。

Linux串口驱动程序(3)-打开设备
先来分析一下串口打开的过程:

1、用户调用open函数打开串口设备文件;
2、在内核中通过tty子系统,把open操作层层传递到串口驱动程序中;
3、在串口驱动程序中的xx_open最终实现这个操作。
这里主要有2个点需要我们重点分析,一个是open函数的传递过程,而是串口驱动程序XXX_open函数的实现。

1.open函数传递

打开uart_register_driver函数,里面就是实现注册串口驱动,在最后有一个tty_register_driver函数,这个函数实际上就是注册一个字符设备。在注册过程中有一个重要的结构:
static const struct file_operations tty_fops = {

.llseek        = no_llseek,
.read        = tty_read,
.write        = tty_write,
.poll        = tty_poll,
.unlocked_ioctl    = tty_ioctl,
.compat_ioctl    = tty_compat_ioctl,
.open        = tty_open,
.release    = tty_release,
.fasync        = tty_fasync,

};
这就是tty_fops结构,里面的tty_open就是响应用户的open操作的。这这个open函数里面肯定不是直接完成串口打开的,它调用了uart_ops里面的open函数:
static const struct tty_operations uart_ops = {

.open        = uart_open,
.close        = uart_close,
.write        = uart_write,
.put_char    = uart_put_char,
.flush_chars    = uart_flush_chars,
.write_room    = uart_write_room,
.chars_in_buffer= uart_chars_in_buffer,
.flush_buffer    = uart_flush_buffer,
.ioctl        = uart_ioctl,
.throttle    = uart_throttle,
.unthrottle    = uart_unthrottle,
.send_xchar    = uart_send_xchar,
.set_termios    = uart_set_termios,
.set_ldisc    = uart_set_ldisc,
.stop        = uart_stop,
.start        = uart_start,
.hangup        = uart_hangup,
.break_ctl    = uart_break_ctl,
.wait_until_sent= uart_wait_until_sent,

ifdef CONFIG_PROC_FS

.proc_fops    = &uart_proc_fops,

endif

.tiocmget    = uart_tiocmget,
.tiocmset    = uart_tiocmset,

ifdef CONFIG_CONSOLE_POLL

.poll_init    = uart_poll_init,
.poll_get_char    = uart_poll_get_char,
.poll_put_char    = uart_poll_put_char,

endif

};
可以看到最终调用的是uart_open函数,这个函数中使用uart_startup(state, 0);实现串口的打开,这个最终又是由s3c24xx_serial_ops里面的s3c24xx_serial_startup函数来实现的。下面分析这个函数。
2.串口打开流程分析

static int s3c24xx_serial_startup(struct uart_port *port)
{

struct s3c24xx_uart_port *ourport = to_ourport(port);
int ret;

dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n",
    port->mapbase, port->membase);

rx_enabled(port) = 1;  // 使能接收

ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0,
          s3c24xx_serial_portname(port), ourport);   // 为数据接收注册中断程序

if (ret != 0) {
    printk(KERN_ERR "cannot get irq %d\n", ourport->rx_irq);
    return ret;
}

ourport->rx_claimed = 1;  // 使能发送

dbg("requesting tx irq...\n");

tx_enabled(port) = 1;

ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_chars, 0,
          s3c24xx_serial_portname(port), ourport);   // 为数据发送注册中断程序

if (ret) {
    printk(KERN_ERR "cannot get irq %d\n", ourport->tx_irq);
    goto err;
}

ourport->tx_claimed = 1;

dbg("s3c24xx_serial_startup ok\n");

/* the port reset code should have done the correct
 * register setup for the port controls */
if (port->line == 2) {
    s3c2410_gpio_cfgpin(S3C2410_GPH(6), S3C2410_GPH6_TXD2);
    s3c2410_gpio_pullup(S3C2410_GPH(6), 1);
    s3c2410_gpio_cfgpin(S3C2410_GPH(7), S3C2410_GPH7_RXD2);
    s3c2410_gpio_pullup(S3C2410_GPH(7), 1);
}
return ret;

err:

s3c24xx_serial_shutdown(port);
return ret;

}
它完成下面的工作:

1、使能接收rx_enabled
2、为数据接收注册中断程序request_irq
3、使能发送tx_enabled

4、为数据发送注册中断程序request_irq

作者:小虾米_2018
来源:CSDN
原文:https://blog.csdn.net/qq_22847457/article/details/91608501
版权声明:本文为博主原创文章,转载请附上博文链接!

相关文章
|
2月前
|
安全 Linux 网络虚拟化
Linux网络名称空间和Veth虚拟设备的关系
在讨论Linux网络名称空间和veth(虚拟以太网对)之间的关系时,我们必须从Linux网络虚拟化的核心概念开始。Linux网络名称空间和veth是Linux网络虚拟化和容器化技术的重要组成部分,它们之间的关系密不可分,对于构建隔离、高效的网络环境至关重要。😊
|
2月前
|
Cloud Native Linux 网络虚拟化
深入理解Linux veth虚拟网络设备:原理、应用与在容器化架构中的重要性
在Linux网络虚拟化领域,虚拟以太网设备(veth)扮演着至关重要的角色🌐。veth是一种特殊类型的网络设备,它在Linux内核中以成对的形式存在,允许两个网络命名空间之间的通信🔗。这篇文章将从多个维度深入分析veth的概念、作用、重要性,以及在容器和云原生环境中的应用📚。
深入理解Linux veth虚拟网络设备:原理、应用与在容器化架构中的重要性
|
15天前
|
Linux 程序员 芯片
【Linux驱动】普通字符设备驱动程序框架
【Linux驱动】普通字符设备驱动程序框架
|
25天前
|
Linux 芯片
Linux 驱动开发基础知识——查询方式的按键驱动程序_编写框架(十三)
Linux 驱动开发基础知识——查询方式的按键驱动程序_编写框架(十三)
14 2
|
4天前
|
存储 Linux
深入了解Linux设备管理:字符、块和网络设备文件
深入了解Linux设备管理:字符、块和网络设备文件
15 0
|
2月前
|
Linux Shell 开发者
|
28天前
|
传感器 物联网 Linux
物联网设备的操作系统之争:Linux vs RTOS
【6月更文挑战第4天】在遥远的数码星球,物联网城中的Linux先生与RTOS小姐展开激烈角逐,分别在操作系统领域各显神通。Linux先生以其开源、兼容性强、功能丰富占据服务器、桌面及嵌入式设备市场,适合处理复杂任务和需要强大计算能力的设备。而RTOS小姐以实时性、高效响应和低资源占用见长,适用于资源有限、强调实时性的物联网设备。设备制造商在两者间抉择,引发物联网设备操作系统的选择大战。通过Python与FreeRTOS示例,展现了两者在智能家居和生产线控制等场景的应用。在物联网世界,Linux与RTOS共同推动设备智能化,为生活带来更多便捷。
69 3
|
15天前
|
Linux
【Linux驱动学习(1)】USB与input子系统,linux统一设备模型,枚举,USB描述符深入剖析
【Linux驱动学习(1)】USB与input子系统,linux统一设备模型,枚举,USB描述符深入剖析
|
2月前
|
运维 Ubuntu 安全
运维最全linux 命令行操作串口_linux串口命令(2),2024年最新Linux运维源码的Binder权限是如何控制
运维最全linux 命令行操作串口_linux串口命令(2),2024年最新Linux运维源码的Binder权限是如何控制
运维最全linux 命令行操作串口_linux串口命令(2),2024年最新Linux运维源码的Binder权限是如何控制