rk3568|rk平台GPIO冲突检测小技巧

原创 一口Linux 2022-12-26 11:54
点击左上方蓝色“一口Linux”,选择“设为星标


第一时间看干货文章 

【干货】嵌入式驱动工程师学习路线
【干货】一个适合初学者的Linux物联网综合项目
【干货】Linux嵌入式知识点-思维导图-免费获取



 1

所有瑞芯微的文章合集,建议订阅

瑞芯微文章合集

上一篇我们讲解了如何编写gpio驱动,但是实际操作中,经常发现gpio引脚被占用的情况发生,那么本篇文章就详细讲解rxw平台下如何快速定位gpio复用问题以及如何解决。

一、GPIO寄存器查找

要想查看某个GPIO引脚可以配置的功能以及地址信息,需要查看TRM手册:

《Rockchip RK3568 TRM Part1》
  • 第一步:对于GPIO2 A2,我们转换成下面字符串然后搜索
gpio2a2_sel

这样我们就可以直接找到该引脚iomux配置寄存器,bit[10:8]。该寄存器地址:

基地址+0x0020

那么如何找到基地址呢?

  • 第二步:

搜索该引脚寄存器的名字:

GRF_GPIO2A_IOMUX_L

注意向上搜索

可以得到该寄存器基地址名称:

SYS_GRF
  • 第三步 直接进入chapter 3

可得SYS_GRF 基地址

0xFDC60000

那么我们就得到了GPIO2 A2的IOMUX配置寄存器地址为

0xFDC60000 + 0x0020

该寄存器的bit[10:8]用于设置该寄存器功能。

当然也可以用下图来查找,更加方便:

那么找到了这个寄存器地址,我要如何来直接读取这个寄存器的值呢?

这个可以借助于一个命令io。

二、io命令

io命令可以直接操作某个寄存器,用于查看设置某个PIO 引脚配置了什么iomux,非常方便。

1. 移植io命令需要的驱动

RK 的 Android 平台,默认有包含 io 工具(源码位置:external\io), linux 系统平台如果没有此源码, 可以将 Android 平台此源码打包过去编译即可( linux 平台代码同步最新都已带有 IO 工具,可直接使用命令)。

  • 第一步:修改Makefile、Kconfig
vim  drivers/char/Makefile

增加
+obj-$(CONFIG_DEVMEM)           += mem.o
vim drivers/char/Kconfig
改文件已经包含下面信息
 10 config DEVMEM
 11     bool "/dev/mem virtual device support"
 12     default y
 13     help
 14       Say Y here if you want to support the /dev/mem device.
 15       The /dev/mem device is used to access areas of physical
 16       memory.
 17       When in doubt, say "Y".

  • 第二步:修改驱动文件

io命令需要内核驱动支持,驱动文件如下:

drivers/char/mem.c

找到下面代码:

#ifdef CONFIG_DEVMEM
         [1] = { "mem", 0, &mem_fops, FMODE_UNSIGNED_OFFSET },
#endif

修改为


+//#ifdef CONFIG_DEVMEM
         [1] = { "mem", 0, &mem_fops, FMODE_UNSIGNED_OFFSET },
+//#endif
  • 第三步:修改配置文件rockchip_defconfig
vim  arch/arm64/configs/rockchip_defconfig
增加
+CONFIG_DEVMEM=y

重新编译内核,烧录重启。

rockchip_defconfig需要根据平台选择

  • 第四步:查看mem字符设备:
rk3568_r:/ # ls /dev/mem -l
ls /dev/mem -l
crw------- 1 media media 1,   1 2017-08-04 09:00 /dev/mem

io命令正是通过这个字符设备来实现寄存器的读写的。

2. 命令说明

rk3568_r:/dev # io
io
Raw memory i/o utility - $Revision: 1.5 $

io -v -1|2|4 -r|w [-l ] [-f ]  []

    -v         Verbose, asks for confirmation
    -1|2|4     Sets memory access size in bytes (default byte)
    -l    Length in bytes of area to access (defaults to
               one access, or whole file length)
    -r|w       Read from or Write to memory (default read)
    -f   File to write on memory read, or
               to read on memory write
         The memory address to access
          The value to write (implies -w)

