欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

Linux下串口读写过程小析

程序员文章站 2022-09-16 20:54:16
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, ....

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

相关标签: TTY