rk3399 io工具的使用示例

本文档详细介绍了如何在RK平台上查询和操作IO寄存器,包括通过IO工具获取寄存器信息,理解寄存器地址与功能位的对应关系,以及如何使用IO命令进行写入操作。内容涵盖了从TRM规格书获取信息,到实际串口或ADB命令的执行,展示了对GPIO3_C1(MAC_TXCLK)寄存器的查询过程和解析结果。
摘要由CSDN通过智能技术生成

rk平台的IO 工具所包含的命令参数详解可以在串口或者 adb 输入“io?” 回车后便可罗列出。
要查询 io 寄存器;
当然,首先要有主控芯片详细规格书 TRM,请向对接的 RK 业务邮件申请(注:在 http://opensource.rock-chips.com/可以找到 3399、3288、3328 的 TRM技术参考手册

1、先找到对应的IO基地址(比如我这里要找gmac的tx clk的寄存器值,)
首先确认MAC_TXCLK对应的GPIO是GPIO3_C1,接下来在 TRM 上搜索 gpio3c1(不带下杠,连着输入名称),可以找到寄存器
寄存器地址是
Address: Operational Base + offset (0x0e018)
(截图)

2、此时顺着往上翻滚可知道该寄存器的基地址名称是“GRF”:
在这里插入图片描述

3、下一步就是在 datasheet 中搜索 address mapping,并在其中找到 GRF 的基地址:
也就是 GRF 为0xFF77_0000
在这里插入图片描述

明确地址后,在串口或者 adb 输入:
io -4 -l 0x100 0xff77e018
(注:这里显示 0x100 这么多个是因为比较直观,有时 gpio 的 clk 被锁也可直观看出)
回车可得到输出结果:

root@localhost:~# io -4 -l 0x100 0xff77e018
ff77e018: 00000007 00000000 00000014 00000555
ff77e028: 00000145 00000000 00000000 00000000
ff77e038: 00000000 00000000 00006aa0 00005555
ff77e048: 0000ffc3 00000143 00000000 00004010
ff77e058: 00000000 0000aaaa 0000aa82 00000655
ff77e068: 00006860 0000aaa9 00000000 00000000
ff77e078: 00000000 00000000 00000000 00000000
ff77e088: 00000000 00000000 00000000 00000000
ff77e098: 00000000 00000000 00000000 000000ff
ff77e0a8: 00000000 00000000 00000000 00000000
ff77e0b8: 00000000 00000000 00000000 00000000
ff77e0c8: 00000000 00000000 00000000 00000000
ff77e0d8: 00000000 00000000 00000000 00000000
ff77e0e8: 00000000 00000000 00000000 00000000
ff77e0f8: 00000000 00000000 0000000f 00000000
ff77e108: 0000ff00 0000000f 0000b01b 00000001

第一行的结果为:ff77e018: 00000007 00000000 00000014 00000555
四个值分别对应地址:0xff77e018、0xff77e01c、0xff77e020、0xff77e024。那么 0xff77e018
输出结果就是 0x00000007,怎么看呢? 因为 0x00000007 是十六进制,我们把它转化为二进制就
是:0000 0000 0000 0000 0000 0000 0000 0111 ,这里写出完整的转化后的 32bit 方便大
家观看,转换后的结果从右至左为低位到高位,即最右边的 bit 为第 0 bit,最左边的 bit
为第 31bit。那么对应到之前查询到的寄存器 :GRF_GPIO3C_IOMUX 便可以一一对应来查看结果了。

那么对应到之前查询到的寄存器 :GRF_GPIO3C_IOMUX 便可以一一对应来
查看结果了。在 GRF_GPIO3C_IOMUX 寄存器中,gpio3c1 的功能寄存器是第 3 bit 和第 2 bit[3:2] :
(截图)

而查看上面串口输出结果转换二进制后结果来看,[3:2] bit 就是 01,也就是对应该寄存
器的 2’b01: mac_txclk 这个功能。由此,我们知道了 gpio3c1 这个 IO 引脚当前的复用
情况就是作为mac的tx clk来使用。

如果这不是自己设置的状态,则去代码中查找哪里被复用即可。

如果想要通过 IO 命令临时写一个寄存器做实验,可以通过 io –w 去写。

例如,已经通过命令: io -4 -r 0xff77e024 读出了寄存器的值,那么此时想对
0xff77e024 这个寄存器的第 0 个 bit 写入 1,那么可以如下操作:
Io -4 –w 0xff77e024 0x00010001

注:为什么寄存器地址后面的十六进制值的第 16 bit 要写 1?因为该寄存器的 16bit 至
31 bit 是写有效位,默认为 0,即不可写。因为要往第 0 bit 写 1,所以 0 bit 对应的
写有效位 16 bit 也要对应置 1 才可写入,这个是根据寄存器描述而定的:

下面是一个使用RK3588的PCIe 3.0的4个通道并发多个并行IO请求的应用程序的示例: ```c++ #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <fcntl.h> #include <unistd.h> #define NUM_THREADS 4 // 线程数 #define IO_SIZE 4096 // 每个IO请求的大小 #define NUM_IO_REQUESTS 8 // 每个线程的IO请求数 void* io_thread(void* arg) { int fd = open("/dev/nvme0n1", O_RDWR | O_DIRECT); // 打开设备节点 if (fd < 0) { perror("open"); exit(1); } char* buffer = aligned_alloc(4096, IO_SIZE); // 分配对齐的缓冲区 if (!buffer) { perror("aligned_alloc"); exit(1); } for (int i = 0; i < NUM_IO_REQUESTS; i++) { // 发送IO请求 ssize_t ret = pread(fd, buffer, IO_SIZE, i * IO_SIZE); if (ret < 0) { perror("pread"); exit(1); } } free(buffer); // 释放缓冲区 close(fd); // 关闭设备节点 pthread_exit(NULL); } int main() { pthread_t threads[NUM_THREADS]; int rc; long t; for (t = 0; t < NUM_THREADS; t++) { rc = pthread_create(&threads[t], NULL, io_thread, (void*)t); if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(1); } } pthread_exit(NULL); } ``` 这个程序使用了4个线程,并发地发送每个线程8个IO请求,每个IO请求的大小为4KB。其中,打开的设备节点为"/dev/nvme0n1",可以根据实际情况进行修改。每个线程的IO请求会分别发送到4个通道中,以充分利用PCIe3.0的4个通道并发传输的能力。需要注意的是,这只是一个简单的示例程序,具体实现需要根据实际情况进行调整和优化。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

零意@

您的打赏将是我继续创作的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值