串口驱动相关数据结构
struct uart_driver; //串口驱动结构
struct uart_port; //端口结构,串口驱动只有一个,端口却有多个,一个端口对应一个实际的串口
struct uart_ops; //函数操作集
struct uart_state; //状态结构
struct uart_info; //串口信息结构
数据结构详细介绍进此:http://www.cnblogs.com/hello2mhb/p/3341291.html
(一)初始化串口流程
~~~~~~~~ 《samsung.c》文件中对串口进行了初始化。
- 注册:
uart_register_driver
初始化:
2.1 取出uart_port
2.2 初始化uart_port:获取硬件地址->获取中断编号->复位串口FIFO
2.3 添加端口(串口):
2.4 创建属性文件:
uart_add_one_port
device_create_file
,在/sys目录下创建相应的属性文件
2.5 初始化动态频率调节:
s3c24xx_serial_cpufreq_register
(二)打开设备流程
~~~~~~~~ 《samsung.c》文件中:对串口进行了打开。
s3c24xx_serial_startup
- 使能接收:
rx_enabled
- 注册接收中断:
request_irq
- 使能发送:
tx_enabled
- 注册发送中断:
request_irq
(三)数据发送流程
~~~~~~~~ 读写数据会用到循环缓冲,在uart_write函数中将用户的数据写入到循环缓冲中,在
s3c24xx_serial_tx_chars
,函数中将循环缓冲中的数据写入到寄存器。
《tty_io.c》文件中如下定义:
static ssize_t tty_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
函数调用流程:
tty_write ——> do_tty_write ——> copy_from_user /*通过此调用流程完成写数据操作*/
串口发送数据中断处理函数: s3c24xx_serial_tx_chars
- 先发送一个标志,相当于串口和PC的通知,例如串口询问PC是否可以开始发送,PC回应我现在有数据而且还没处理完,你先等等。
![]()
嵌入式Linux之串口驱动结构 - 判断循环缓冲或者串口状态是否可以发送
![]()
嵌入式Linux之串口驱动结构 - 利用循环缓冲写入数据,一次中断最多发送256个字符(count=256)
![]()
嵌入式Linux之串口驱动结构 3.1 判断发送FIFO时候是空的
3.2 如果FIFO为空,从循环缓冲中取出数据开始写入,否则退出写入
3.3 调整循环缓冲的位置
- 计算循环缓冲数据量,如果循环缓冲中的数据低于某个数量(这里是256),通知应用程序可再次往串口写入。(就是唤醒之前发送时阻塞的进程)
![]()
嵌入式Linux之串口驱动结构 - 判断循环缓冲的数据,如果为空,关闭发送中断
![]()
嵌入式Linux之串口驱动结构
(四)数据接收流程
串口接收数据中断处理函数:~
s3c24xx_serial_rx_chars
- 读取寄存器
![]()
嵌入式Linux之串口驱动结构 - 检测FIFO数据量,如果为0,退出读取
![]()
嵌入式Linux之串口驱动结构 - 读取寄存器UERSTAT,从URXH,读取接收到的字符
![]()
嵌入式Linux之串口驱动结构 - 流控
![]()
嵌入式Linux之串口驱动结构 - 根据UERSTAT寄存器记录错误类型
- 如果收到sysrq字符,进行特殊处理
- 将接收到的字符送入串口驱动
- 把串口驱动收到的数据送入线路规程