日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

AM335x Linux uart 串口(rs485rs232)无法正常通信的一种解决方法

發布時間:2023/12/31 linux 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AM335x Linux uart 串口(rs485rs232)无法正常通信的一种解决方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

先大概說說我是如何解決rs485(uart4)&rs233(uart5)的通信問題。

首先,在kernel-AGV/drivers/tty/serial/omap-serial.c中確定串口的默認時鐘頻率。

接著,在kernel/arch/arm/mach-omap2/board-ipc335x.c和kernel/arch/arm/mach-omap2/mux33xx.c中查看uart4(和流控腳)&uart5的配置;說明一下,board-ipc335x.c這個文件是根據evm板進行的更改,與各位的板級配置文件名可能不一致。

?

?

?

?從而確認板級配置沒有問題。

進一步的,查看uart_omap_port_set_rts_gpio函數的定義,將gpio設置成rts_gpio;

?重點查看drivers/tty/serial目錄,找到8250.c文件。通過更改nr_uarts的賦值達成目的,

/*static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;*/ static unsigned int nr_uarts = 5; //支持uart0~5 static void __init serial8250_isa_init_ports(void) {struct uart_8250_port *up;static int first = 1;int i, irqflag = 0;if (!first)return;first = 0;for (i = 0; i < nr_uarts; i++) {struct uart_8250_port *up = &serial8250_ports[i];up->port.line = i;spin_lock_init(&up->port.lock);init_timer(&up->timer);up->timer.function = serial8250_timeout;/** ALPHA_KLUDGE_MCR needs to be killed.*/up->mcr_mask = ~ALPHA_KLUDGE_MCR;up->mcr_force = ALPHA_KLUDGE_MCR;up->port.ops = &serial8250_pops;}if (share_irqs)irqflag = IRQF_SHARED;for (i = 0, up = serial8250_ports;i < ARRAY_SIZE(old_serial_port) && i < nr_uarts;i++, up++) {up->port.iobase = old_serial_port[i].port;up->port.irq = irq_canonicalize(old_serial_port[i].irq);up->port.irqflags = old_serial_port[i].irqflags;up->port.uartclk = old_serial_port[i].baud_base * 16;up->port.flags = old_serial_port[i].flags;up->port.hub6 = old_serial_port[i].hub6;up->port.membase = old_serial_port[i].iomem_base;up->port.iotype = old_serial_port[i].io_type;up->port.regshift = old_serial_port[i].iomem_reg_shift;set_io_from_upio(&up->port);up->port.irqflags |= irqflag;if (serial8250_isa_config != NULL)serial8250_isa_config(i, &up->port, &up->capabilities);} }

此時uart4&uart5雖然可以正常使用,但是rs485(uart4)仍然不能正常通訊,最后查閱documentation目錄下的serial-rs485.txt;如下:

??????????????????????? RS485 SERIAL COMMUNICATIONS

1. INTRODUCTION

?? EIA-485, also known as TIA/EIA-485 or RS-485, is a standard defining the
?? electrical characteristics of drivers and receivers for use in balanced
?? digital multipoint systems.
?? This standard is widely used for communications in industrial automation
?? because it can be used effectively over long distances and in electrically
?? noisy environments.

2. HARDWARE-RELATED CONSIDERATIONS

?? Some CPUs/UARTs (e.g., Atmel AT91 or 16C950 UART) contain a built-in
?? half-duplex mode capable of automatically controlling line direction by
?? toggling RTS or DTR signals. That can be used to control external
?? half-duplex hardware like an RS485 transceiver or any RS232-connected
?? half-duplex devices like some modems.

?? For these microcontrollers, the Linux driver should be made capable of
?? working in both modes, and proper ioctls (see later) should be made
?? available at user-level to allow switching from one mode to the other, and
?? vice versa.

3. DATA STRUCTURES ALREADY AVAILABLE IN THE KERNEL

?? The Linux kernel provides the serial_rs485 structure (see [1]) to handle
?? RS485 communications. This data structure is used to set and configure RS485
?? parameters in the platform data and in ioctls.

?? The device tree can also provide RS485 boot time parameters (see [2]
?? for bindings). The driver is in charge of filling this data structure from
?? the values given by the device tree.

?? Any driver for devices capable of working both as RS232 and RS485 should
?? provide at least the following ioctls:

??? - TIOCSRS485 (typically associated with number 0x542F). This ioctl is used
????? to enable/disable RS485 mode from user-space

??? - TIOCGRS485 (typically associated with number 0x542E). This ioctl is used
????? to get RS485 mode from kernel-space (i.e., driver) to user-space.

?? In other words, the serial driver should contain a code similar to the next
?? one:

?? ?static struct uart_ops atmel_pops = {
?? ??? ?/* ... */
?? ??? ?.ioctl?? ??? ?= handle_ioctl,
?? ?};

?? ?static int handle_ioctl(struct uart_port *port,
?? ??? ?unsigned int cmd,
?? ??? ?unsigned long arg)
?? ?{
?? ??? ?struct serial_rs485 rs485conf;

?? ??? ?switch (cmd) {
?? ??? ?case TIOCSRS485:
?? ??? ??? ?if (copy_from_user(&rs485conf,
?? ??? ??? ??? ?(struct serial_rs485 *) arg,
?? ??? ??? ??? ?sizeof(rs485conf)))
?? ??? ??? ??? ??? ?return -EFAULT;

?? ??? ??? ?/* ... */
?? ??? ??? ?break;

?? ??? ?case TIOCGRS485:
?? ??? ??? ?if (copy_to_user((struct serial_rs485 *) arg,
?? ??? ??? ??? ?...,
?? ??? ??? ??? ?sizeof(rs485conf)))
?? ??? ??? ??? ??? ?return -EFAULT;
?? ??? ??? ?/* ... */
?? ??? ??? ?break;

?? ??? ?/* ... */
?? ??? ?}
?? ?}


4. USAGE FROM USER-LEVEL

?? From user-level, RS485 configuration can be get/set using the previous
?? ioctls. For instance, to set RS485 you can use the following code:

?? ?#include <linux/serial.h>

?? ?/* Driver-specific ioctls: */
?? ?#define TIOCGRS485????? 0x542E
?? ?#define TIOCSRS485????? 0x542F

?? ?/* Open your specific device (e.g., /dev/mydevice): */
?? ?int fd = open ("/dev/mydevice", O_RDWR);
?? ?if (fd < 0) {
?? ??? ?/* Error handling. See errno. */
?? ?}

?? ?struct serial_rs485 rs485conf;

?? ?/* Enable RS485 mode: */
?? ?rs485conf.flags |= SER_RS485_ENABLED;

?? ?/* Set logical level for RTS pin equal to 1 when sending: */
?? ?rs485conf.flags |= SER_RS485_RTS_ON_SEND;
?? ?/* or, set logical level for RTS pin equal to 0 when sending: */
?? ?rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);

?? ?/* Set logical level for RTS pin equal to 1 after sending: */
?? ?rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
?? ?/* or, set logical level for RTS pin equal to 0 after sending: */
?? ?rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);

?? ?/* Set rts delay before send, if needed: */
?? ?rs485conf.delay_rts_before_send = ...;

?? ?/* Set rts delay after send, if needed: */
?? ?rs485conf.delay_rts_after_send = ...;

?? ?/* Set this flag if you want to receive data even whilst sending data */
?? ?rs485conf.flags |= SER_RS485_RX_DURING_TX;

?? ?if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
?? ??? ?/* Error handling. See errno. */
?? ?}

?? ?/* Use read() and write() syscalls here... */

?? ?/* Close the device when finished: */
?? ?if (close (fd) < 0) {
?? ??? ?/* Error handling. See errno. */
?? ?}

5. REFERENCES

?[1]?? ?include/linux/serial.h
?[2]?? ?Documentation/devicetree/bindings/serial/rs485.txt