Examples:
    io 0x1000                  Reads one byte from 0x1000
    io 0x1000 0x12             Writes 0x12 to location 0x1000
    io -2 -l 8 0x1000          Reads 8 words from 0x1000
    io -r -f dmp -l 100 200    Reads 100 bytes from addr 200 to file
    io -w -f img 0x10000       Writes the whole of file to memory

Note access size (-1|2|4) does not apply to file based accesses.

3. 举例1,通过IO读寄存器:

读取gpio2 A2引脚配置寄存器

io -4 -l 0x30 0xFDC60000
-4         : 按字(4个字节) 访问内存 
0x30       : 读取0x30(48)个字节
0xFDC60000 : 基地址

由上图可得0xFDC60020的bit[10:8]值为1

所以该io引脚被设置的iomux为

3'h1: SDMMC0_CLK

如果我们是希望通过设备树设置该引脚为普通gpio,那么该值应该为0,

那么这就说明了,我们设置失败了,

那就可以到设备树中查找设置SDMMC0的地方,将其注释掉。

要读取单个寄存器,可以用下面命令:

 io -4 -r 0xFDC60024

4. 举例2,通过IO写寄存器

比如已经通过命令:io -4 -r 0xFDC60024读出了寄存器的值,那么此时想把gpio2 A2修改为普通GPIO, 那么只需要对0xFDC60024这个寄存器的第 3 个 1 写 0,那么可以如下操作:

io -4 –w 0xFDC60024 0x01002011

注意:

  • 第三个1对应是bit[10:8]
  • 通过 io 写的寄存器值 reboot 后不会保留
  • 为什么寄存器地址后面的十六进制值的 bit [24]写 1?因为该寄存器的 16bit 至31 bit 是写有效位,默认为 0,即不可写。因为要往[8] bit 写 1,所以[8] bit  对应的 写有效位 16 bit 也要对应置 1 才可写入,这个是根据寄存器描述而定的。

修改过后,再查看,可以发现对应的位的值变为了1:

三、 通过函数gpiod_direction_output()

思 路 :驱 动 里 如 果 想 要 去 操 作 GPIO , 肯 定 会 调 用 到 gpio_direction_output 、gpio_direction_input、 gpiod_direction_output、 gpiod_direction_input 这几个接口, 他们的定义位置是:

 vim kernel/drivers/gpio/gpiolib.c

在这些接口里添加判断对应查询的 IO 口条件,通过以下函数就可以打印出哪些模块复用了该引脚:

dump_stack(); 

注意:在 linux3.10 内核的 sdk 中用的是 gpio_direction_output 和gpio_direction_input 接 口 , 在 linux4.4 内 核 中 则 是 gpiod_direction_output 和gpiod_direction_input。

下面以 linux4.4 版本为例来讲解如何查看引脚:gpio4 b3。

首先,需要计算出代表 gpio4b3 的值,算法如下:

gpio4_B3 = 4 *32 + (B-A) * 8 + 3 = 3 *32 + 1 * 8 + 3 = 139

计算方法参考:《rk3568 | 瑞芯微平台GPIO引脚驱动编写》

  • 最前面和 32 相乘的数字因为是 gpio4,所以是 432。如果是 gpio3,那就是 332;
  • 括号里面的 A、 B、 C、 D 分别代表数值 0、 1、 2、 3,在计算时候分别对应去减即可,这里因为是 B3,所以用 B-A,如果是 C3,就是 C-A;
  • 最后的+3 是因为是   B3,如果是 GPIO4B2,那么最后就+2。

注:在 linux4.4 内核, io 引脚的值有些变化,也就是按照上文算法计算的结 果要+1000,所以 GPIO4B3 如果是 linux4.4 内核里要填 1139。

int gpiod_direction_output(struct gpio_desc *desc, int value)
{
 if (!desc || !desc->chip) {
  pr_warn("%s: invalid GPIO\n", __func__);
  return -EINVAL;
 }
+  if ( desc_to_gpio(desc) == 1139)
+  {
+   printk("dump_stack_start\n");
+   dump_stack();
+   printk("dump_stack_end\n");
+  }
 if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
  value = !value;
 return _gpiod_direction_output_raw(desc, value);
}

