瑞芯微|rk3568 uart快速上手

一、调试环境
平台:rk3568
kernel: 4.19.232
SDK: rk_android11.0_sdk
Board: rk3568-evb1-ddr4-v10
二、 rk3568 uart控制器
1. 特性:
rk3568 UART控制器特性如下:
- UART控制器通道:UART0~UART8 【datasheet好像写的有问题】
- 包含2组64字节的 FIFO,用于接收和传输
- 支持流控
- 支持速率 115.2Kbps, 460.8Kbps, 921.6Kbps, 1.5Mbps, 3Mbps, 4Mbps
- 支持5、6、7、8 bits数据位。
- 支持1、1.5、2 bits停止位。
- 支持奇校验和偶校验。
- 支持基于中断/DMA 模式
2. UART控制器架构

APB INTERFACE
处理器通过APB接口访问UART的数据,做控制,以及状态信息。
UART支持8、16和32位的APB数据总线宽度。Register block
负责UART的主要功能,包括控制、状态和中断产生。Modem Synchronization block
同步modem输入信号.FIFO block
负责FIFO控制和存储或向发送信号以控制外部RAM。Baud Clock Generator
收发比特率设置。Serial Transmitter
数据发送模块。Serial Receiver
数据接收模块。
3. 控制器驱动
瑞芯微提供sdk中已经提供了8250uart驱动。
以下为主要驱动文件:
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驱动
4. 设备树:
普通串口设备将会根据dts中的aliase来对串口进行编号,对应注册成ttySx设备。
dts中的aliases如下:
aliases {
serial0 = &uart0;
serial1 = &uart1;
serial2 = &uart2;
serial3 = &uart3;
......
@kernel\arch\arm64\boot\dts\rockchip\rk3568.dtsi
uart6: serial@fe6a0000 {
compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart";
reg = <0x0 0xfe6a0000 0x0 0x100>;
interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_UART6>, <&cru PCLK_UART6>;
clock-names = "baudclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
dmas = <&dmac0 12>, <&dmac0 13>;
pinctrl-names = "default";
pinctrl-0 = <&uart6m0_xfer>;
status = "disabled";
};
UART的板级dts配置只有以下参数允许修改:
- dma-names:
"tx" 打开tx dma
"rx" 打开rx dma
"!tx" 关闭tx dma
"!rx" 关闭rx dma - pinctrl-0:
&uart1m0_xfer 配置tx和rx引脚为iomux group 0
&uart1m1_xfer 配置tx和rx引脚为iomux group 1
&uart1m0_ctsn和&uart1m0_rtsn 配置硬件自动流控cts和rts引脚为iomux group 0
&uart1m1_ctsn和&uart1m1_rtsn 配置硬件自动流控cts和rts引脚为iomux group 1 - status:
"okay" 打开
"disabled" 关闭
引脚说明在下面定义:
以UART6为例:
@kernel\arch\arm64\boot\dts\rockchip\rk3568-pinctrl.dtsi
uart6 {
/omit-if-no-ref/
uart6m0_xfer: uart6m0-xfer {
rockchip,pins =
/* uart6_rxm0 */
<2 RK_PA3 3 &pcfg_pull_up>,
/* uart6_txm0 */
<2 RK_PA4 3 &pcfg_pull_up>;
};
/omit-if-no-ref/
uart6m0_ctsn: uart6m0-ctsn {
rockchip,pins =
/* uart6m0_ctsn */
<2 RK_PC0 3 &pcfg_pull_none>;
};
/omit-if-no-ref/
uart6m0_rtsn: uart6m0-rtsn {
rockchip,pins =
/* uart6m0_rtsn */
<2 RK_PB7 3 &pcfg_pull_none>;
};
/omit-if-no-ref/
uart6m1_xfer: uart6m1-xfer {
rockchip,pins =
/* uart6_rxm1 */
<1 RK_PD6 3 &pcfg_pull_up>,
/* uart6_txm1 */
<1 RK_PD5 3 &pcfg_pull_up>;
};
};
5. 使用硬件自动流控
UART使用硬件自动流控时,需要确保UART驱动使能硬件自动流控功能,且在dts中已经切换cts和rts流控引脚的iomux。
建议在高波特率(1.5M波特率及以上)、大数据量的场景下都使用硬件自动流控,即使用四线UART。
6. 使用串口唤醒系统
串口唤醒系统功能是在系统待机时串口保持打开,并且把串口中断设置为唤醒源。使用时需要在dts中增
加以下参数:
&uart1 {
wakeup-source;
};
注意,串口唤醒系统需要同时修改trust固件,请联系Rockchip以获取支持。
三、 移植
1. 修改设备树
sdk中UART默认并没有打开,所以我们只需要修改设备树就可以了。
下面以uart6为例,带流控:
/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dtsi
&uart6{
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&uart6m1_xfer >;
};
注意:
引脚选择有两种配置: m0、m1;
编写设备树之前,查看电路图先确认,
公板是m1。
只有m0支持流控,如果需要支持设置 pinctrl-0:
pinctrl-0 = <&uart6m0_xfer &uart6m0_ctsn &uart6m0_rtsn>;
重新编译烧录boot.img即可。
查看设备文件
rk3568_r:/ # ls /dev/ttyS*
/dev/ttyS6 /dev/ttyS8
其中ttyS8是给蓝牙使用。
2. 引脚复用问题:uart6与gmac0冲突
uart6引脚与以太网口Gmac0会有冲突:
@kernel\arch\arm64\boot\dts\rockchip\rk3568-pinctrl.dtsi
gmac0 {
/omit-if-no-ref/
gmac0_miim: gmac0-miim {
rockchip,pins =
/* gmac0_mdc */
<2 RK_PC3 2 &pcfg_pull_none>,
/* gmac0_mdio */
<2 RK_PC4 2 &pcfg_pull_none>;
};
…………………………
/omit-if-no-ref/
gmac0_rgmii_bus: gmac0-rgmii-bus {
rockchip,pins =
/* gmac0_rxd2 */
<2 RK_PA3 2 &pcfg_pull_none>,
/* gmac0_rxd3 */
<2 RK_PA4 2 &pcfg_pull_none>,
/* gmac0_txd2 */
<2 RK_PA6 2 &pcfg_pull_none_drv_level_2>,
/* gmac0_txd3 */
<2 RK_PA7 2 &pcfg_pull_none_drv_level_2>;
};
};
只需要禁用gmac0即可
/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dtsi
&gmac0 {
………………
phy-handle = <&rgmii_phy0>;
status = "disable";
};
3. 通过寄存器,查看引脚复用配置情况
uart6使用到的引脚如下:

1) GRF_GPIO1D_IOMUX_H
Address: Operational Base + offset (0x001C)

