您的位置:首页 > 其它

嵌入式学习-驱动开发-lesson6.3-UART驱动send和receive流程分析

2016-08-04 21:59 766 查看

四、串口驱动分析–数据发送

本课需要解决的知识点是:

1.当使用write系统调用时,是如何一步一步传递到串口驱动来的,

2.当串口驱动接收到来自用户空间的发送数据请求后,如何实现发送

1)TTY数据发送调用关系









tty_write又调用线路规程中的n_tty_write





在n_tty_write中,





在uart_write函数中,又会调用uart_start



uart_start调用__uart_start函数,







上面的函数调用关系,总结如下:



s3c24xx_serial_start_tx这个函数将是我们的发送函数,接下来我们需要了解这个函数是怎么实现的。



如果tx_enabled没有被打开,则使能中断,打开tx_enabled,但是这里面并没有数据的发送??,原因是在前面串口的打开即open 一章中介绍过,有发送中断和接收中断,当中断打开之后,如果有fifo数据,则在中断处理函数中,进行数据的接收和发送。

start_tx起到激活中断,使能中断的作用,在中断处理程序中完成数据的发送

找到中断处理程序:



发送中断处理程序s3c24xx_serial_tx_chars



发现发送数据寄存器S3C2410_UTXH,说明中断处理程序完成数据的发送。

也就是说,write函数经过一系列调用,找到了start_tx函数,start_tx激活中断,然后驱动程序里面的中断处理程序,完成数据的发送。

问题来了,数据从哪里来的?

在串口中有一个重要的部分—循环缓冲,tty会把数据放到循环缓冲里面,当触发发送中断时,中断处理程序会从循环缓冲里面把数据取走。



如果循环缓冲不为空,则从中取出数据,并发送。

那么,数据是如何送进循环缓冲的?

在uart_write函数,可以看到buf是在这个函数里面写进去的,



上图中的buf是从应用程序中传递过来的,

然后uart_write会通过memcpy把buf写到循环缓冲里面去,如下



循环缓冲的结构如下:



言归正传,开始分析串口中断处理处理程序之发送函数s3c24xx_serial_tx_chars函数:



发送xon标志,代表可以开始接受数据。即:



循环缓冲为空,或者串口停止发送,则调用s3c24xx_serial_stop_tx来关闭中断



发送缓冲不为空,发送数据,



最多一次性发送256个字符

循环发送数据 条件:循环缓冲有数据 最多发送256个数据

在这个循环函数中,主要是做了三项工作



1.当发送fifo满的时候,退出发送

2.从循环缓冲中取出数据,写入UTXH寄存器

3.调整循环缓冲位置



数据量< 256时,唤醒在发送之前阻塞的进程



如果循环缓冲为空,则关闭中断



综合以上流程,可以得知,uart_write会把用户空间的数据写到循环buf里面去, 驱动里面的start_tx会激活发送中断,从而调用发送中断处理函数,发送中断处理函数会从循环buf取出数据,通过一系列检验过程,最终把数据传送到串口,这便是串口的数据发送过程。

五、 串口驱动分析–数据接收

1)数据接收过程

数据的接收和上面数据的发送过程基本一致,下面开始分析:

29



tty_read响应read系统调用,



调用线路规程里面的read,即n_tty_read



在n_tty_read函数中,做了下面几项工作:



将当前的状态设置为TASK_INTERRUPTIBLE状态,可中断阻塞态



如果没有数据可读,通过调度让阻塞失效。



如果有数据,从read_buf中读走数据

上面便是接收数据函数之间的调用关系,流程图如下:



问题来了,read_buf中的数据从哪里来的?下面分析中断处理接收函数,便可以得到答案,

2)串口接收数据分析

在串口接收终端处理函数s3c24xx_serial_rx_chars中,做了一下几个工作

36




读取UFCON寄存器

读取UFSTAT寄存器



如果接收fifo里面的数据量为0,退出



读取UERSTAT寄存器,

从URXH取出接收到字符



进行流控处理



根据UERSTAT的值,记录具体的错误类型



如果接收到的是sysrq字符,进行特殊处理uart_handle_sysrq_char



把接收到的字符放到串口驱动的bufuart_insert_char



把串口驱动接收到的数据送进线路规程的read_buf -tty_flip_buffer_push

综合以上可以得知,在中断处理接收函数中,进行数据的接收,并将接收到的数据放到read_buf中去,而线路规程中的n_tty_read函数,则从read_buf中读走数据。over

下面是具体流程图



菜鸟一枚,如有错误,多多指教。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: