Rockchip系列之浅度分析UART接口系列(1)

本文涉及的产品
视频直播,500GB 1个月
简介: Rockchip系列之浅度分析UART接口系列(1)

本篇文章是基于Rockchip 公开文档<UART开发指南>基础框架之上, 我自己增加一些内容 , 并验证了部分功能。


该文章和文档适合搞driver和硬件的人看的 , 基本rockchip 的uart很少去改动 用默认的就行。

 

第4部分的测试 我没用官方的(没找到) , 然后自己搞了个

测试程序之UART 232/485适用于Android/Linux_一歲抬頭的博客-CSDN博客

1. 功能特点

Rockchip UART (Universal Asynchronous Receiver/Transmitter) 基于16550A串口标准,完整模块支持以下功能:

  • 支持5、6、7、8 bits数据位。
  • 支持1、1.5、2 bits停止位。
  • 支持奇校验和偶校验,不支持mark校验和space校验。
  • 支持接收FIFO和发送FIFO,一般为32字节或者64字节。
  • 支持最高4M波特率,实际支持波特率需要芯片时钟分频策略配合。
  • 支持中断传输模式和DMA传输模式。
  • 支持硬件自动流控,RTS+CTS。

下面是关于UART的一些关键字的详细解释:

关键字

解释

UART

UART (Universal Asynchronous Receiver/Transmitter) 是一种通用异步收发器,用于串行数据通信。它是一种常见的串口通信协议,用于将数据以字节的形式在设备和外部设备之间进行传输。

16550A

16550A是一种常见的串口控制器芯片,用于实现UART通信。它是一种标准的串口控制器,提供了数据位、停止位、校验位、波特率等参数的设置,并具有FIFO缓冲区、中断传输模式、硬件流控等功能。

数据位

数据位是指在UART通信中每个字节中用于传输数据的位数。常见的数据位数包括5位、6位、7位和8位,表示一个字节中所包含的二进制位数。不同的数据位数可以用于传输不同范围的数据。

停止位

停止位是在UART通信中用于标识一个数据帧的结束的位。常见的停止位数包括1位、1.5位和2位。停止位之后可能会有奇偶校验位,然后是下一个数据帧的起始位。停止位的设置有助于接收端正确解析数据帧。

奇校验和偶校验

奇校验和偶校验是一种在UART通信中用于检测数据传输错误的校验方式。在奇校验中,校验位被设置为使整个数据帧中“1”的位数(包括数据位和校验位)为奇数;在偶校验中,校验位被设置为使整个数据帧中“1”的位数为偶数。校验位有助于验证数据的完整性和准确性。

FIFO

FIFO (First In, First Out) 是一种缓冲区,用于在UART通信中临时存储数据。接收FIFO用于存储接收到的数据字节,发送FIFO用于存储待发送的数据字节。FIFO的使用可以提高数据传输的效率,减少CPU的负载。

波特率

波特率是UART通信中数据传输速率的衡量单位,表示每秒传输的位数。常见的波特率包括9600、115200等,数值越大表示传输速率越快。发送端和接收端的波特率必须保持一致,以确保数据的正确传输。

中断传输模式

中断传输模式是UART通信中一种数据传输方式,通过中断来触发数据的接收和发送。在接收到数据后,UART会产生一个接收中断,通知处理器读取接收FIFO中的数据;在发送完数据后,UART会产生一个发送中断,通知处理器继续发送下一个数据。中断传输模式可以减少CPU的轮询负载。

DMA传输模式

DMA (Direct Memory Access) 是一种数据传输方式,通过DMA控制器直接将数据从内存中复制到UART的发送FIFO或从UART的接收FIFO复制到内存中,而不需要CPU的介入。DMA传输模式可以减轻CPU的负载,提高数据传输的效率。

硬件自动流控

硬件自动流控是一种通过硬件信号来控制数据传输的方式。在UART通信中,使用RTS (Request to Send) 和CTS (Clear to Send) 引脚来实现硬件自动流控。当发送FIFO中的数据量超过阈值时,UART会通过拉高RTS引脚来通知对方停止发送数据,接收FIFO中的数据量低于阈值时,UART会通过CTS引脚来允许对方发送数据。硬件自动流控可以避免数据的丢失和溢出。

串口唤醒系统

串口唤醒系统是一种功能,用于在系统待机时保持串口打开,并将串口中断设置为唤醒源。当有数据到达时,串口中断会唤醒系统。串口唤醒系统可以用于实现低功耗的数据传输和远程唤醒功能。

ttySx