2) GRF_GPIO2A_IOMUX_L
Address: Operational Base + offset (0x0020)

3) GRF_GPIO2A_IOMUX_H
Address: Operational Base + offset (0x0024)

4) GRF_GPIO2B_IOMUX_H
Address: Operational Base + offset (0x002C)

5) GRF_GPIO2C_IOMUX_L
Address: Operational Base + offset (0x0030)

uart6寄存器配置对应位位置如下图所示:,

我们只设置m1引脚为uart6的收发引脚,m0引脚未设置
所以只有寄存器 0xFDC60000+0x1c 的 bit[11:4]为 33
四、测试
公板预留了UART2~UART7的接口(4根线),
一口君不会焊接线,所以直接找的硬件工程师把线连好,
我只负责测试。
板子上的测试程序,瑞芯微官方已经提供了: ts_uart.uart

该工具获取,见文章底部。
1. 移植ts_uart.uart
adb root
adb remount
adb push ts_uart.uart /bin
adb push send_0x55 /bin
adb push send_00_ff /bin
2. ts_uart.uart实用
1) 查看ts_uart.uart帮助信息:
rk3568_r:/ # ts_uart.uart
Use the following format to run the HS-UART TEST PROGRAM
ts_uart v1.1
For sending data:
./ts_uart <tx_rx(s/r)> <file_name> <baudrate> <flow_control(0/1)> <max_delay(0-100)> <random_size(0/1)>
tx_rx : send data from file (s) or receive data (r) to put in file
file_name : file name to send data from or place data in
baudrate : baud rate used for TX/RX
flow_control : enables (1) or disables (0) Hardware flow control using RTS/CTS lines
max_delay : defines delay in seconds between each data burst when sending. Choose 0 for continuous stream.
random_size : enables (1) or disables (0) random size data bursts when sending. Choose 0 for max size.
max_delay and random_size are useful for sleep/wakeup over UART testing. ONLY meaningful when sending data
Examples:
Sending data (no delays)
ts_uart s init.rc 1500000 0 0 0 /dev/ttyS0
loop back mode:
ts_uart m init.rc 1500000 0 0 0 /dev/ttyS0
receive, data must be 0x55
ts_uart r init.rc 1500000 0 0 0 /dev/ttyS0
2) 非流控read:
ts_uart.uart r init.rc 115200 0 0 0 /dev/ttyS6
3) 流控read:
ts_uart.uart r init.rc 115200 1 0 0 /dev/ttyS6
4) 非流控write:
ts_uart.uart s /data/send_0x55.0x55 115200 0 0 0 /dev/ttyS6
5) 流控write:
ts_uart.uart s /data/send_0x55.0x55 115200 1 0 0 /dev/ttyS6
五、编写自己的测试程序
下面是一口君自己编写的测试程序,可以实现简单的数据收发,
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<termios.h>
#include<string.h>
int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
{
struct termios newtio,oldtio;
if ( tcgetattr( fd,&oldtio) != 0)
{
perror("SetupSerial 1");
return -1;
}
bzero( &newtio, sizeof( newtio ) );
newtio.c_cflag |= CLOCAL | CREAD;
newtio.c_cflag &= ~CSIZE;
switch( nBits )
{
case 7:
newtio.c_cflag |= CS7;
break;
case 8:
newtio.c_cflag |= CS8;
break;
}
switch( nEvent )
{
case 'O':
newtio.c_cflag |= PARENB;
newtio.c_cflag |= PARODD;
newtio.c_iflag |= (INPCK | ISTRIP);
break;
case 'E':
newtio.c_iflag |= (INPCK | ISTRIP);
newtio.c_cflag |= PARENB;
newtio.c_cflag &= ~PARODD;
break;
case 'N':
newtio.c_cflag &= ~PARENB;
break;
}
switch( nSpeed )
{
case 2400:
cfsetispeed(&newtio, B2400);
cfsetospeed(&newtio, B2400);
break;
case 4800:
cfsetispeed(&newtio, B4800);
cfsetospeed(&newtio, B4800);
break;
case 9600:
cfsetispeed(&newtio, B9600);
cfsetospeed(&newtio, B9600);
break;
case 115200:
cfsetispeed(&newtio, B115200);
cfsetospeed(&newtio, B115200);
break;
case 460800:
cfsetispeed(&newtio, B460800);
cfsetospeed(&newtio, B460800);
break;
default:
cfsetispeed(&newtio, B9600);
cfsetospeed(&newtio, B9600);
break;
}
if( nStop == 1 )
newtio.c_cflag &= ~CSTOPB;
else if ( nStop == 2 )
newtio.c_cflag |= CSTOPB;
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 0;
tcflush(fd,TCIFLUSH);
if((tcsetattr(fd,TCSANOW,&newtio))!=0)
{
perror("com set error");
return -1;
}
// printf("set done!\n\r");
return 0;
}
int main(void)
{
int fd1;
char data[10] = "yikoupeng";
char buf[100]={0};
fd1 = open( "/dev/ttyS6", O_RDWR);
if (fd1 == -1)
exit(1);
nset = set_opt(fd1, 115200, 8, 'N', 1);
if (nset == -1)
{
exit(1);
}
printf("write start!\n");
write(fd1,data,strlen(data));
read(fd1,buf,sizeof(buf));
printf("rcv:%s\n",buf);
close(fd1);
return 0;
}
工具ts_uart.uart s获取
公众号后台回复:rxw
瑞芯微|rk3568 uart快速上手的更多相关文章
- 瑞芯微RK3399宣布系统开源,进入百余种行业市场!
集微网消息,2月24日瑞芯微官方突然宣布, Rockchip RK3399Linux系统开源!作为Rockchip旗舰级芯片,RK3399具有高性能.高扩展.全能型应用特性. 这一重磅消息立马刷爆朋友 ...
- Linux下更新瑞芯微固件
有这样的需求,是因为提供的BSP中是在windows下烧写的系统.我直接在linux下开发,每次编译后代码都要在windows下烧写,是一个很麻烦的事情.为了解决这个问题我尝试着用VirtualBox ...
- 9.7寸RK3188瑞芯微四核爱立顺M33平板电脑 - 深圳吉祥星晨科技有限公司 - 华强商情网
9.7寸RK3188瑞芯微四核爱立顺M33平板电脑 - 深圳吉祥星晨科技有限公司 - 华强商情网 欢迎加入 2000人超级QQ群,平板电脑行业交流群:221371451,平板电脑产品及报价群:5765 ...
- 瑞芯微发布最新旗舰应用处理器-RK3588
在瑞芯微电子第四届“开发者之春”大会上,瑞芯微推出了新一代8nm旗舰处理器-RK3588 这个芯片将采用8nm 制程工艺.基于A76+A55 内核组合,具备4K UI性能.8K VPU,拥有NPU2. ...
- 瑞芯微ROCK960 RK3399固件烧录总结
1 下载固件 进入瑞芯微ROCK960下载主页 https://www.96boards.org/documentation/consumer/rock/downloads/ 选择os固件, Debi ...
- 瑞芯微RK3399六核-迅为3399开发板介绍
迅为3399开发板基于瑞芯微的RK3399处理器设计,Rockchip RK3399是瑞芯微推出的一款低功耗.高性能的应用处理器芯片,该芯片基于Big.Little架构,即具有独立的NEON协同处理器 ...
- 瑞芯微RKnanC芯片处理器介绍
RKnanC是一种低成本.低功耗.高效率的数字多媒体芯片,它是基于ARM的低功耗处理器结构和硬件加速器.它是专为便携式音频产品应用,如MP3播放器等. RKnanC可以支持各种音频标准的解码,如MP3 ...
- 瑞芯微RK3188如何配置USB摄像头支持
- 瑞芯微RK3188摄像头相关参数的配置
- 瑞芯微ROCK960 RK3399烧录image后扩容rootfs
问题描述: RK3399开发板烧录官网提供的ubuntu镜像: Ubuntu 16.04 Server arm64(下载地址:https://www.96boards.org/documentatio ...
随机推荐
- 【ClickHouse】2:clickhouse基本语法
背景介绍: 有三台CentOS7服务器安装了ClickHouse HostName IP 安装程序 程序端口 centf8118.sharding1.db 192.168.81.18 clickhou ...
- 记一次win10 python -m http.server 启动后无法访问的经历
前言 最近需要在win10上使用python创建一个http文件服务(默认端口 8000),结果执行了 python3 -m http.server -b 0.0.0.0 后,发现服务跑起来了,但浏览 ...
- 树莓派4B-PCA9685驱动舵机
前言 不知道你们有没有遇到过这么一种情况,直接用树莓派的引脚输出PWM控制舵机,舵机是会出现抖动的.就算代码进行一定的时延迟优化还是会有影响的. 现在我们可以使用PCA9685这个模块去驱动舵机. P ...
- Mybatis 总结ResultMap的复杂对象查询
association:映射的是一个POJO类,处理一对一的关联关系 collection:映射的一个集合列表,处理的是一对多的关联关系 模版 <!--column不做限制,可以为任意表的字段, ...
- Django 自定义创建密码重置确认页面
要实现上述功能,你需要修改模板文件以添加"忘记密码"链接,并创建新的视图函数来处理密码丢失修改页面.验证和密码修改.下面是你可以进行的步骤: 1. 修改模板文件 在登录页面的表单下 ...
- [oeasy]python0074_修改字体背景颜色_background_color_背景色
修改背景色 回忆上次内容 上次将asciiart和颜色一起来玩 7 种基本色 变化多端 不过到目前为止 改的 都是前景色 背景色可以修改吗? 重温参数 具体动手试试 print("\033[ ...
- 题解:P10417 [蓝桥杯 2023 国 A] 第 K 小的和
分析 这道题不是板子么. 先对序列排序,然后二分答案,设当前答案为 \(x\),枚举 \(a\) 中的数,然后二分查找 \(b\) 中不大于 \(x-a\) 的元素个数,累加判断是否不大于 \(k\) ...
- C# EF Core 后端代码已定义的用户实体,如何扩展字段?
注:"2020中国.NET开发者大会"上学习到的开发技巧, 记录下来 1.问题 后端代码已定义的用户实体,如下: public class UserEntity { public ...
- 网络基础 Modbus协议学习总结
协议简介 Modbus协议,首先从字面理解它包括Mod和Bus两部分,首先它是一种bus,即总线协议,总线就意味着有主机,有从机,这些设备在同一条总线上. Modbus支持单主机,多个从机,最多支持2 ...
- idea快捷键Ctrl+alt+m:如何快速抽离部分方法
Ctrl+alt+m 效果如下图