添加后编译烧录,只要对应判断的引脚有被调用,启动 log 中就会打印出堆栈,可以根据找出结果查看,找到驱动调用函数。

四、通过函数rockchip_set_mux()

配置IOMUX会调用该接口,

仍然以引脚gpio4 b3为例。

[drivers/pinctrl/pinctrl-rockchip.c]

  @@ -1224,6 +1224,17 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
   dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n",
             bank->bank_num, pin, mux);
+       if((bank->bank_num == 4)&&(pin == 11)){
+               printk("6902 setting mux of GPIO%d-%d to %d\n",
+                               bank->bank_num, pin, mux);
+               dump_stack();
+       }
    if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
            regmap = info->regmap_pmu;
  • bank_num 表示gpio4
  • 这里“ pin ==”后面跟的值计算方式为:将 A0 至 D7 32 个引脚顺序对应数值 0 至 31,b3为11。

五、如何去掉设备树中的复用引脚信息?

刚才分析,发现GPIO2 A2被SDMMC0占用,那么如何来解决这个冲突呢?

只要从设备树下手即可。

瑞芯微平台的设备树,根据平台区分,往往前缀是:

rk + 平台  + 板子型号 + ddr型号 + 版本

比如rk3568系列设计的设备树文件如下:

arch/arm64/boot/dts/rockchip/rk3568-amp.dtsi
arch/arm64/boot/dts/rockchip/rk3568-android9.dtsi
arch/arm64/boot/dts/rockchip/rk3568-android.dtsi
arch/arm64/boot/dts/rockchip/rk3568-dram-default-timing.dtsi
arch/arm64/boot/dts/rockchip/rk3568.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-android9.dts
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dtb
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-linux.dts
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-linux-spi-nor.dts
arch/arm64/boot/dts/rockchip/rk3568-evb2-lp4x-v10-bt1120-to-hdmi.dts
arch/arm64/boot/dts/rockchip/rk3568-evb2-lp4x-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb2-lp4x-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb4-lp3-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb5-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb5-ddr4-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb6-ddr3-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb6-ddr3-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb6-ddr3-v10-linux.dts
arch/arm64/boot/dts/rockchip/rk3568-evb6-ddr3-v10-rk628-bt1120-to-hdmi.dts
arch/arm64/boot/dts/rockchip/rk3568-evb6-ddr3-v10-rk628-rgb2hdmi.dts
arch/arm64/boot/dts/rockchip/rk3568-evb6-ddr3-v10-rk630-bt656-to-cvbs.dts
arch/arm64/boot/dts/rockchip/rk3568-evb7-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb.dtsi
arch/arm64/boot/dts/rockchip/rk3568-iotest-ddr3-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-iotest-ddr3-v10-linux.dts
arch/arm64/boot/dts/rockchip/rk3568-linux.dtsi
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v10-linux.dts
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v10-linux-spi-nand.dts
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v12.dtsi
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v12-linux.dts
arch/arm64/boot/dts/rockchip/rk3568-nvr-demo-v12-linux-spi-nand.dts
arch/arm64/boot/dts/rockchip/rk3568-nvr.dtsi
arch/arm64/boot/dts/rockchip/rk3568-nvr-linux.dtsi
arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi

一口君的板子是evb1,ddr4,v10版本,所以去掉其他的文件,

我们只需要关注以下文件即可。

arch/arm64/boot/dts/rockchip/rk3568-android.dtsi
与安卓相关的信息

arch/arm64/boot/dts/rockchip/rk3568.dtsi 
描述cpu、memory、timer、clk、sata、usb host、gic、视频控制器、sram、cru、i2c控制器、uart、pwm、pmu等各种Soc内部硬件信息

arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dts
arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10.dtsi
arch/arm64/boot/dts/rockchip/rk3568-evb.dtsi
与evb1底板相关的外设硬件信息

arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi
pinctl相关硬件信息

还有1个描述pinctl引脚驱动能力的文件:

rockchip-pinconf.dtsi

使用grep命令来查询:

grep sdmmc0 arch/arm64/boot/dts/rockchip/rk3568* -nr

好在信息不多,逐个查看,下面这个文件,我们找到了复用的地方。

rk3568-pinctrl.dtsi

该引脚被定义为sdmmc0_clk,作为时钟被使用了。

 sdmmc0 {
  ………………
  /omit-if-no-ref/
  sdmmc0_clk: sdmmc0-clk {
   rockchip,pins =
    /* sdmmc0_clk */
    <2 RK_PA2 1 &pcfg_pull_up_drv_level_2>;
  };

修改的方法有很多种:

  1. 投机取巧法 将sdmmc0_clk改成其他没有用的gpio

  2. 简单粗暴法 如果确定没有使用sdmmc0,可以将所有sdmmc0地方全部注释掉

设备树支持下面这种方法:

#if 0
#endif
  1. 硬件飞线法

找硬件工程师飞线,改用其他的GPIO

  1. 最优法 如果sdmmc0也用到了,

那就只能修改冲突的GPIO,

但是这种情况,往往会牵一发而动全身,

要改好几处,那就需要各位老铁细心慢慢修改了。

好了,本文到底结束。

一口君目标是写100篇瑞芯微平台的文章,

有喜欢瑞芯微的老铁,

欢迎大家关注学习。

end


一口Linux 


关注,回复【1024】海量Linux资料赠送

精彩文章合集


文章推荐

【专辑】ARM
【专辑】粉丝问答
专辑linux入门
专辑计算机网络
专辑Linux驱动
【干货】嵌入式驱动工程师学习路线
【干货】Linux嵌入式所有知识点-思维导图

一口Linux 写点代码,写点人生!
评论
  • 学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&
    youyeye 2024-11-30 14:30 73浏览
  • 最近几年,新能源汽车愈发受到消费者的青睐,其销量也是一路走高。据中汽协公布的数据显示,2024年10月,新能源汽车产销分别完成146.3万辆和143万辆,同比分别增长48%和49.6%。而结合各家新能源车企所公布的销量数据来看,比亚迪再度夺得了销冠宝座,其10月新能源汽车销量达到了502657辆,同比增长66.53%。众所周知,比亚迪是新能源汽车领域的重要参与者,其一举一动向来为外界所关注。日前,比亚迪汽车旗下品牌方程豹汽车推出了新车方程豹豹8,该款车型一上市就迅速吸引了消费者的目光,成为SUV
    刘旷 2024-12-02 09:32 101浏览
  • 作为优秀工程师的你,已身经百战、阅板无数!请先醒醒,新的项目来了,这是一个既要、又要、还要的产品需求,ARM核心板中一个处理器怎么能实现这么丰富的外围接口?踌躇之际,你偶阅此文。于是,“潘多拉”的魔盒打开了!没错,USB资源就是你打开新世界得钥匙,它能做哪些扩展呢?1.1  USB扩网口通用ARM处理器大多带两路网口,如果项目中有多路网路接口的需求,一般会选择在主板外部加交换机/路由器。当然,出于成本考虑,也可以将Switch芯片集成到ARM核心板或底板上,如KSZ9897、
    万象奥科 2024-12-03 10:24 41浏览
  • 光伏逆变器是一种高效的能量转换设备,它能够将光伏太阳能板(PV)产生的不稳定的直流电压转换成与市电频率同步的交流电。这种转换后的电能不仅可以回馈至商用输电网络,还能供独立电网系统使用。光伏逆变器在商业光伏储能电站和家庭独立储能系统等应用领域中得到了广泛的应用。光耦合器,以其高速信号传输、出色的共模抑制比以及单向信号传输和光电隔离的特性,在光伏逆变器中扮演着至关重要的角色。它确保了系统的安全隔离、干扰的有效隔离以及通信信号的精准传输。光耦合器的使用不仅提高了系统的稳定性和安全性,而且由于其低功耗的
    晶台光耦 2024-12-02 10:40 105浏览
  • 概述 说明(三)探讨的是比较器一般带有滞回(Hysteresis)功能,为了解决输入信号转换速率不够的问题。前文还提到,即便使能滞回(Hysteresis)功能,还是无法解决SiPM读出测试系统需要解决的问题。本文在说明(三)的基础上,继续探讨为SiPM读出测试系统寻求合适的模拟脉冲检出方案。前四代SiPM使用的高速比较器指标缺陷 由于前端模拟信号属于典型的指数脉冲,所以下降沿转换速率(Slew Rate)过慢,导致比较器检出出现不必要的问题。尽管比较器可以使能滞回(Hysteresis)模块功
    coyoo 2024-12-03 12:20 71浏览
  • 遇到部分串口工具不支持1500000波特率,这时候就需要进行修改,本文以触觉智能RK3562开发板修改系统波特率为115200为例,介绍瑞芯微方案主板Linux修改系统串口波特率教程。温馨提示:瑞芯微方案主板/开发板串口波特率只支持115200或1500000。修改Loader打印波特率查看对应芯片的MINIALL.ini确定要修改的bin文件#查看对应芯片的MINIALL.ini cat rkbin/RKBOOT/RK3562MINIALL.ini修改uart baudrate参数修改以下目
    Industio_触觉智能 2024-12-03 11:28 45浏览
  • 戴上XR眼镜去“追龙”是种什么体验?2024年11月30日,由上海自然博物馆(上海科技馆分馆)与三湘印象联合出品、三湘印象旗下观印象艺术发展有限公司(下简称“观印象”)承制的《又见恐龙》XR嘉年华在上海自然博物馆重磅开幕。该体验项目将于12月1日正式对公众开放,持续至2025年3月30日。双向奔赴,恐龙IP撞上元宇宙不久前,上海市经济和信息化委员会等部门联合印发了《上海市超高清视听产业发展行动方案》,特别提到“支持博物馆、主题乐园等场所推动超高清视听技术应用,丰富线下文旅消费体验”。作为上海自然
    电子与消费 2024-11-30 22:03 86浏览
  • 当前,智能汽车产业迎来重大变局,随着人工智能、5G、大数据等新一代信息技术的迅猛发展,智能网联汽车正呈现强劲发展势头。11月26日,在2024紫光展锐全球合作伙伴大会汽车电子生态论坛上,紫光展锐与上汽海外出行联合发布搭载紫光展锐A7870的上汽海外MG量产车型,并发布A7710系列UWB数字钥匙解决方案平台,可应用于数字钥匙、活体检测、脚踢雷达、自动泊车等多种智能汽车场景。 联合发布量产车型,推动汽车智能化出海紫光展锐与上汽海外出行达成战略合作,联合发布搭载紫光展锐A7870的量产车型
    紫光展锐 2024-12-03 11:38 71浏览
  • RDDI-DAP错误通常与调试接口相关,特别是在使用CMSIS-DAP协议进行嵌入式系统开发时。以下是一些可能的原因和解决方法: 1. 硬件连接问题:     检查调试器(如ST-Link)与目标板之间的连接是否牢固。     确保所有必要的引脚都已正确连接,没有松动或短路。 2. 电源问题:     确保目标板和调试器都有足够的电源供应。     检查电源电压是否符合目标板的规格要求。 3. 固件问题: &n
    丙丁先生 2024-12-01 17:37 86浏览
  • 《高速PCB设计经验规则应用实践》+PCB绘制学习与验证读书首先看目录,我感兴趣的是这一节;作者在书中列举了一条经典规则,然后进行详细分析,通过公式推导图表列举说明了传统的这一规则是受到电容加工特点影响的,在使用了MLCC陶瓷电容后这一条规则已经不再实用了。图书还列举了高速PCB设计需要的专业工具和仿真软件,当然由于篇幅所限,只是介绍了一点点设计步骤;我最感兴趣的部分还是元件布局的经验规则,在这里列举如下:在这里,演示一下,我根据书本知识进行电机驱动的布局:这也算知行合一吧。对于布局书中有一句:
    wuyu2009 2024-11-30 20:30 106浏览
  • 11-29学习笔记11-29学习笔记习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-02 23:58 52浏览
  •         温度传感器的精度受哪些因素影响,要先看所用的温度传感器输出哪种信号,不同信号输出的温度传感器影响精度的因素也不同。        现在常用的温度传感器输出信号有以下几种:电阻信号、电流信号、电压信号、数字信号等。以输出电阻信号的温度传感器为例,还细分为正温度系数温度传感器和负温度系数温度传感器,常用的铂电阻PT100/1000温度传感器就是正温度系数,就是说随着温度的升高,输出的电阻值会增大。对于输出
    锦正茂科技 2024-12-03 11:50 70浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