ttySx 是Linux系统中用于表示串口设备的特殊文件。x是串口的编号,例如ttyS0表示第一个串口设备,ttyS1表示第二个串口设备,以此类推。在Linux系统中,可以通过读写ttySx文件来进行串口通信。

ttyFIQ0

ttyFIQ0 是在Rockchip平台上将UART配置为控制台时的特殊文件。在Rockchip SDK中,一般会将uart2配置为ttyFIQ0设备,用于作为控制台进行调试和日志输出。通过读写ttyFIQ0文件,可以进行控制台输入输出。

2. 作为普通串口

2.1 驱动路

在Linux kernel 3.10中,使用以下驱动文件:

  • drivers/tty/serial/rk_serial.c

在Linux kernel 4.4和Linux kernel 4.19中,使用8250串口通用驱动,以下为主要驱动文件:

  • drivers/tty/serial/8250/8250_core.c # 8250串口驱动核心
  • drivers/tty/serial/8250/8250_dw.c # Synopsis DesignWare 8250串口驱动
  • drivers/tty/serial/8250/8250_dma.c # 8250串口DMA驱动
  • drivers/tty/serial/8250/8250_port.c # 8250串口端口操作
  • drivers/tty/serial/8250/8250_early.c # 8250串口early console驱动
2.2 menuconfig配置

在不同版本的Linux kernel中,UART相关的menuconfig配置均在以下路径选项,选项说明十分详细,这里不再展开:

  • Device Drivers --->
  • Character devices --->
  • Serial drivers --->

建议使用Rockchip SDK中提供的UART默认配置。

2.3 dts配置

在不同版本的Linux kernel中,UART的dts配置典型如下所示。以下典型配置以Linux kernel 4.19 RK3568芯片为例,在rk3568.dtsi中:

uart0: serial@fdd50000 {
        compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart";
        reg = <0x0 0xfdd50000 0x0 0x100>;
        interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
        clocks = <&pmucru SCLK_UART0>, <&pmucru PCLK_UART0>;
        clock-names = "baudclk", "apb_pclk";
        reg-shift = <2>;
        reg-io-width = <4>;
        dmas = <&dmac0 0>, <&dmac0 1>;
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_xfer>;
        status = "disabled";
};
 
//.... 其他几个也是一样的。

在自己的xxxrk3568.dts中打开就ok了。

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

其中,uart1表示UART的设备节点,可以根据具体芯片和配置进行调整。

2.4 波特率配置

UART波特率的计算公式为:UART波特率 = 工作时钟源 / 内部分频系数 / 16。

当工作时钟源由24M晶振直接提供时,UART将使用内部分频系数得到需要的波特率。当工作时钟源由CRU模块通过PLL分频提供时,UART波特率一般为工作时钟源的1/16。UART实际允许配置的波特率和此波特率下数据传输的稳定性在软件上主要由UART工作时钟分频策略决定。

目前,UART驱动会根据配置的波特率大小自动获取需要的工作时钟频率。可以通过以下命令查询UART工作时钟频率:

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

Rockchip UART对常用的波特率,如115200、460800、921600、1500000、3000000、4000000等进行稳定支持。对于一些特殊的波特率,可能需要修改工作时钟分频策略才能支持。

2.5 使用DMA

UART使用DMA传输模式只有在数据量很大时才会明显减轻CPU负载的效果。一般情况下,和使用中断传输模式相比,UART使用DMA传输模式并不一定能提高数据传输速度。

因为现代CPU性能较高,传输瓶颈通常在外设。另外,启动DMA需要消耗额外的资源,而且由于UART数据长度不确定的特性,会使DMA传输效率下降。

因此,建议在一般情况下使用默认的中断传输模式。以下是使用DMA传输模式的打印信息:

  • 在DMA通道资源紧张的使用场景下,可以考虑关闭TX的DMA传输。
2.6 使用硬件自动流控

UART使用硬件自动流控时,需要确保UART驱动使能硬件自动流控功能,并在dts中已经切换cts和rts流控引脚的iomux。建议在高波特率(1.5M波特率及以上)和大数据量的场景下使用硬件自动流控,即使使用四线UART。

2.7 使用串口

唤醒系统

串口唤醒系统功能是在系统待机时,串口保持打开,并将串口中断设置为唤醒源。使用时需要在dts中增加以下参数。注意,串口唤醒系统需要同时修改trust固件,请联系Rockchip以获取支持。

&uart1 {
    wakeup-source;
};
2.8 设备注册

在dts中使能UART后,能在系统启动的log中看到设备正常注册的打印信息。

