linux 下串口读写,Linux下串口读写过程小析

open串口过程

static const struct file_operations tty_fops = {

.open= tty_open,

.read= tty_read,

.write= tty_write,

};

static struct tty_ldisc_ops n_tty_ops = {

.open = n_tty_open,

.read = n_tty_read,

.write = n_tty_write,

};

static const struct tty_operations uart_ops = {

.open= uart_open,

.write= uart_write,

};

static const struct uart_ops serial_sprd_ops = {

.stop_tx = sprd_stop_tx,

.start_tx = sprd_start_tx,

.stop_rx = sprd_stop_rx,

.set_termios = sprd_set_termios,

};

//open

static int tty_open(struct inode *inode, struct file *filp)

{

struct tty_struct *tty;

tty = tty_open_by_driver(device, inode, filp);

retval = tty->ops->open(tty, filp);----->

}

//寻找driver,比如有usb转串口driver,cpu的uart driver

static struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode,struct file *filp)

{

driver = tty_lookup_driver(device, filp, &index);

-->tty = tty_init_dev(driver, index);

tty = alloc_tty_struct(driver, idx);---->tty_ldisc_init(tty);

tty->ops = driver->ops;

retval = tty_driver_install_tty(driver, tty);

retval = tty_ldisc_setup(tty, tty->link);

}

static struct uart_driver sprd_uart_driver = {

.owner = THIS_MODULE,

.driver_name = "sprd_serial",

.dev_name = SPRD_TTY_NAME,

.major = 0,

.minor = 0,

.nr = UART_NR_MAX,

.cons = SPRD_CONSOLE,

};

static int uart_open(struct tty_struct *tty, struct file *filp)

{

retval = uart_startup(tty, state, 0);--->retval = uport->ops->startup(uport);

uart_change_speed(tty, state, NULL);--->uport->ops->set_termios(uport, termios, old_termios);

}

static const struct tty_operations uart_ops = {

.open= uart_open,

.write= uart_write,

};

int uart_register_driver(struct uart_driver *drv)

{

tty_set_operations(normal, &uart_ops);--->driver->ops = op;

}

串口发送过程

static ssize_t tty_write(struct file *file, const char __user *buf,size_t count, loff_t *ppos)

{

ret = do_tty_write(ld->ops->write, tty, file, buf, count);

}

static inline ssize_t do_tty_write(ssize_t (*write)(struct tty_struct *, struct file *, const unsigned char *, size_t),struct tty_struct *tty,struct file *file,const char __user *buf,size_t count)

{

ret = write(tty, file, tty->write_buf, size);--->n_tty_write

}

static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,const unsigned char *buf, size_t nr)

{

while (nr > 0) {

c = tty->ops->write(tty, b, nr);

}

}

static int uart_write(struct tty_struct *tty,const unsigned char *buf, int count)

{

while (1) {

c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);

if (count < c)

c = count;

if (c <= 0)

break;

memcpy(circ->buf + circ->head, buf, c);

circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);

buf += c;

count -= c;

ret += c;

}

__uart_start(tty);

}

static void __uart_start(struct tty_struct *tty)

{

port->ops->start_tx(port);

}

static void sprd_start_tx(struct uart_port *port)

{

unsigned int ien;

ien = serial_in(port, SPRD_IEN);

if (!(ien & SPRD_IEN_TX_EMPTY)) {

ien |= SPRD_IEN_TX_EMPTY;

serial_out(port, SPRD_IEN, ien);

}

}

//准备好了,把数据发过去

static irqreturn_t sprd_handle_irq(int irq, void *dev_id)

{

if (ims & SPRD_IMSR_TX_FIFO_EMPTY)

sprd_tx(port);

}

static inline void sprd_tx(struct uart_port *port)

{

do {

serial_out(port, SPRD_TXD, xmit->buf[xmit->tail]);

xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);

port->icount.tx++;

if (uart_circ_empty(xmit))

break;

} while (--count > 0);

}

串口接收过程

//中断来了,开始读数据,并存储

static irqreturn_t sprd_handle_irq(int irq, void *dev_id){

ims = serial_in(port, SPRD_IMSR);

if (ims & (SPRD_IMSR_RX_FIFO_FULL |

SPRD_IMSR_BREAK_DETECT | SPRD_IMSR_TIMEOUT))

sprd_rx(port);

}

static inline void sprd_rx(struct uart_port *port)

{

struct tty_port *tty = &port->state->port;

unsigned int ch, flag, lsr, max_count = SPRD_TIMEOUT;

while ((serial_in(port, SPRD_STS1) & 0x00ff) && max_count--) {

lsr = serial_in(port, SPRD_LSR);

ch = serial_in(port, SPRD_RXD);//把数据一个接一个读处理,然后放缓冲区里

uart_insert_char(port, lsr, SPRD_LSR_OE, ch, flag);--->uart_insert_char--->

}

tty_flip_buffer_push(tty);

}

static ssize_t tty_read(struct file *file, char __user *buf, size_t count,loff_t *ppos)

{

i = ld->ops->read(tty, file, buf, count);--->n_tty_read

}

static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,unsigned char __user *buf, size_t nr)

{

uncopied = copy_from_read_buf(tty, &b, &nr);

}

本文地址:https://blog.csdn.net/mike8825/article/details/107598833

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值