根據serial-rs485.txt給出的提示,在Linux下編譯下面的代碼,將生成的二進制可執行文件放入AM335x內核的文件系統中,執行它即可實現rs485通信(之所以需要執行該程序,是因為底層驅動配置中沒有配置對應uart作為rs485的功能)。

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <linux/serial.h> #include <fcntl.h> #include <termios.h> #include <errno.h> #include <sys/ioctl.h>#define FALSE -1 #define TRUE 0 /* Driver-specific ioctls: */ #define TIOCGRS485 0x542E #define TIOCSRS485 0x542Fvoid set_speed(int fd, int speed){ int speed_arr[] = { B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300,B38400, B19200, B9600, B4800, B2400, B1200, B300, }; int name_arr[] = { 115200, 38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, }; int i; int status; struct termios Opt; tcgetattr(fd, &Opt); for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) { if (speed == name_arr[i]) { tcflush(fd, TCIOFLUSH); cfsetispeed(&Opt, speed_arr[i]); cfsetospeed(&Opt, speed_arr[i]); status = tcsetattr(fd, TCSANOW, &Opt); if (status != 0) { perror("tcsetattr fd1"); return; } tcflush(fd,TCIOFLUSH); } } } int set_Parity(int fd,int databits,int stopbits,int parity) { struct termios options; if ( tcgetattr( fd,&options) != 0) { perror("SetupSerial 1"); return(FALSE); } options.c_cflag &= ~CSIZE; switch (databits) { case 7: options.c_cflag |= CS7; break; case 8: options.c_cflag |= CS8; break; default: fprintf(stderr,"Unsupported data size\n"); return (FALSE); } switch (parity) { case 'n': case 'N': options.c_cflag &= ~PARENB; /* Clear parity enable */ options.c_iflag &= ~INPCK; /* Enable parity checking */ break; case 'o': case 'O': options.c_cflag |= (PARODD | PARENB); options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'e': case 'E': options.c_cflag |= PARENB; /* Enable parity */ options.c_cflag &= ~PARODD; options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'S': case 's': /*as no parity*/ options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB;break; default: fprintf(stderr,"Unsupported parity\n"); return (FALSE); } switch (stopbits) { case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: fprintf(stderr,"Unsupported stop bits\n"); return (FALSE); } /* Set input parity option */ if (parity != 'n') options.c_iflag |= INPCK; tcflush(fd,TCIFLUSH); options.c_cc[VTIME] = 150; options.c_cc[VMIN] = 0; /* Update the options and do it NOW */ if (tcsetattr(fd,TCSANOW,&options) != 0) { perror("SetupSerial 3"); return (FALSE); } return (TRUE); }int read_datatty(int fd, unsigned char *rcv_buf, int TimeOut, int Len) {int retval;fd_set rfds;struct timeval tv;int ret, pos;tv.tv_sec = TimeOut / 1000; //set the rcv wait timetv.tv_usec = TimeOut % 1000 * 1000; //100000us = 0.1spos = 0;while (1){FD_ZERO(&rfds);FD_SET(fd, &rfds);retval = select(fd + 1, &rfds, NULL, NULL, &tv);if (retval == -1){perror("select()");break;}else if (retval){ret = read(fd, rcv_buf + pos, 1);if (-1 == ret){printf("read error\n");break;}pos++;if (Len <= pos){break;}}else{printf("select_timeout\n");break;}}return pos; }int main() { int fdO4; int ret;fdO4 = open("/dev/ttyO4",O_RDWR);if(fdO4 == -1) { perror("serialport error\n"); }else { printf("open "); printf("%s",ttyname(fdO4)); printf(" successfully\n"); } struct serial_rs485 rs485conf;/* Enable RS485 mode: */rs485conf.flags |= SER_RS485_ENABLED;/* Set logical level for RTS pin equal to 1 when sending: */rs485conf.flags |= SER_RS485_RTS_ON_SEND;/* Set logical level for RTS pin equal to 0 after sending: */rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);/* Set this flag if you want to receive data even whilst sending data *//*rs485conf.flags |= SER_RS485_RX_DURING_TX;*/if (ioctl (fdO4, TIOCSRS485, &rs485conf) < 0) {printf("ioctl Error\n");}set_speed(fdO4,115200); if (set_Parity(fdO4,8,1,'N') == FALSE) { printf("Set Parity Error\n"); exit(-1); }unsigned char recvbuf[20] = { 0 };const unsigned char sendbuf[] ={ 0x08, 0x03, 0x00, 0x04, 0x00, 0x04, 0x05, 0x51 };ret = write(fdO4, sendbuf, 8);if (ret == -1){printf("write device error\n");}else if (ret == 8){printf("write_suc\n");} read_datatty(fdO4, recvbuf, 2000, 14);for(int i = 1; i < 14; i++) {printf("%x ",recvbuf[i]);}printf("\n");close(fdO4);return 0; }

一階段結束,然后我們來大致分析下uart初始化過程;

首先是uart驅動框架

uart驅動架構:

?

Linux tty subsystem:

在論述串口初始化之前,將簡要說明一些重要的數據結構;順便插一句,對于通用串口控制器,THR(發送保持寄存器)、RHR(接收保持寄存器)、IER(中斷使能寄存器)、FCR(緩沖控制寄存器)、LCR(控制寄存器)、LSR(狀態寄存器)、MCR(模式控制寄存器)、MSR(模式狀態寄存器)

struct uart_driver : 用于描述串口結構,一個串口對應一個串口驅動

struct uart_driver {

struct module?? *owner; //模塊所有者

const char? *driver_name;?? //驅動名

const char? *dev_name;? //設備名

int? major; //主設備號

int? minor; //次設備號

int? nr;??? //支持串口個數

struct console? *cons;//控制臺設備

//下面兩個變量應被初始化為NULL

//tty_driver在函數register_uart_driver中被賦值,同時state也會被分配空間

//最后通過uart_add_one_port添加uart_state->uart_port

struct uart_state?? *state; //串口狀態,下層(串口驅動層)

struct tty_driver?? *tty_driver; //tty相關

};

struct uart_port : 串口端口結構體,有幾個串口就對應幾個uart_port

struct uart_port {

spinlock_t? lock;

unsigned long?? iobase; //io端口基地址(物理地址)

unsigned char __iomem?? *membase; //io內存基地址(虛擬地址)

unsigned int??? (*serial_in)(struct uart_port *, int); //串口讀函數

void??? (*serial_out)(struct uart_port *, int, int); //串口寫方法

void??? (*set_termios)(struct uart_port *,struct ktermios *new,struct ktermios *old); //串口配置方法函數

void??? (*pm)(struct uart_port *, unsigned int state,unsigned int old);

unsigned int??? irq;??? //中斷號

unsigned long?? irqflags;?? //中斷標志

unsigned int??? uartclk;?? //串口時鐘

unsigned int??? fifosize;?? //fifo大小

unsigned char?? x_char;

unsigned char?? regshift;?? //寄存器偏移值

unsigned char?? iotype; //io訪問類型

unsigned char?? unused1;

unsigned int??? read_status_mask;

unsigned int??? ignore_status_mask;

struct uart_state?? *state; //uart_state結構體

struct uart_icount? icount; //串口使用計數

struct console? *cons;? //console控制臺

#if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(SUPPORT_SYSRQ)

unsigned long?? sysrq;

#endif

upf_t?? flags;

unsigned int??? mctrl;

unsigned int??? timeout;

unsigned int??? type; //串口類型

const struct uart_ops?? *ops;?? //串口操作函數集

unsigned int??? custom_divisor;

unsigned int??? line;?? //端口號

resource_size_t mapbase; //串口寄存器基地址(物理地址)

struct device?? *dev;?? //設備文件

unsigned char?? hub6;

unsigned char?? suspended;

unsigned char?? irq_wake;

unsigned char?? unused[2];

void??? *private_data;

};

struct uart_ops : 串口相關操作函數集