普通串口设备将根据dts中的aliases对串口进行编号,对应注册成ttySx设备。dts中的aliases如下所示:

aliases {
   serial0 = &uart0;
   serial1 = &uart1;
   serial2 = &uart2;
   serial3 = &uart3;
   serial4 = &uart4;
   serial5 = &uart5;
   serial6 = &uart6;
   serial7 = &uart7;
   serial8 = &uart8;
   serial9 = &uart9;
}

如果需要将uart3注册成ttyS1,可以进行以下修改:

aliases {
    serial0 = &uart0;
    serial1 = &uart3;
    serial2 = &uart2;
    serial3 = &uart1;
    ...
}

3. 作为控制台

3.1 驱动路径

Rockchip UART作为控制台时,使用fiq_debugger流程。Rockchip SDK一般会将uart2配置为ttyFIQ0设备。使用以下驱动文件:

  • drivers/staging/android/fiq_debugger/fiq_debugger.c # 驱动文件
  • drivers/soc/rockchip/rk_fiq_debugger.c # kernel 4.4及之后的平台实现
  • arch/arm/mach-rockchip/rk_fiq_debugger.c # kernel 3.10平台实现
3.2 menuconfig配置

在不同版本的Linux kernel中,fiq_debugger相关的menuconfig配置均在以下路径选项。建议使用Rockchip SDK默认配置。

  • Device Drivers --->
  • [*] Staging drivers --->
  • Android --->
3.3 dts配置

以Linux kernel 4.19 RK3568为例,在dts中配置fiq_debugger节点如下。注意,fiq_debugger和普通串口互斥,使能fiq_debugger节点后必须禁用对应的普通串口uart节点。

# 19 "arch/arm64/boot/dts/rockchip/rk3568-android.dtsi"
 fiq-debugger {
  compatible = "rockchip,fiq-debugger";
  rockchip,serial-id = <2>;
  rockchip,wake-irq = <0>;
 
  rockchip,irq-mode-enable = <1>;
  rockchip,baudrate = <115200>;
  interrupts = <0 252 8>;
  pinctrl-names = "default";
  pinctrl-0 = <&uart2m0_xfer>;
  status = "okay";
 };
 
&uart2 {
    status = "disabled";
};

其中,rockchip,serial-id表示使用的UART编号,可以根据具体配置调整。rockchip,irq-mode-enable配置为1使用irq中断,配置为0使用fiq中断。interrupts配置辅助中断,保持默认即可。

3.4 parameter.txt配置

如果使用Linux kernel 3.10和Linux kernel 4.4,需要在parameter.txt文件中指定控制台相关的命令,例如:

CMDLINE: console=ttyFIQ0 androidboot.console=ttyFIQ0 
//虽然但是 我没找到这个 我的文件内容是:
CMDLINE:mtdparts=rk29xxnand:0x00002000@0x00002000(security) ......

4. 驱动调试

Rockchip UART调试提供一个测试程序ts_uart.uart和两个测试用文件send_0x55和send_00_ff,该程序可以从Rockchip FAE处获取。

我没找到rk提供的测试文件 , 不过我自己搞了个<>测试程序也是一样的

将测试程序通过adb工具放在开发板上一个可执行的路径下,以下放在data路径:

adb push ts_uart.uart /data
adb push send_0x55 /data
adb push send_00_ff /data

修改测试程序权限:

adb shell
chmod +x /data/ts_uart.uart

使用以下命令可以获取程序帮助:

./data/ts_uart.uart
4.1 测试发送

测试发送的命令如下,send_0x55和send_00_ff为发送的文件。发送成功后,可以通过USB转UART小板连接PC端,使用PC端串口调试工具验证。

adb root
adb remount
adb shell
./data/ts_uart.uart s ./data/send_0x55 1500000 0 0 0 /dev/ttyS1
./data/ts_uart.uart s ./data/send_00_ff 1500000 0 0 0 /dev/ttyS1
4.2 测试接收

测试接收的命令如下,receive_0x55为接收的文件。可以使用PC端串口调试工具发送数据,测试程序将自动检测接收的数据。

adb root
adb remount
adb shell
./data/ts_uart.uart r ./data/receive_0x55 1500000 0 0 0 /dev/ttyS1
4.3 测试内部自发自收

测试内部自发自收的命令如下。按下Ctrl+C停止测试,可以观察结束时的日志,比较发送和接收的数据是否一致

adb root
adb remount
adb shell
./data/ts_uart.uart m ./data/send_0x55 1500000 0 0 0 /dev/ttyS1

