通用接口(4)——UART & 485

39 篇文章 13 订阅
5 篇文章 0 订阅

struct termios

kernel/arch/arm64/include/generated/asm/termios.h
kernel/include/asm-generic/termios.h
kernel/include/uapi/asm-generic/termios.h
kernel/include/uapi/asm-generic/termbits.h

c_iflag c_oflag c_cflag c_lflag

struct termios {
        tcflag_t c_iflag;               /* input mode flags */
        tcflag_t c_oflag;               /* output mode flags */
        tcflag_t c_cflag;               /* control mode flags */
        tcflag_t c_lflag;               /* local mode flags */
        cc_t c_line;                    /* line discipline */
        cc_t c_cc[NCCS];                /* control characters */
};

速率

/* c_cflag bit meaning */
#define CBAUD   0010017
#define  B0     0000000         /* hang up */
#define  B50    0000001
#define  B75    0000002
#define  B110   0000003
#define  B134   0000004
#define  B150   0000005
#define  B200   0000006
#define  B300   0000007
#define  B600   0000010
#define  B1200  0000011
#define  B1800  0000012
#define  B2400  0000013
#define  B4800  0000014
#define  B9600  0000015
#define  B19200 0000016
#define  B38400 0000017
#define EXTA B19200
#define EXTB B38400
#define CSIZE   0000060
#define   CS5   0000000
#define   CS6   0000020
#define   CS7   0000040
#define   CS8   0000060
#define CSTOPB  0000100
#define CREAD   0000200
#define PARENB  0000400
#define PARODD  0001000
#define HUPCL   0002000
#define CLOCAL  0004000
#define CBAUDEX 0010000
#define    BOTHER 0010000
#define    B57600 0010001
#define   B115200 0010002
#define   B230400 0010003
#define   B460800 0010004
#define   B500000 0010005
#define   B576000 0010006
#define   B921600 0010007
#define  B1000000 0010010
#define  B1152000 0010011
#define  B1500000 0010012
#define  B2000000 0010013
#define  B2500000 0010014
#define  B3000000 0010015
#define  B3500000 0010016
#define  B4000000 0010017
#define CIBAUD    002003600000  /* input baud rate */
#define CMSPAR    010000000000  /* mark or space (stick) parity */
#define CRTSCTS   020000000000  /* flow control */
struct termios oldtio,newtio;
speed_t speed = B4000000;
tcgetattr(fd,&oldtio);
bzero(&newtio,sizeof(newtio));
newtio.c_cflag = speed|CS8|CLOCAL|CREAD;
newtio.c_cflag &= ~CSTOPB;
newtio.c_cflag &= ~PARENB;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
tcflush(fd,TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
tcgetattr(fd,&oldtio);

tcgetattr和tcsetattr

int tcgetattr(int fd, struct termios *termios_p);

tcgetattr函数用于获取与终端相关的参数。参数fd为终端的文件描述符,返回的结果保存在termios 结构体中,该结构体一般包括如下的成员:
tcflag_t c_iflag;
tcflag_t c_oflag;
tcflag_t c_cflag;
tcflag_t c_lflag;
cc_t c_cc[NCCS];

int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);

tcsetattr函数用于设置终端参数。函数在成功的时候返回0,失败的时候返回-1,并设置errno的值。参数fd为打开的终端文件描述符,参数optional_actions用于控制修改起作用的时间,而结构体termios_p中保存了要修改的参数。optional_actions可以取如下的值。
TCSANOW:不等数据传输完毕就立即改变属性。
TCSADRAIN:等待所有数据传输结束才改变属性。
TCSAFLUSH:等待所有数据传输结束,清空输入输出缓冲区才改变属性。
错误信息:
EBADF:非法的文件描述符。
EINTR:tcsetattr函数调用被信号中断。
EINVAL:参数optional_actions使用了非法值,或参数termios中使用了非法值。
ENOTTY:非终端的文件描述符。

串口流控

参考链接:
https://blog.csdn.net/u010591305/article/details/44747805

数据在两个串口之间传输时,常常会出现丢失数据的现象,或者两台计算机的处理速度不同,如台式机与单片机之间的通讯,
接收端数据缓冲区已满,则此时继续发送来的数据就会丢失。现在我们在网络上通过MODEM进行数据传输,这个问题就尤为突出。
流控制能解决这个问题,当接收端数据处理不过来时,就发出“不再接收”的信号,发送端就停止发送,直到收到“可以继续发送”的信号再发送数据。
因此流控制可以控制数据传输的进程,防止数据的丢失。 PC机中常用的两种流控制是硬件流控制(包括RTS/CTS、DTR/CTS等)和软件流控制XON/XOFF(继续/停止)。