struct uart_ops {

unsigned int??? (*tx_empty)(struct uart_port *);??? //發送緩沖區為空

void??? (*set_mctrl)(struct uart_port *, unsigned int mctrl);?? //設置串口modem控制模式

unsigned int??? (*get_mctrl)(struct uart_port *);?? //獲取串口modem控制模式

void??? (*stop_tx)(struct uart_port *); //停止發送

void??? (*start_tx)(struct uart_port *);??? //開始發送

void??? (*send_xchar)(struct uart_port *, char ch);

void??? (*stop_rx)(struct uart_port *); //停止接收

void??? (*enable_ms)(struct uart_port *);?? //使能modem狀態信息

void??? (*break_ctl)(struct uart_port *, int ctl);

int (*startup)(struct uart_port *); //打開串口

void??? (*shutdown)(struct uart_port *);??? //關閉串口

void??? (*flush_buffer)(struct uart_port *);

void??? (*set_termios)(struct uart_port *, struct ktermios *new,struct ktermios *old);? //設置串口參數

void??? (*set_ldisc)(struct uart_port *, int new);

void??? (*pm)(struct uart_port *, unsigned int state,unsigned int oldstate);

int (*set_wake)(struct uart_port *, unsigned int state);

const char *(*type)(struct uart_port *);

void??? (*release_port)(struct uart_port *);??? //釋放端口

int (*request_port)(struct uart_port *);??? //請求端口

void??? (*config_port)(struct uart_port *, int);??? //配置端口

int (*verify_port)(struct uart_port *, struct serial_struct *); //校驗端口

int (*ioctl)(struct uart_port *, unsigned int, unsigned long);? //控制

#ifdef CONFIG_CONSOLE_POLL

void??? (*poll_put_char)(struct uart_port *, unsigned char);

int (*poll_get_char)(struct uart_port *);

#endif

};

struct uart_state : 描述串口狀態信息

struct uart_state {

struct tty_port port;

int???? pm_state; //電源狀態

struct circ_buf xmit; //數據緩沖區

struct tasklet_struct?? tlet;

struct uart_port??? *uart_port;//指向對應的串口結構

};

uart初始化:

大致為:分配一個struct uart_driver用于定義并描述串口,再調用uart_register_driver注冊串口驅動,最后調用uart_add_one_port添加端口到串口設備。

static struct uart_driver serial8250_reg = {

.owner????????????????? = THIS_MODULE,

.driver_name???????? = “serial”,

.dev_name??????????? = “ttyS”,

.major?????????????????? = TTY_MAJAOR,

.minor????????????????? = 64,

.cons??????????????????? = SERIAL8250_CONSOLE,

};

static int __init serial8250_init(void)

{

?????? int ret;

?????? if (nr_uarts > UART_NR)

????????????? nr_uarts = UART_NR;

?????? printk(KERN_INFO "Serial: 8250/16550 driver, "

????????????? "%d ports, IRQ sharing %sabled\n", nr_uarts,

????????????? share_irqs ? "en" : "dis");

#ifdef CONFIG_SPARC

?????? ret = sunserial_register_minors(&serial8250_reg, UART_NR);

#else

?????? serial8250_reg.nr = UART_NR; //串口數量

?????? ret = uart_register_driver(&serial8250_reg); //注冊串口驅動

#endif

?????? if (ret)

????????????? goto out;

?????? serial8250_isa_devs = platform_device_alloc("serial8250",

????????????????????????????????????????? ??? PLAT8250_DEV_LEGACY);

?????? if (!serial8250_isa_devs) {

????????????? ret = -ENOMEM;

????????????? goto unreg_uart_drv;

?????? }

?????? ret = platform_device_add(serial8250_isa_devs);

?????? if (ret)

????????????? goto put_dev;

?????? serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);

?????? ret = platform_driver_register(&serial8250_isa_driver);

?????? if (ret == 0)

????????????? goto out;

?????? platform_device_del(serial8250_isa_devs);

put_dev:

?????? platform_device_put(serial8250_isa_devs);

unreg_uart_drv:

#ifdef CONFIG_SPARC

?????? sunserial_unregister_minors(&serial8250_reg, UART_NR);

#else

?????? uart_unregister_driver(&serial8250_reg);

#endif

out:

?????? return ret;

}

int uart_register_driver(struct uart_driver *drv)

{

?????? struct tty_driver *normal;

?????? int i, retval;

?????? BUG_ON(drv->state);

?????? /*

?????? ?* Maybe we should be using a slab cache for this, especially if

?????? ?* we have a large number of ports to handle.

?????? ?*/

?????? drv->state = kzalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL);

?????? if (!drv->state)

????????????? goto out;

?????? normal = alloc_tty_driver(drv->nr);

?????? if (!normal)

????????????? goto out_kfree;

?????? drv->tty_driver = normal; //賦值給uart_driver結構的tty_driver成員

?????? //對tty_driver成員指向的結構初始化

?????? normal->owner?????????? = drv->owner;

?????? normal->driver_name? = drv->driver_name;

?????? normal->name??????????? = drv->dev_name;

?????? normal->major??????????? = drv->major;

?????? normal->minor_start?? = drv->minor;

?????? normal->type????????????? = TTY_DRIVER_TYPE_SERIAL;

?????? normal->subtype??????? = SERIAL_TYPE_NORMAL;

?????? normal->init_termios?? = tty_std_termios; // drivers/tty/tty_io.c

?????? normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;

?????? normal->init_termios.c_ispeed = normal->init_termios.c_ospeed = 9600;

?????? normal->flags???????????? = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;

?????? normal->driver_state??? = drv;

?????? //將tty_driver結構的normal操作指向uart_ops ,即tty_ops封裝uart_ops

tty_set_operations(normal, &uart_ops);

?????? /*

?????? ?* Initialise the UART state(s).

?????? ?*/

?????? for (i = 0; i < drv->nr; i++) {

????????????? struct uart_state *state = drv->state + i;

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

?????? ?????? tty_port_init(port);

????????????? port->ops = &uart_port_ops;

????????????? port->close_delay???? = 500;??? /* .5 seconds */

????????????? port->closing_wait??? = 30000; /* 30 seconds */

?????? }

?????? retval = tty_register_driver(normal);

?????? if (retval >= 0)

????????????? return retval;

?????? put_tty_driver(normal);

out_kfree:

?????? kfree(drv->state);

out:

?????? return -ENOMEM;

}

//初始化uart_port

static void __init serial8250_isa_init_ports(void)

{

?????? struct uart_8250_port *up;

?????? static int first = 1;

?????? int i, irqflag = 0;

?????? if (!first)

????????????? return;

?????? first = 0;

?????? for (i = 0; i < nr_uarts; i++) {

????????????? struct uart_8250_port *up = &serial8250_ports[i];

????????????? up->port.line = i; //串口號,i==0對應串口0

????????????? spin_lock_init(&up->port.lock);

????????????? init_timer(&up->timer); //初始化定時器

????????????? up->timer.function = serial8250_timeout; //初始化定時器超時函數

????????????? /*

????????????? ?* ALPHA_KLUDGE_MCR needs to be killed.

????????????? ?*/

????????????? up->mcr_mask = ~ALPHA_KLUDGE_MCR;

????????????? up->mcr_force = ALPHA_KLUDGE_MCR;

????????????? up->port.ops = &serial8250_pops;

?????? }

/******************************************

static struct uart_ops serial8250_pops = {

.tx_empty?= serial8250_tx_empty,

.set_mctrl?= serial8250_set_mctrl,

.get_mctrl?= serial8250_get_mctrl,

.stop_tx?= serial8250_stop_tx,

.start_tx?= serial8250_start_tx,

.stop_rx?= serial8250_stop_rx,

.enable_ms?= serial8250_enable_ms,

.break_ctl?= serial8250_break_ctl,

.startup?= serial8250_startup,

.shutdown?= serial8250_shutdown,

.set_termios?= serial8250_set_termios,

.set_ldisc?= serial8250_set_ldisc,

.pm??= serial8250_pm,

.type??= serial8250_type,

.release_port?= serial8250_release_port,

.request_port?= serial8250_request_port,

.config_port?= serial8250_config_port,

.verify_port?= serial8250_verify_port,

#ifdef CONFIG_CONSOLE_POLL

.poll_get_char = serial8250_get_poll_char,

.poll_put_char = serial8250_put_poll_char,

#endif

};

******************************************/

?????? if (share_irqs) //中斷是否共享

????????????? irqflag = IRQF_SHARED;

?????? for (i = 0, up = serial8250_ports;

?????? ???? i < ARRAY_SIZE(old_serial_port) && i < nr_uarts;

?????? ???? i++, up++) {

????????????? up->port.iobase?? = old_serial_port[i].port;

????????????? up->port.irq????? = irq_canonicalize(old_serial_port[i].irq);

????????????? up->port.irqflags = old_serial_port[i].irqflags;

????????????? up->port.uartclk? = old_serial_port[i].baud_base * 16;

????????????? up->port.flags??? = old_serial_port[i].flags;

????????????? up->port.hub6???? = old_serial_port[i].hub6;

????????????? up->port.membase? = old_serial_port[i].iomem_base;

????????????? up->port.iotype?? = old_serial_port[i].io_type;

????????????? up->port.regshift = old_serial_port[i].iomem_reg_shift;

????????????? set_io_from_upio(&up->port);

????????????? up->port.irqflags |= irqflag;

????????????? if (serial8250_isa_config != NULL)

???????????????????? serial8250_isa_config(i, &up->port, &up->capabilities);

?????? }

}

