跳到主要内容

串口

设备上的串口分两种,一种是普通串口,另外一种是通过转换芯片把SPI转换而成的串口。转换而成的串口和普通串口功能完全一致但是需要注意它们的设备文件名是不一样的。下面是两者的区别:

# 普通串口
root@firefly:~# ls /dev/ttyS*
ttyS0 ttyS1 ttyS2 ttyS3

# SPI转串口
root@firefly:~# ls /dev/ttysWK*
ttysWK0 ttysWK1 ttysWK2 ttysWK3

10.1. 设置波特率

ttyS4 为例,查看串口波特率命令:

root@firefly:~# stty -F /dev/ttyS4
speed 9600 baud; line = 0;
-brkint -imaxbel

设置波特率命令:

# 设置波特率为 115200
root@firefly:~# stty -F /dev/ttyS4 ospeed 115200 ispeed 115200 cs8

# 查看确认是否已经修改
root@firefly:~# stty -F /dev/ttyS4
speed 115200 baud; line = 0;
-brkint -imaxbel
root@firefly:~#

10.2. 关闭回显

在做环回收发测试的时候回显功能会影响到我们的测试结果,所以在环回测试或者其他特殊情况下需要关闭回显。以下是关闭回显的命令:

# 关闭回显示
root@firefly:~# stty -F /dev/ttyS4 -echo -echoe -echok

# 查看所有功能的配置,检查是否已经关闭。“-” 号代表该功能已经关闭
root@firefly:~# stty -F /dev/ttyS4 -a | grep echo
isig icanon iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke -flusho -extproc

10.3. 发送接收原始数据

在实际应用中实际发送数据和我们希望发送的数据可能存在差别,例如多了回车或者其他特殊字符。利用 stty 可以把发送接收设置成 raw 模式确保发送接收的是原始数据,以下是设置命令:

root@firefly:~# stty -F /dev/ttyS4 raw

10.4. 工作模式

串口有 2 种工作模式分别是中断模式和 DMA 模式。

10.4.1. 中断模式

内核默认把串口配置成中断模式所以不需要做任何修改。中断模式下传输速率比较快但是在传大量数据的时候很容易丢包或者出错,所以当数据量比较大的时候请不要使用中断模式。

10.4.2. DMA 模式

DMA 模式主要是传输大量数据的时候使用。内核会为串口提供一个缓存空间接收数据来尽量降低串口传输的丢包率。

注意: 缓存空间限默认大小为 8K 如果一次传输超过缓存大小就会丢包,所以使用 DMA 模式的话需要发送端需要分包发送。

设备树文件配置

&uart4 {
status = "okay";
+ dmas = <&dmac_peri 8>, <&dmac_peri 9>;
+ dma-names = "tx", "rx";
};

DMA 模式并不能提高传输速率,相反因为需要缓存,传输速率会有所下降,所以如果不是需要传输大量数据的话不要使用 DMA 模式。

10.5. 流控

不管是中断模式还有 DMA 模式都无法保证数据传输万无一失,因为长时间传输大量数据的时候 DDR、CPU 变频或者占用率过高都可能导致上层处理数据不及时导致丢包,这个时候就需要是用流控了。流控分两种,一种是软件流控另一种为硬件流控,下面只介绍硬件流控的使用。

10.5.1. 硬件支持

硬件流控需要有硬件支持,设备的串口 CTXRTX 脚需要和远端设备相连。

注意: 设备不是所有串口都支持硬件流控,请先从原理图上确认硬件是否支持。

10.5.2. 设备树文件配置

  • RK3568:

    uart3: serial@ff1b0000 { compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart"; reg = <0x0 0xff1b0000 0x0 0x100>; clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>; clock-names = "baudclk", "apb_pclk"; interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH 0>; reg-shift = <2>; reg-io-width = <4>; pinctrl-names = "default";

    • pinctrl-0 = <&uart3_xfer &uart3_cts &uart3_rts>;
      status = "disabled";

    };

  • RK3399:

    uart3: serial@ff1b0000 { compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart"; reg = <0x0 0xff1b0000 0x0 0x100>; clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>; clock-names = "baudclk", "apb_pclk"; interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH 0>; reg-shift = <2>; reg-io-width = <4>; pinctrl-names = "default";

    • pinctrl-0 = <&uart3_xfer &uart3_cts &uart3_rts>;
      status = "disabled";

    };

  • RK3288:

    uart4: serial@ff1c0000 { compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; reg = <0x0 0xff1c0000 0x0 0x100>; interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; reg-io-width = <4>; clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>; clock-names = "baudclk", "apb_pclk"; pinctrl-names = "default";

    • pinctrl-0 = <&uart4_xfer>;
    • pinctrl-0 = <&uart4_xfer &uart4_cts &uart4_rts>;
      status = "disabled";

    };

10.5.3. 应用层设置

上层也需要打开流控的设置,这里介绍 stty 如何打开流控,如果你使用的是其他应用程序请从应用中打开流控。

# 打开流控
root@firefly:~# stty -F /dev/ttyS4 crtscts

# 检测流控是否打开,“-” 号代表该功能已经关闭
root@firefly:~# stty -F /dev/ttyS4 -a | grep crtscts
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal crtscts