hardware
Auto Flow Control
The UART can be configured to have a 16750-compatible Auto RTS and Auto CTS serial data flow control mode available. If FIFOs are not implemented, then this mode cannot be selected.When Auto Flow Control mode has been selected, it can be enabled with the Modem Control Register (MCR[5]). Following figure shows a block diagram of the Auto Flow Control functionality.

Auto RTS – Becomes active when the following occurs:

Auto Flow Control is selected during configuration
FIFOs are implemented
RTS (MCR[1] bit and MCR[5]bit are both set)
FIFOs are enabled (FCR[0]) bit is set)
SIR mode is disabled (MCR[6] bit is not set)

Auto CTS – becomes active when the following occurs:

Auto Flow Control is selected during configuration
FIFOs are implemented
AFCE (MCR[5] bit is set)
FIFOs are enabled through FIFO Control Register FCR[0] bit
SIR mode is disabled (MCR[6] bit is not set)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
software

代码路径

drivers/tty/serial/8250/8250.h
drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/8250/8250_dma.c 			dma实现
drivers/tty/serial/8250/8250_dw.c 			design ware ip相关操作
drivers/tty/serial/8250/8250_early.c 		early console实现
drivers/tty/serial/8250/8250_fsl.c
drivers/tty/serial/8250/8250.c
drivers/tty/serial/8250/8250_port.c 		端口相关的接口
drivers/tty/serial/earlycon.c 				解析命令行参数,并提供注册early con接口
kernel/include/uapi/linux/serial_reg.h

#define UART_MCR        4       /* Out: Modem Control Register */
#define UART_MCR_CLKSEL         0x80 /* Divide clock by 4 (TI16C752, EFR[4]=1) */
#define UART_MCR_TCRTLR         0x40 /* Access TCR/TLR (TI16C752, EFR[4]=1) */
#define UART_MCR_XONANY         0x20 /* Enable Xon Any (TI16C752, EFR[4]=1) */
#define UART_MCR_AFE            0x20 /* Enable auto-RTS/CTS (TI16C550C/TI16C750) */
#define UART_MCR_LOOP           0x10 /* Enable loopback test mode */
#define UART_MCR_OUT2           0x08 /* Out2 complement */
#define UART_MCR_OUT1           0x04 /* Out1 complement */
#define UART_MCR_RTS            0x02 /* RTS complement */
#define UART_MCR_DTR            0x01 /* DTR complement */

#define UART_FCR        2       /* Out: FIFO Control Register */
#define UART_FCR_ENABLE_FIFO    0x01 /* Enable the FIFO */
#define UART_FCR_CLEAR_RCVR     0x02 /* Clear the RCVR FIFO */
#define UART_FCR_CLEAR_XMIT     0x04 /* Clear the XMIT FIFO */
#define UART_FCR_DMA_SELECT     0x08 /* For DMA applications */
drivers/tty/serial/8250/8250.h

#define UART_CAP_AFE    (1 << 11)       /* MCR-based hw flow control */
void
serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
                          struct ktermios *old)
{
...
        /*
         * MCR-based auto flow control.  When AFE is enabled, RTS will be
         * deasserted when the receive FIFO contains more characters than
         * the trigger, or the MCR RTS bit is cleared.  In the case where
         * the remote UART is not using CTS auto flow control, we must
         * have sufficient FIFO entries for the latency of the remote
         * UART to respond.  IOW, at least 32 bytes of FIFO.
         */
        if (up->capabilities & UART_CAP_AFE && port->fifosize >= 32) {
                up->mcr &= ~UART_MCR_AFE;
                if (termios->c_cflag & CRTSCTS)
                        up->mcr |= UART_MCR_AFE;
        }

应用里面将termios->c_cflag置位CRTSCTS后,串口MCR寄存器就会打开auto flow control。

添加支持流控的uart节点

kernel/arch/arm64/boot/dts/rockchip/OK3399-C.dts

&uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
        status = "okay";
};

编写应用测试收发即可

485收发控制

TBC

==================================================

相关知识

RK3399 UART特性

最高支持4M波特率
UART0、3支持硬件自动流控
支持中断传输模式和DMA传输模式

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值