/**

?*??? uart_add_one_port - attach a driver-defined port structure

?*??? @drv: pointer to the uart low level driver structure for this port

?*??? @uport: uart port structure to use for this port.

?*

?*??? This allows the driver to register its own uart_port structure

?*??? with the core driver.? The main purpose is to allow the low

?*??? level uart drivers to expand uart_port, rather than having yet

?*??? more levels of structures.

?*/

int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)

{

?????? struct uart_state *state;

?????? struct tty_port *port;

?????? int ret = 0;

?????? struct device *tty_dev;

?????? BUG_ON(in_interrupt());

?????? if (uport->line >= drv->nr)

????????????? return -EINVAL;

?????? state = drv->state + uport->line;

?????? port = &state->port;

?????? mutex_lock(&port_mutex);

?????? mutex_lock(&port->mutex);

?????? if (state->uart_port) {

????????????? ret = -EINVAL;

????????????? goto out;

?????? }

?????? state->uart_port = uport;

?????? state->pm_state = -1;

?????? uport->cons = drv->cons;

?????? uport->state = state;

?????? /*

?????? ?* If this port is a console, then the spinlock is already

?????? ?* initialised.

?????? ?*/

?????? if (!(uart_console(uport) && (uport->cons->flags & CON_ENABLED))) {

????????????? spin_lock_init(&uport->lock);

????????????? lockdep_set_class(&uport->lock, &port_lock_key);

?????? }

//進行port的自動配置,在未進行serial8250_probe()時,串口的port->iobase(io基地址)、port->mapbase(串口寄存器基地址)、port->membase(io內存基地址)都為空,所以函數進去會立即返回,即未配置成功。

//當進行完serial8250_probe()函數時,還會調用uart_add_one_port(),再到這個函數配置時就會配置成功

?????? uart_configure_port(drv, state, uport);

?????? /*

?????? ?* Register the port whether it's detected or not.? This allows

?????? ?* setserial to be used to alter this ports parameters.

?????? ?*/

?????? tty_dev = tty_register_device(drv->tty_driver, uport->line, uport->dev);

?????? if (likely(!IS_ERR(tty_dev))) {

????????????? device_init_wakeup(tty_dev, 1);

????????????? device_set_wakeup_enable(tty_dev, 0);

?????? } else

????????????? printk(KERN_ERR "Cannot register tty device on line %d\n",

????????????? ?????? uport->line);

?????? /*

?????? ?* Ensure UPF_DEAD is not set.

?????? ?*/

?????? uport->flags &= ~UPF_DEAD;

?out:

?????? mutex_unlock(&port->mutex);

?????? mutex_unlock(&port_mutex);

?????? return ret;

}

static void

uart_configure_port(struct uart_driver *drv, struct uart_state *state,

????????????? ??? struct uart_port *port)

{

?????? unsigned int flags;

?????? /*

?????? ?* If there isn't a port here, don't do anything further.

?????? ?*/

?????? //未調用serial8250_probe()之前,會從這里直接返回

?????? if (!port->iobase && !port->mapbase && !port->membase)

????????????? return;

?????? /*

?????? ?* Now do the auto configuration stuff.? Note that config_port

?????? ?* is expected to claim the resources and map the port for us.

?????? ?*/

?????? flags = 0;

?????? if (port->flags & UPF_AUTO_IRQ)

????????????? flags |= UART_CONFIG_IRQ;

?????? if (port->flags & UPF_BOOT_AUTOCONF) {

????????????? if (!(port->flags & UPF_FIXED_TYPE)) { //經過probe()函數,已設置該標志,不執行???????????????

port->type = PORT_UNKNOWN;

???????????????????? flags |= UART_CONFIG_TYPE;

????????????? }

//調用設備的自動配置函數,即serial8250_config_port()

????????????? port->ops->config_port(port, flags); }

?????? if (port->type != PORT_UNKNOWN) {

????????????? unsigned long flags;

????????????? uart_report_port(drv, port); //打印串口信息

????????????? /* Power up port for set_mctrl() */

????????????? uart_change_pm(state, 0);

????????????? /*

????????????? ?* Ensure that the modem control lines are de-activated.

????????????? ?* keep the DTR setting that is set in uart_set_options()

????????????? ?* We probably don't need a spinlock around this, but

????????????? ?*/

????????????? spin_lock_irqsave(&port->lock, flags);

????????????? port->ops->set_mctrl(port, port->mctrl & TIOCM_DTR);

????????????? spin_unlock_irqrestore(&port->lock, flags);

????????????? /*

????????????? ?* If this driver supports console, and it hasn't been

????????????? ?* successfully registered yet, try to re-register it.

????????????? ?* It may be that the port was not available.

????????????? ?*/

????????????? if (port->cons && !(port->cons->flags & CON_ENABLED))

???????????????????? register_console(port->cons);

????????????? /*

????????????? ?* Power down all ports by default, except the

????????????? ?* console if we have one.

????????????? ?*/

????????????? if (!uart_console(port))

???????????????????? uart_change_pm(state, 3);

?????? }

}

/*

?* Register a set of serial devices attached to a platform device.? The

?* list is terminated with a zero flags entry, which means we expect

?* all entries to have at least UPF_BOOT_AUTOCONF set.

?*/

static int __devinit serial8250_probe(struct platform_device *dev)

{

?????? struct plat_serial8250_port *p = dev->dev.platform_data;

?????? struct uart_port port;

?????? int ret, i, irqflag = 0;

?????? memset(&port, 0, sizeof(struct uart_port));

?????? if (share_irqs)

????????????? irqflag = IRQF_SHARED;

?????? for (i = 0; p && p->flags != 0; p++, i++) {

????????????? port.iobase?????????? = p->iobase;

????????????? port.membase????? = p->membase;

????????????? port.irq????????? ?????? = p->irq;

????????????? port.irqflags????????? = p->irqflags;

????????????? port.uartclk?????????? = p->uartclk;

????????????? port.regshift????????? = p->regshift;

????????????? port.iotype??????????? = p->iotype;

????????????? port.flags????????????? = p->flags;

????????????? port.mapbase?????? = p->mapbase;

????????????? port.hub6???????????? = p->hub6;

????????????? port.private_data?? = p->private_data;

????????????? port.type??????? ?????? = p->type;

????????????? port.serial_in???????? = p->serial_in;

????????????? port.serial_out?????? = p->serial_out;

????????????? port.handle_irq???? = p->handle_irq;

????????????? port.set_termios??? = p->set_termios;

????????????? port.pm??????????????? = p->pm;

????????????? port.dev???????? = &dev->dev;

????????????? port.irqflags?? |= irqflag;

????????????? ret = serial8250_register_port(&port);

????????????? if (ret < 0) {

???????????????????? dev_err(&dev->dev, "unable to register port at index %d "

??????????????????????????? "(IO%lx MEM%llx IRQ%d): %d\n", i,

??????????????????????????? p->iobase, (unsigned long long)p->mapbase,

??????????????????????????? p->irq, ret);

????????????? }

?????? }

?????? return 0;

}

