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
Linux串口驱动程序(3)-打开设备相关推荐
- Linux串口驱动程序(4)-数据发送
1.tty数据发送调用关系 怎么样才能找到发送数据所使用的函数呢?打开uart_register_driver函数,找到里面的tty_register_driver,转到定义,这里调用了tty_fop ...
- Linux串口驱动程序(1)-tty驱动程序架构
1.tty概念分析 在Linux系统中,终端是一类字符型设备,它包括多种类型,通常使用tty来简称各种类型的终端设备.由于串口也是一种终端,因此这里引入终端这个概念 串口终端(/dev/ttyS*) ...
- Linux串口驱动程序(6)-串口驱动实现
在Linux驱动开发中,一般都不会从0开始写,我们做的更多的是移植和修改,有时候还需要对驱动程序进行优化.当然具备移植.修改驱动能力的基础是能够读懂驱动程序,同时需要对这个驱动程序的核心功能非常了解. ...
- Linux内核深入理解中断和异常(8):串口驱动程序
Linux内核深入理解中断和异常(8):串口驱动程序 rtoax 2021年3月 /*** start_kernel()->setup_arch()->idt_setup_early_tr ...
- linux文件控制驱动程序,Linux设备驱动程序学习(6)-高级字符驱动程序操作[(3)设备文件的访问控制]...
Linux设备驱动程序学习(6) -高级字符驱动程序操作[(3)设备文件的访问控制] 提供访问控制对于一个设备节点来的可靠性来说有时是至关重要的.这部分的内容只是在open和release方法上做些修 ...
- linux两个进程同时打开串口,linux串口操作及设置详解
串口操作需要的头文件 #include /*标准输入输出定义*/ #include /*标准函数库定义*/ #include /*Unix标准函数定义*/ #include #include #inc ...
- Unix/Linux操作系统分析实验四 设备驱动: Linux系统下的字符设备驱动程序编程
Unix/Linux操作系统分析实验一 进程控制与进程互斥 Unix/Linux操作系统分析实验二 内存分配与回收:Linux系统下利用链表实现动态内存分配 Unix/Linux操作系统分析实验三 文 ...
- linux usbnet网络驱动,[技术资料]基于usb设备的linux网络驱动程序开发
1 引言 做为开放源代码 (open source) 运动重要组成部分,linux操作系统吸引了数以万计的程序员共同开发.由于linux比较完整的继承了各种unix版本的稳定和高效,并且克服和改进了传 ...
- Linux设备驱动程序 三 字符设备驱动
Linux设备驱动程序 三 字符设备驱动 笔记 第三章 字符驱动设备 本章会编写一个完整的字符设备,字符设备简单,易于理解, 名字是scull:Simple Caracter Utility for ...
最新文章
- CSS grid 的用法
- 自从用完 Gradle 后,有点嫌弃 Maven 了!
- 人本质要好,要善良,要真诚,有格局和胸怀,有能力,有眼光,能讲故事,能找到人,能搞到钱...
- vs2015上使用github进行版本控制
- Centos 6.5下的OPENJDK卸载和SUN的JDK安装、环境变量配置
- 开放原子超级链动态内核上线,十分钟可搭建一条区块链
- linux语言换成英语,把Linux的默认语言改为英语
- html5监听动画结束,js判断css动画是否完成 animation,transition
- webpack代理解决跨域
- Sps的content menu 和 smart-tag的问题
- 【机器学习】机器学习从零到掌握之十三 -- 教你理解Logistics回归之梯度上升算法
- 程序员的进阶课-架构师之路(6)-链表
- cfe刷机教程 斐讯k3_2019斐讯K3全版本免拆机免降级刷机教程
- 2016年考研数学一解析 ​​​
- php实现ps修图,ps皮肤处理精修方法
- 基于springboot编写的小程序幸运转盘抽奖功能
- Mac重装系统-使用Mac笔记本制作U盘启动盘
- L1-023 输出GPLT (20分) 给定一个长度不超过10000的、仅由英文字母构成的字符串。请将字符重新调整顺序,按GPLTGPLT....这样的顺序输出,并忽略其它字符。当然,四种字符(不区分
- np.array的axis进行横向纵向的求和运算
- Hard-Margin SVM(支持向量机)