Jasonangel

V1

2023/05/03阅读:19主题:默认主题

UART 子系统

1、前言

UART:Universal Asynchronous Receiver/Transmitter,通用异步接收器/发送器。

串行接口 (Serial Interface)是指数据一位一位地顺序传送。区分于并行信号。

UART 包含 TTL 电平的串口和 RS232 电平的串口。TTL 电平是 3.3V 的,而 RS232 是负逻辑电平,它定义 +5 ~ +12V 为低电平,而 -12 ~ -5V 为高电平。

因为 UART 都是由 CPU、MCU 等控制器或专用芯片产生的,所以 UART 的原始电平一般为 TTL 电平即低电平 0V、高电平 3.3V 或 5V。所以,单独说 UART 指的就是 TTL 电平的异步串行通信协议。它有三根线,TX、RX 和 GND。

2、UART spec

起始位:每开始一次通信时发送方先发出一个逻辑”0”的信号(低电平),表示传输字符的开始。(总线空闲时为高电平)

数据位:数据位可以是5、6、7、8,9位等,构成一个字符(一般都是8位)。如ASCII码(7位),扩展BCD码(8位)。先发送最低位,最后发送最高位,‘0’低电平,‘1’高电平。

奇偶校验位:数据位加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校验数据传送的正确性。校验位其实是调整个数,串口校验分几种方式:

1、无校验(no parity)。
2、奇校验(odd parity):如果数据位中“1”的数目是偶数,则校验位为“1”,如果“1”的数目是奇数,校验位为“0”。
3、偶校验(even parity):如果数据为中“1”的数目是偶数,则校验位为“0”,如果为奇数,校验位为“1”。
4、mark parity:校验位始终为1(不常用)。
5、parity:校验位始终为0(不常用)。

停止位:高电平 1/1.5/2 bit。

空闲位:当总线处于空闲状态时,信号线的状态为‘1’即高电平,表示当前线路上没有数据传输。

3、Linux UART driver

采用的是 8250 通用驱动

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 接口

内核配置

Device Drivers --->
  Character devices --->
    Serial drivers --->
     [*] 8250/16550 and compatible serial support
     [ ] Support 8250_core.* kernel options (DEPRECATED)
     [*] Console on 8250/16550 and compatible serial port 8250串口开启 console 功能
     [ ] DMA support for 16550 compatible UART controllers
     (5) Maximum number of 8250/16550 serial ports //一般填最大串口数
     (5) Number of 8250/16550 serial ports to register at runtime //一般填最大串口数
     [ ] Extended 8250/16550 serial driver options
     [*] Support for Synopsys DesignWare 8250 quirks

关于 DMA 的使用

  1. 和中断传输模式相比,使用 DMA 并不一定能提高传输速度,相反可能略降低传输速度。
  2. 因为现在 CPU 的性能都很高,传输瓶颈在外设,而且启动 DMA 还会消耗额外的资源。
  3. 但整体上看中断模式会占用更多的 CPU 资源。只有传输数据量很大时,DMA 的使用对 CPU 负载的减轻效果才会比较明显。

使用 DMA 建议

  1. 如果外接的设备传输数据量不大,请使用默认的中断模式。
  2. 如果外接的设备传输数据量较大,可以使用 DMA。
  3. 如果串口没接自动流控脚,可以使用 DMA 作为 FIFO 缓冲,防止数据丢失

波特率

波特率 = 时钟源/16/DIV。(DIV 是分频系数)

9600、19200、38400、57600、115200、230400、460800、921600、1000000、1500000

cat /sys/kernel/debug/clk/clk_summary | grep uart

设置串口可唤醒系统

&uart0 {
  wakeup-source; //使能串口唤醒功能,作用是待机时不去关闭串口,并把串口中断设置为唤醒源
  status = "okay";
};

关掉串口打印功能

Device Drivers --->
  Character devices --->
    Serial drivers --->
      [ ] Console on 8250/16550 and compatible serial port

4、tty 子系统

由于终端种类繁多,为了使其具有统一的上层接口函数,Linux 系统对终端设备进行了总结抽象,总结其共性,抽象出共用的上层接口函数,采用分层的设计思想,将 tty 设备分成三层: tty 核心层,tty 线路规程以及 tty 驱动层。

从图中可以看出用户程序通过 open 、 read 等函数调用核心层,核心层可通过线路规程与 tty 驱动通信。如果数据不需要处理加工,核心层也可直接与 tty 驱动层进行数据的传输。

tty 驱动程序将数据格式化为硬件理解的形式,然后才将数据发送到硬件设备。在用户程序进行终端设备操作时,要调用核心层操作函数 file operations,实现了所以终端设备的 API 函数,是核心层的主要数据结构。

在链路层主要通过 tty_regiser_driver()函数注册线路规程,是链路层的核心函数。终端设备的主要工作是实现 tty_driver 结构体成员的填充,实现其成员函数。

5、波形解析

示例 1

串口输入字符 1,即数据 0x31。

0x31 --> 00110001B --> LSB(低位先发) --> 10001100B

波形解析:

起始位 0
数据位 10001100
停止位 1

波特率计算

50us/div >6bit/div (图中所得)波特率= 6 /5010^6 ~115200 bps

https://blog.csdn.net/a371132/article/details/90727740

分类:

后端

标签:

后端

作者介绍

Jasonangel
V1