首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

打通linux的tty驱动的数据链路

打通linux的tty驱动的数据链路




{
……
while((head = tty->buf.head) != NULL) {
………
count= head->commit – head->read;
………
char_buf= head->char_buf_ptr + head->read;
flag_buf= head->flag_buf_ptr + head->read;
head->read+= count;
disc->ops->receive_buf(tty,char_buf,
flag_buf,count);
………
}
……
}
这个函数主要的功能是,从tty_buffer中找到数据缓冲区char_buf_ptr,并将这个缓冲区指针传递给线路规程的操作函数receive_buf.再来看receive_buf:
static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char*cp,
char *fp, int count)
{
……
if(tty->real_raw) {
………
memcpy(tty->read_buf+ tty->read_head, cp, i);
………
}else{
………
switch(flags) {
caseTTY_NORMAL:
n_tty_receive_char(tty,*p);
break;
……
}
if(tty->ops->flush_chars)
tty->ops->flush_chars(tty);
………
}
………
}
从上面这段代码可以看到,if条件成立,明显地是拷贝数据进tty的read_buf;进入else,在正常的状态下会调用n_tty_receive_char,然后会调用put_tty_queue,在这个函数里最终还是把数据拷贝到tty的read_buf中。
到此,tty驱动的读操作数据链路基本上连通了。
uart_write:
static int uart_write(struct tty_struct *tty,
const unsigned char *buf, int count)
{
……
port= state->uart_port;
circ= &state->xmit;
……
while(1){
c= CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
………
memcpy(circ->buf+ circ->head, buf, c);
………
}
……
uart_start(tty);
return ret;
}
上面代码的意思是把要写的数据拷贝到state的缓冲区里。然后调用uart_start.
static void __uart_start(struct tty_struct *tty)
{
struct uart_state *state = tty->driver_data;
struct uart_port *port = state->uart_port;
if(!uart_circ_empty(&state->xmit) && state->xmit.buf&&
!tty->stopped && !tty->hw_stopped)
port->ops->start_tx(port);
}
调用了uart_port的操作函数集的start_tx.
static void serial8250_start_tx(struct uart_port *port)
{
struct uart_8250_port *up = container_of(port, struct uart_8250_port, port);
……
transmit_chars(up);
………
}
在transmit_chars中会把state->xmit缓冲区的数据写进串口发送数据寄存器,也就是数据到达硬件层。到此,写操作的数据链路也连通。
返回列表