如果测试失败,说明当前串口存在问题或者有其他程序正在使用同一个串口。可以使用以下命令查看哪些程序打开了这个串口:

lsof | grep ttyS1
4.4 测试流控

验证CTS流控,先手动拉高CTS引脚电平,再使用以下命令发送数据。当CTS电平被拉高时,发送数据会被阻塞。当释放CTS引脚电平为低电平时,被阻塞的数据会完成发送。

验证RTS流控,通过测量RTS引脚电平是否能够正常拉高和拉低来确认。

adb root
adb remount
adb shell
./data/ts_uart.uart s ./data/send_0x55 1500000 1 0 0 /dev/ttyS1

本文档介绍了Rockchip UART的基本配置和使用方式,包括作为普通串口和控制台的设置。可以根据实际需求,按照指南进行配置和调试 , 如果有啥问题 欢迎留言 欢迎三连。

相关文章
|
4月前
|
Java Android开发
Rockchip系列之客制化GPIO接口应用部分(5)
Rockchip系列之客制化GPIO接口应用部分(5)
44 0
|
4月前
|
Linux API Android开发
Rockchip系列之客制化GPIO接口Hardware部分(3)
Rockchip系列之客制化GPIO接口Hardware部分(3)
67 0
|
4月前
|
存储 Android开发
Rockchip系列之客制化GPIO接口Driver部分(2)
Rockchip系列之客制化GPIO接口Driver部分(2)
60 0
|
4月前
|
内存技术
【HARDWARE】 --- SPI接口协议介绍与应用说明
【HARDWARE】 --- SPI接口协议介绍与应用说明
144 3
|
Perl
PYNQ-关于PYNQ的GPIO的使用(RPI接口和arduino接口)或者常用的IO设备(如UART SPI IIC TIMER)
PYNQ-关于PYNQ的GPIO的使用(RPI接口和arduino接口)或者常用的IO设备(如UART SPI IIC TIMER)
611 0
PYNQ-关于PYNQ的GPIO的使用(RPI接口和arduino接口)或者常用的IO设备(如UART SPI IIC TIMER)
|
25天前
|
编解码 数据格式
IMX6ULL开发板spi OLED驱动
【8月更文挑战第24天】本文档介绍在IMX6ULL开发板上实现SPI接口OLED显示器驱动的步骤。首先需正确连接OLED至开发板的SPI接口,包括时钟(SCLK)、数据(MOSI)及片选(CS)等线路。理解SPI协议与OLED规格也很关键:SPI为同步串行通信,涉及主从设备交互;OLED参数如分辨率、颜色深度等须明确。接下来配置IMX6ULL的SPI控制器,通过设备树设定时钟频率、数据宽度等参数,并加载内核驱动。最后编写驱动程序,初始化SPI设备、发送控制命令与数据以完成OLED初始化,并实现文本或图像的显示功能。
|
3月前
|
开发者
【经典案例】使用HAL库配置STM32F407的SPI外设
在嵌入式系统开发中,STM32F407是一款广泛应用的微控制器,而SPI(Serial Peripheral Interface)是一种常用的通信接口。本文将详细介绍如何使用STM32的硬件抽象层(HAL)库配置STM32F407的SPI外设,并提供完整的代码示例。
243 1
|
2月前
|
传感器 编解码 API
【STM32开发入门】温湿度监测系统实战:SPI LCD显示、HAL库应用、GPIO配置、UART中断接收、ADC采集与串口通信全解析
SPI(Serial Peripheral Interface)是一种同步串行通信接口,常用于微控制器与外围设备间的数据传输。SPI LCD是指使用SPI接口与微控制器通信的液晶显示屏。这类LCD通常具有较少的引脚(通常4个:MISO、MOSI、SCK和SS),因此在引脚资源有限的系统中非常有用。通过SPI协议,微控制器可以向LCD发送命令和数据,控制显示内容和模式。
|
4月前
|
传感器
imx6ull开发板i2c应用编程读取AP3216c传感器数据
imx6ull开发板i2c应用编程读取AP3216c传感器数据
64 0
|
XML 测试技术 网络安全
开发工具:USB转IIC/I2C/SPI/UART适配器模块可编程开发板
总的思路是通过USB或者UART接口发送一些协议字符串,由模块转换成上面几种接口的硬件时序电信号,实现与这几种接口芯片、设备的快速测试。 首先声明一下,大家都是搞硬件开发的,这几种接口当然是很简单的事,但有些时候对于一个新的设备或者芯片的测试,有个现成的工具当然更顺手,节省时间,也更可靠嘛。