以上,基本就是uart初始化過程,當然忽略了platform_device、platform_drive;串口中的驅動分兩層,首先是基于控制臺的驅動,即serial8250_console,還有一個是基于UART的驅動,相當于我們在實際使用串口時,使用的set_termois,start_tx,stop_tx,start_rx,stop_rx等函數。本文只談論了基于uart的驅動,跳過基于console的驅動原因是uart4&uart5并不用作為控制臺。

文中存在不妥之處,還請指出,謝謝!

?

總結

以上是生活随笔為你收集整理的AM335x Linux uart 串口(rs485rs232)无法正常通信的一种解决方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

人人干人人搞 | 国产一区二区三区四区在线 | 亚洲精品免费观看视频 | 国产日韩精品在线观看 | 天天干天天操天天入 | 91av手机在线观看 | 人人爽人人爽人人爽人人爽 | 九九视频精品在线 | 日日操日日 | 中文字幕第一页在线 | 日韩av电影网站在线观看 | 国产一区在线看 | 狠狠色丁香婷婷综合最新地址 | 在线视频精品播放 | 婷婷国产一区二区三区 | 中文字幕在线观看资源 | 久久久精品一区二区三区 | 国产成视频在线观看 | 成人国产一区 | 99久久99视频只有精品 | 在线 高清 中文字幕 | 九九在线高清精品视频 | 在线观看精品 | 五月天激情婷婷 | 欧美一级在线看 | 日韩av免费在线电影 | 99爱这里只有精品 | 久久伊人国产精品 | 成人在线播放视频 | 国产一级在线观看 | 人成午夜视频 | 久久久不卡影院 | 91网址在线 | 亚洲成人网在线 | 日韩有码第一页 | 亚洲在线a| 久青草电影 | 久久综合免费视频影院 | 国产精品久久视频 | 精品国产诱惑 | 国产成人精品一区二区三区网站观看 | 日韩二区在线播放 | 天天激情在线 | av大片免费看 | 美女视频黄在线观看 | 欧美大jb| 九九亚洲视频 | 久草免费色站 | 国产精品 日本 | 国产一区二区综合 | 久久超级碰 | 永久免费看av | 国产精品视频永久免费播放 | 四虎国产精品成人免费影视 | av在线播放中文字幕 | 亚洲国产午夜精品 | 97久久精品午夜一区二区 | 四虎国产精品永久在线国在线 | 成人在线免费观看视视频 | 69av视频在线观看 | 免费看黄色91 | 日韩一区在线免费观看 | 蜜桃av人人夜夜澡人人爽 | 91九色视频国产 | 久草在线久草在线2 | 国产精品99久久99久久久二8 | 欧美巨乳网 | 成人免费视频网站 | 最新中文字幕在线资源 | 欧美日韩在线播放 | 成人黄色在线看 | 人人精久 | 91大神精品视频 | 日韩欧美在线综合网 | 天天曰天天 | 国产精品专区在线观看 | 亚洲精品高清视频 | 91免费看片黄 | 色视频网址 | 一本一本久久a久久精品综合妖精 | 最近中文字幕高清字幕免费mv | 亚洲九九影院 | 色婷婷亚洲婷婷 | 黄网站免费看 | 高清久久久 | 日韩激情视频在线 | 亚洲动漫在线观看 | 国模吧一区 | 欧美激情精品久久久久 | 岛国av在线不卡 | 天天操夜夜想 | 香蕉免费在线 | 久久亚洲国产精品 | 天天射综合| 91精品色 | 在线精品在线 | 亚洲aⅴ免费在线观看 | 国产精品久久久久久久毛片 | 亚洲精品一区二区三区四区高清 | 天天天干天天天操 | 精品久久久久久久 | 国产精品久久久一区二区 | 色在线高清 | 欧洲一区二区在线观看 | 91精品国产九九九久久久亚洲 | 亚洲精品福利在线观看 | 久久99久久99| 日韩激情在线 | 人人看人人做人人澡 | 亚洲国产播放 | 91经典在线 | 国产黄色片在线 | 91在线影院 | 麻豆久久久久 | 黄网站免费久久 | 精品伦理一区二区三区 | 色综合天天综合在线视频 | 久久爱992xxoo | 亚洲色图色 | 日韩电影在线观看一区 | 久草精品电影 | 日韩精品高清不卡 | 日韩一区二区三区高清免费看看 | 久久精品视频网站 | 国产精品美女视频网站 | 亚洲国产精品影院 | 欧美另类sm图片 | 免费看日韩 | 久久九九免费 | 亚洲欧美日韩在线一区二区 | 99超碰在线播放 | 99久久精品国产一区二区三区 | 久久久久人人 | 亚州精品在线视频 | www.久热| 午夜私人影院 | 99re久久精品国产 | 亚洲专区视频在线观看 | www.xxxx变态.com | 日韩精品视频免费在线观看 | 人人添人人澡 | 亚洲国产福利视频 | 一区二区三区在线播放 | 久久久国产精品一区二区中文 | 亚洲三级黄色 | 欧美成人视 | 91看毛片 | 国产在线色| 日韩精品免费一区 | 夜夜操夜夜干 | 国产精品久久久久久一区二区三区 | 中文字幕高清免费日韩视频在线 | 久久久久综合网 | 久久久久女人精品毛片 | 天天射天天干天天操 | 欧美久久久久久久 | 欧美精品亚洲精品日韩精品 | 丁香六月在线观看 | 精品中文字幕视频 | 操操操夜夜操 | 成人国产精品久久久 | 欧美日韩中文字幕视频 | 日韩在线一区二区免费 | 97在线视频免费看 | 四虎影视成人永久免费观看视频 | 久久久久久久久黄色 | 一级黄色电影网站 | 久久乱码卡一卡2卡三卡四 五月婷婷久 | 日韩簧片在线观看 | 亚洲一区网 | 亚洲 中文字幕av | 久久污视频 | 成人av免费看 | 亚洲精品一区二区网址 | 91成人精品国产刺激国语对白 | 国产成人在线网站 | 一级c片| 久久高清片| 日韩黄色免费电影 | 中文字幕色婷婷在线视频 | 国产在线播放一区二区三区 | 国产精品青青 | av高清在线观看 | 久久爱资源网 | 久久久91精品国产一区二区精品 | 一级黄色免费网站 | 国产1区2区 | 国产手机在线观看视频 | 国产91粉嫩白浆在线观看 | 日韩免费专区 | 在线 视频 一区二区 | 最近中文字幕mv | 精品久久久成人 | 国语自产偷拍精品视频偷 | 日韩免费观看一区二区 | 午夜精品久久久久久久99热影院 | 麻豆免费看片 | 日韩视频欧美视频 | 国产成人精品女人久久久 | 91福利试看 | 天天色天天 | 精品视频中文字幕 | 国产无限资源在线观看 | 草久电影 | 久久99热久久99精品 | 久久激五月天综合精品 | 国产91亚洲 | 中文字幕在线字幕中文 | 中文字幕高清在线播放 | 国产一及片 | 天天干夜夜擦 | av黄色一级片 | 国产黄色大片 | 成人黄色电影在线观看 | 国产精品久久99综合免费观看尤物 | 亚洲日本韩国一区二区 | av一本久道久久波多野结衣 | 天天射天天 | 国产破处在线播放 | 四虎国产精品免费观看视频优播 | 国内精品视频一区二区三区八戒 | 一区二区三区精品在线 | 色综合久久久久综合 | 日韩欧美一区二区在线观看 | 黄色三级免费观看 | 成 人 a v天堂 | 亚洲国产片色 | 在线观看黄网站 | 精品一区二三区 | 国产一级免费播放 | 欧美视频网址 | 国产精品99久久久久 | a午夜电影 | 天天射天天舔天天干 | 国内精品久久久久久久影视简单 | 人人爽人人爱 | 欧美精品久久久久久久免费 | av一级免费 | 91chinese在线| 欧美日韩国产在线精品 | 国产字幕在线播放 | 丁香五月缴情综合网 | 美女黄频视频大全 | 国产99黄| 中文电影网 | 国产美女精品在线 | 色天天久久 | 国产999久久久 | 免费网站污 | 超碰97中文 | 夜夜躁日日躁狠狠躁 | 国产一级黄色av | 五月天六月婷婷 | 国产丝袜在线 | 日韩精品久久久久久久电影竹菊 | 亚洲国产中文字幕在线 | 久久久综合色 | 久久躁日日躁aaaaxxxx | 欧美专区国产专区 | 一区二区免费不卡在线 | 九九热视频在线免费观看 | 色综合天天综合 | 成片视频在线观看 | 激情欧美丁香 | 久草精品电影 | 狠狠狠色 | 日韩动漫免费观看高清完整版在线观看 | 欧美另类xxxxx | 日韩在线视频一区二区三区 | 在线久草视频 | 五月婷婷综合在线观看 | 亚洲精品乱码久久久久久蜜桃欧美 | 日日躁夜夜躁xxxxaaaa | 亚洲精品久久激情国产片 | 麻豆视频免费入口 | 亚洲综合在线五月 | 国产精品黄网站在线观看 | 91黄色在线视频 | 日韩精品一区二区三区高清免费 | www.神马久久 | 99欧美| 深夜免费福利视频 | 黄网在线免费观看 | 国产精品18久久久 | 欧美色伊人 | a√天堂资源 | 久久综合久久综合这里只有精品 | 国产精品美女在线观看 | 免费av网站在线 | 欧美永久视频 | 国产精品一区二区三区久久久 | 激情久久五月 | 亚洲九九九在线观看 | 国产午夜精品免费一区二区三区视频 | 麻豆网站免费观看 | 天天艹天天| 国产一区二区在线精品 | 91视频88av | 欧美国产日韩一区 | 国产精品视频一二三 | 欧美精品久久久久a | 狠狠色狠狠色综合日日小说 | 欧美一二三视频 | 五月婷婷,六月丁香 | 91精品在线观看视频 | 99久久久国产精品免费99 | 91亚洲国产成人久久精品网站 | 久久精品国产一区二区电影 | 黄色亚洲片 | 色婷婷狠狠| 久久精品波多野结衣 | 成年人国产在线观看 | 国产视频在线观看一区二区 | 国产成人精品一区二区三区网站观看 | 五月婷婷六月丁香在线观看 | 午夜的福利 | 成人久久国产 | 国产特级毛片aaaaaaa高清 | 久久不见久久见免费影院 | 夜添久久精品亚洲国产精品 | 日本久久中文 | 久久久久久网站 | 中文字幕永久免费 | 成人精品一区二区三区电影免费 | 亚洲精品在线免费播放 | 日韩精品免费在线观看视频 | 久久一区二区三区日韩 | 91视频91自拍| 天天干天天草天天爽 | 亚洲精品免费在线 | 国产福利精品一区二区 | 国产一级免费视频 | 色国产精品一区在线观看 | 免费看片网址 | 成人毛片一区二区三区 | 国产精品久久久久9999吃药 | 色婷婷久久一区二区 | 五月婷香蕉久色在线看 | 中日韩在线视频 | 久草在线在线精品观看 | 成人av电影在线播放 | 欧美国产不卡 | 色综合久久中文字幕综合网 | 一区二区三区手机在线观看 | 97精品一区 | 久久美女免费视频 | 天天操天天操天天操天天 | 久久久影院官网 | 啪啪免费观看网站 | 一级黄色免费网站 | 亚洲精品国产品国语在线 | 国产亚洲视频系列 | 在线中文字幕网站 | 精品人人人人 | 在线视频免费观看 | 91视频在线观看免费 | 亚洲资源片| 久草爱 | 在线只有精品 | 国产精品国产自产拍高清av | 在线观看免费日韩 | 成年人看片 | 美女网站视频免费都是黄 | 欧美日韩国产综合网 | 99在线国产 | 午夜久久久久久久久久久 | 在线观看av中文字幕 | 精品一区在线看 | 少妇精69xxtheporn| 精品999在线 | 久久99精品国产99久久 | av黄色在线观看 | 三级视频片 | 色综合天天在线 | 一区二区三区在线播放 | 国产精品第54页 | 97在线免费观看视频 | 最近中文字幕在线中文高清版 | 国产黄| 久久免费精品 | 亚洲精品天天 | 成人免费观看视频大全 | www毛片com| 亚洲最大激情中文字幕 | 99久久er热在这里只有精品15 | 99这里都是精品 | 香蕉影院在线 | 黄色大片国产 | 一本一本久久a久久 | 一区二区三区在线观看中文字幕 | 一区 二区 精品 | 97香蕉久久超级碰碰高清版 | 亚洲 欧美 国产 va在线影院 | 久久人人精 | 久久美女电影 | 欧美一级性生活片 | 欧美亚洲久久 | 国产日韩高清在线 | 91免费观看视频在线 | 亚洲国产精品推荐 | 久久综合久久伊人 | 在线视频 精品 | 成人性生交大片免费看中文网站 | 超碰公开在线观看 | 韩国中文三级 | 国产在线色站 | 日韩精品一区二区三区免费观看视频 | 在线免费看片 | 中文字幕在线看视频 | 久久五月婷婷丁香社区 | 久久视频精品 | 免费在线观看亚洲视频 | 亚洲在线视频播放 | 国产精品嫩草69影院 | 中文字幕在线观看av | 粉嫩av一区二区三区四区在线观看 | 欧美日本不卡 | 手机av在线不卡 | 国产精品午夜免费福利视频 | 亚洲综合国产精品 | 偷拍区另类综合在线 | www.夜色.com| 免费进去里的视频 | 日韩三级视频在线观看 | 五月婷婷国产 | 五月天伊人网 | 999久久国精品免费观看网站 | 欧美精品乱码久久久久久 | 亚洲激情av | 亚洲综合小说电影qvod | 五月天久久久 | 在线观看亚洲专区 | 91成人精品一区在线播放69 | 欧美有色| 色久综合| 天天操天天爽天天干 | 亚欧日韩av | 成人av免费播放 | 国产a国产 | 欧美一级特黄aaaaaa大片在线观看 | 日韩网站视频 | 亚洲h色精品 | 99久久国产免费,99久久国产免费大片 | 狠狠色伊人亚洲综合成人 | 黄色a视频免费 | 国产成人精品av | 毛片二区 | 国产精品黄 | 精品日韩在线一区 | 综合天天 | 久久天天躁狠狠躁亚洲综合公司 | 欧美在线观看视频一区二区三区 | 六月婷婷久香在线视频 | 在线免费国产视频 | 91精品免费| 国产精品久久久影视 | 欧美资源| 91一区二区三区久久久久国产乱 | 亚洲人成网站精品片在线观看 | 国产一级二级在线播放 | 九九免费精品视频在线观看 | 最近能播放的中文字幕 | 日本公乱妇视频 | 国产经典三级 | 国产伦精品一区二区三区高清 | 久久久高清视频 | 欧美 日韩 视频 | 亚洲综合色视频 | 色黄视频免费观看 | 新版资源中文在线观看 | 成人国产精品电影 | 最新日本中文字幕 | 国精产品999国精产 久久久久 | 天天躁天天操 | 亚洲女同ⅹxx女同tv | 日韩精品免费在线观看 | av电影免费看 | 久久久久久久99精品免费观看 | 婷婷综合五月 | 婷婷在线资源 | 天天干com| 视频在线观看入口黄最新永久免费国产 | 又粗又长又大又爽又黄少妇毛片 | 国产福利91精品一区二区三区 | 国产精品av久久久久久无 | 91九色最新| 亚洲精品在线观看的 | 17videosex性欧美| 在线观看中文字幕亚洲 | 日韩在线观看a | 国产精品高潮呻吟久久久久 | 99久久超碰中文字幕伊人 | 欧美一级片 | 婷婷中文字幕在线观看 | 国产专区精品视频 | 丁香综合网 | 最近中文字幕免费视频 | 亚洲精品777 | 中文字幕 国产视频 | 久久婷亚洲五月一区天天躁 | 黄色小说免费观看 | 午夜.dj高清免费观看视频 | 亚洲理论视频 | 五月婷影院 | 午夜视频在线观看一区二区三区 | 国产精品美女久久久久aⅴ 干干夜夜 | www.伊人网 | 欧美一级电影在线观看 | 天天插狠狠干 | 国产尤物在线视频 | 日韩 精品 一区 国产 麻豆 | 一个色综合网站 | 天天看天天干天天操 | 国产a级精品 | 日韩在线视频播放 | 免费看黄在线网站 | 开心激情婷婷 | 一级片免费在线 | 精品女同一区二区三区在线观看 | 日韩精品视频在线观看免费 | 国产成人久久久77777 | 国产成人333kkk | 99精品视频免费 | 久久精品激情 | 国产日产亚洲精华av | 中文字幕日本电影 | 久久久久久久久免费 | 91九色性视频 | av福利网址导航大全 | 全久久久久久久久久久电影 | 成年人视频在线免费播放 | 福利一区在线 | 成人四虎影院 | 伊在线视频 | 成人在线播放视频 | 亚洲天堂网在线播放 | 亚洲高清不卡av | 四虎在线观看精品视频 | 国产视频中文字幕在线观看 | 91精品婷婷国产综合久久蝌蚪 | 久99久精品视频免费观看 | 在线观看av免费观看 | 人人狠狠综合久久亚洲 | 福利一区二区在线 | 成人性生交大片免费看中文网站 | 18网站在线观看 | a成人在线| 久久久久国产精品视频 | 久久久久久久久久久久久影院 | 在线观看欧美成人 | 国产一区二区网址 | 在线日韩视频 | 狠狠色丁香婷婷综合视频 | www.久久91 | 美女免费黄网站 | 免费又黄又爽视频 | 一区二区影院 | av线上免费观看 | 日韩超碰在线 | 欧美精品一区二区三区四区在线 | 99久高清在线观看视频99精品热在线观看视频 | 成人片在线播放 | 久久av伊人 | 成人黄色毛片视频 | 久久精品二区 | 超碰在线97国产 | 天天干夜夜爱 | 在线观看av免费观看 | 免费久草视频 | 人人看黄色| 中文字幕a在线 | 91色网址| 婷婷久久五月天 | japanese黑人亚洲人4k | 日韩欧美高清在线 | 天天插视频 | 久久视频在线免费观看 | 99精品美女 | 日韩免费成人 | 国产视频高清 | 久久久91精品国产一区二区三区 | 欧美成人免费在线 | www.成人精品 | 97精品伊人 | 人人爽网站 | 精品字幕在线 | 激情久久久久久久久久久久久久久久 | 91欧美国产 | 免费特级黄毛片 | 色婷婷亚洲婷婷 | 免费看毛片在线 | 久久精品五月 | 亚洲综合成人专区片 | 欧美在线aaa | 国产精品99在线播放 | 丁香狠狠 | 国产精品久久久久三级 | 一区二区三区免费在线观看视频 | 在线视频日韩 | 91最新在线视频 | 欧日韩在线视频 | 99精品国产一区二区三区不卡 | 视频一区亚洲 | 亚洲免费色 | 欧美一级视频一区 | 在线高清一区 | 国产精品1区2区3区 久久免费视频7 | 爱av在线网 | 中文字幕在线视频网站 | 国产精品一区免费观看 | 国产精品自在线拍国产 | 色综合天天色综合 | 91亚洲永久精品 | 国产精成人品免费观看 | 国产精品一区在线观看你懂的 | 日韩a在线观看 | 国产视频欧美视频 | 日韩久久精品一区二区 | 日韩精品免费一区二区三区 | www.777奇米| av久久在线 | 伊人网av| 国产系列在线观看 | 日日操天天操狠狠操 | 一本大道久久精品懂色aⅴ 五月婷社区 | 欧美福利在线播放 | 色哟哟国产精品 | 色久av| 亚洲 欧美 日韩 综合 | 国产精品久久久久亚洲影视 | 日韩和的一区二在线 | 精品中文字幕在线播放 | 91日韩免费 | www.人人干| 中国一级片免费看 | 91资源在线观看 | 国产一区二区高清 | 国产在线国产 | 天天草天天草 | 成人久久久久久久久久 | 欧美 日韩精品 | 国产精品乱码久久久久久1区2区 | 欧美日韩视频免费看 | 4438全国亚洲精品在线观看视频 | 日本中文字幕在线电影 | 久久人人爽爽人人爽人人片av | 999久久国产 | 三级黄色网址 | 久久99亚洲精品久久久久 | av久久久 | 91在线免费播放视频 | 超碰在97 | 国产成人精品亚洲精品 | 精品亚洲网 | 亚洲午夜精品一区 | 黄色看片| 超碰在线公开免费 | 精品在线观 | 在线观看免费中文字幕 | 国产91av视频在线观看 | a级国产乱理伦片在线播放 久久久久国产精品一区 | 国产伦精品一区二区三区无广告 | 亚洲免费av电影 | 天天插天天干天天操 | 成人精品一区二区三区中文字幕 | 97超碰在线资源 | 国产美女久久久 | 91最新视频 | 国产视频精品视频 | 三级av在线 | 在线观看 亚洲 | 欧美综合国产 | www.午夜视频 | 国产精品密入口果冻 | 在线免费观看视频你懂的 | 日日干网| 国产成人精品一区二区三区 | 国产免费又粗又猛又爽 | 中文字幕视频一区二区 | 精品一区欧美 | 四虎国产精品永久在线国在线 | 97超碰资源站| 91福利社区在线观看 | 国产一级性生活视频 | 美女免费视频一区 | 色吧久久| 国产永久免费高清在线观看视频 | 亚洲电影av在线 | 欧美一级性视频 | 国产福利小视频在线 | 91久久国产综合精品女同国语 | 黄色成人av在线 | 亚洲欧美国产精品va在线观看 | 国产精品18久久久久vr手机版特色 | 免费在线观看午夜视频 | 成年人免费电影在线观看 | 亚洲区精品视频 | 超碰成人免费电影 | 成人在线观看日韩 | 欧美日韩精品在线 | 国产不卡一 | 天天综合导航 | 久久久国产成人 | 色婷婷一区 | 五月天天色 | 天天弄天天干 | 免费中文字幕在线观看 | 国产精品久久久久久久99 | 久草视频在线资源站 | 国产99久久九九精品免费 | 国产精品在线看 | 久久伦理网 | 国产在线不卡一区 | 波多野结衣小视频 | 91豆麻精品91久久久久久 | 又长又大又黑又粗欧美 | av夜夜操 | 麻豆免费看片 | 天天狠狠 | 手机看国产毛片 | 在线看片中文字幕 | 精品99久久久久久 | 在线免费观看黄网站 | 91亚洲精品国偷拍自产在线观看 | 成人av教育 | 久久免费99 | 波多野结衣在线视频免费观看 | 中文字幕国产 | 亚洲精品一区二区三区四区高清 | 亚洲色视频 | 日韩亚洲国产精品 | 日日夜夜网 | 久久久综合九色合综国产精品 | 国产欧美综合在线观看 | 91精品欧美一区二区三区 | 日本夜夜草视频网站 | 国产成人av综合色 | 韩国一区二区三区在线观看 | 911国产在线观看 | 黄色成人av | www国产亚洲精品久久麻豆 | 免费成人在线观看 | 欧美极品裸体 | 久久伊人五月天 | 九九免费精品视频 | 在线看成人 | 久久精品国产一区 | 国产男女无遮挡猛进猛出在线观看 | 五月天久久综合网 | 久久久久国产精品午夜一区 | 中文字幕一区二区三区乱码在线 | 91丨九色丨蝌蚪丨老版 | 中文字幕日本在线观看 | 国产精品成人一区二区三区 | 色www精品视频在线观看 | 久久精品91视频 | 亚洲一区欧美激情 | 欧美a√大片| 91精品麻豆 | 国产精品一区二区久久精品 | 成人 亚洲 欧美 | 69热国产视频 | a级成人毛片 | 中文字幕日韩免费视频 | 日本女人b | 亚洲激情视频 | 亚洲成人频道 | 视频一区二区三区视频 | 四虎影视精品永久在线观看 | 国产精品久久久久久久av电影 | caobi视频| 天天操综 | 欧美一二三区播放 | 欧美性生爱 | 欧美一级视频免费 | 国产 在线 高清 精品 | 久草视频一区 | 国产精品1区2区3区 久久免费视频7 | 西西444www| 91麻豆网| 久草精品视频在线观看 | 99re8这里有精品热视频免费 | 亚洲国产网站 | 天天天综合网 | 国产精品免费观看在线 | 中文字幕一区二 | 91网页版免费观看 | 人人干人人草 | h动漫中文字幕 | 综合久久久久久久 | 三级小视频在线观看 | 国产第一二区 | 久久亚洲视频 | 亚洲精品久久视频 | 欧美一区二区三区免费看 | 一区二区三区四区五区在线 | 国产人成免费视频 | 国产玖玖精品视频 | 91麻豆操 | 亚洲伊人天堂 | 日韩精品一区二区不卡 | 免费看精品久久片 | 久热香蕉视频 | 日韩理论在线 | 在线观看日韩国产 | 91精品久久久久久 | 欧美性受极品xxxx喷水 | 91成品人影院 | 欧美成人视 | 69av免费视频 | 免费在线激情视频 | 一区二区三区在线观看免费视频 | 国产精品国产精品 | 99久久综合国产精品二区 | 在线观看视频在线 | 国产精品久久久久久久久久了 | 黄色电影小说 | 日韩精品首页 | 国产精品久久久久毛片大屁完整版 | 久久久精品福利视频 | 久久综合成人网 | 中文字幕久久精品 | 成人午夜毛片 | 五月天久久精品 | 高潮毛片无遮挡高清免费 | 国产69精品久久久久99尤 | 91成人免费观看视频 | 日女人免费视频 | 国产在线播放一区二区三区 | 成人高清在线观看 | av再线观看 | 丁香国产视频 | 97碰在线视频 | 激情av在线资源 | 国产3p视频 | 999视频精品 | 天天干天天操天天爱 | 东方av在| 久久久久久毛片精品免费不卡 | 精品久久免费看 | 8x成人在线 | 一本一本久久a久久精品综合 | 国产一区二区在线免费视频 | av大全在线免费观看 | av手机在线播放 | 九九视频免费观看视频精品 | 不卡精品视频 | 国产精品私人影院 | 激情av一区二区 | 国产成人精品亚洲a | 狠狠干成人综合网 | 九草在线观看 | 91av视频在线观看免费 | 99久久这里有精品 | 色一级片 | 日韩城人在线 | 亚洲视频免费 | 亚洲综合激情网 | 91黄色免费网站 | 久久久久国产精品视频 | 在线视频日韩一区 | 中文字幕成人在线 | 天天天天色射综合 | 综合久久网站 | 亚洲国产精品传媒在线观看 | 成人免费视频网站在线观看 | 免费在线观看污 | 日韩在线观看你懂的 | 麻豆视传媒官网免费观看 | 欧美日韩亚洲第一页 | 亚洲欧洲精品一区 | 国产亚洲成人网 | 人人视频网站 | 久久精品免视看 | www.黄色片.com | 成人中文字幕av | 国产色综合天天综合网 | 日日爽天天爽 | 精品女同一区二区三区在线观看 | 国产小视频在线看 | 欧美另类69 | 婷婷久久综合网 | 国产91精品看黄网站 | japanese黑人亚洲人4k | 亚洲在线精品视频 | 九九热视频在线 | 一级黄色片网站 | www.五月天 | 中文字幕在线观看完整版电影 | 免费色av | 免费av网址大全 | 成人在线免费视频 | 狠狠久久 | 日韩一级电影在线观看 | 五月天高清欧美mv | 99久久超碰中文字幕伊人 | 中文字幕超清在线免费 | 麻豆小视频在线观看 | 黄网站www| 亚洲国产中文字幕 | 国产精品一区久久久久 | 狠狠色噜噜狠狠 | 亚洲三区在线 | 五月天婷亚洲天综合网鲁鲁鲁 | av大全在线免费观看 | 韩国精品福利一区二区三区 | 手机在线黄色网址 | 伊人五月婷| 久久精品视频中文字幕 | 青春草免费视频 | 久草电影在线 | 国产97视频在线 | 在线播放 日韩专区 | 狠狠地操 | 亚洲精品一区二区三区在线观看 | 成人国产精品免费 | 欧美一进一出抽搐大尺度视频 | 午夜精品一区二区三区在线播放 | 久草在线视频网站 | 玖玖视频国产 | 亚洲少妇激情 | 东方av免费在线观看 | 狠狠色噜噜狠狠狠狠2022 | 免费看91的网站 | av中文字幕在线观看网站 | 国产拍揄自揄精品视频麻豆 | 福利视频一二区 | 亚洲国产精品va在线看黑人 | 欧美激情精品久久久久久免费 | 片网址 | avlulu久久精品 | 国产成人一区二区三区久久精品 | 99久久婷婷国产精品综合 | 免费a v在线 | 在线免费看黄色 | 国产精品1区2区 | 香蕉日日 | 91插插插免费视频 | 日韩视频免费观看高清完整版在线 | 亚洲精品在线视频网站 | 视频一区在线免费观看 | 福利视频入口 | 91黄色免费看 | 亚洲另类xxxx| 欧美小视频在线 | 91黄色在线视频 | 曰韩在线 | 中文字幕乱码电影 | 激情 婷婷 | 天天操综合网站 | 毛片网免费 | 国产一区在线不卡 | av黄色大片| 色婷婷狠狠操 | 五月天激情在线 | 日产av在线播放 | 久草热久草视频 | 亚州视频在线 | 久久另类小说 | 久久夜av| 亚洲欧洲精品在线 | 日本久久久久久久久久 | 一级片在线| 亚洲国产一区在线观看 | 最新中文字幕在线资源 | 久久久久久久久久久久久久av | 免费在线视频一区二区 | 色婷婷狠狠五月综合天色拍 | 欧美日韩在线观看一区二区三区 | 久久国产精品久久w女人spa | 亚洲 成人 一区 | 天天干天天做 | 精品不卡视频 | 男女免费av | 亚洲一区日韩在线 | 日韩城人在线 | 亚洲视频专区在线 | 国产看片免费 | 超碰人人射 | 黄色亚洲大片免费在线观看 | 国产精品1000 | 女人18精品一区二区三区 | 国产98色在线 | 日韩 | 国产999精品久久久影片官网 | 中文字幕一区三区 | 欧美精品一区二区蜜臀亚洲 | 黄色毛片一级 | 欧美一区二区三区特黄 | 最近中文字幕大全中文字幕免费 | 日韩三级精品 | 天天天天天天天操 | 亚洲成av人片在线观看 | 在线精品一区二区 | 亚洲国产色一区 | 天天综合网在线观看 | 日日添夜夜添 | 亚洲视频观看 | 一性一交视频 |