当前位置: 首页 > article >正文

King3399(ubuntu文件系统)wifi设备树分析

该文章仅供参考,编写人不对任何实验设备、人员及测量结果负责!!!

0 引言

文章主要介绍King3399(ubuntu)wifi设备树,涉及king-rk3399.dts、rp-wifi-sdio.dtsi内容修改与介绍

在使用wifi前本人遇到了一个比较奇怪的问题,即自行编译的镜像文件烧录后无法使用wifi功能,使用指令ip a查看时没有wlan这部分,配置界面也没有相关选项,具体情况如下图所示,摸索一周后不清楚修改了哪里wifi又可正常启用(非设备树问题,因为对比前后逆向生成设备树文件各项配置相同,故排除设备树)
 wifi or not
一开始我认为是设备树的问题,因为rp-wifi-sdio.dtsi中的属性为wifi_chip_type = "ap6210";,而板子的wifi型号为ap6354s,将该属性修改后重新编译boot.img并烧录,wifi依然无法正常启用,于是便想从官方的镜像中获取设备树,对比从SDK中自行编译的设备树之间的区别

这篇文章具有一定的局限性:需要一个完整且功能正常的镜像做为参考

1 wifi模块硬件分析

king3399可以通过有线网络、无线wifi与4G模块三种方式联网,在进行开发时,大多数情况下都是利用有线的方式,这种方式更为稳定且在软件层面配置也较为简单,硬件上仅仅是多一根网线,但这也有一定局限性,例如当下无线网的应用更为广泛,利用手机的热点就可以组成局域网,随时随地都可以进行开发,免去杂乱的布线困扰,前面的文章本人使用的是有线的方式,最近将wifi的部分研究后,对这部分进行总结

cdrom_king3399_new\03-硬件文档\底板硬件资料\KING3399-20180712原理图.pdf

在上述路径中可以找到板子的原理图,其中wifi部分硬件原理图如下图所示(该模块为wifi+BT,本文只涉及wifi部分),模块外围电路并不复杂,采用SDIO接口与主控通信
 wifi硬件接口
wifi模块使用型号为ap6354,这个模块在正基(AMPAK)官网已下架,但网上有大量相关资料,datasheet(ap6354/ap6210)可在文末链接中下载

2 设备树分析

建议在查看设备树文件前先对其进行备份,避免误修改!!!

wifi这部分涉及多个设备树文件与子系统,在节点中有大量有用/无用的属性,如果刚接触这块内容学习起来是比较困难的,这里分享一个方法:逆向分析设备树,学习过设备树知识的应该都知道设备树这部分内容其实并不难(仅看懂与会修改),子节点的配置类似于stm32硬件的初始化,个人觉得难点在于节点内部属性的引用以及属性的具体意义

首先是引用,设备树中为了便于修改与配置,会使用大量的“&”对变量名进行引用,相对于直接写一堆数字/地址确实有助于分析代码,但这也会导致同一个变量名可能会出现在多个文件中,当使用“&”对一个子节点引用时就要注意了,这可能是对其属性的初始化,也可能是对其属性修改,还有可能是添加某个属性,当涉及多个文件与属性时,很容易迷糊

其次是属性,每个子节点都是由大量的属性组成,部分属性是固有的,这些在修改前必须了解,还有部分是第三方自定义的,这部分非常重要,通常具有极强针对性,但这部分可查找资料有限,往往需要根据实际情况推测

cdrom_king3399_new\04-镜像文件\ubuntu2004\update-king3399-linux-ubuntu20-hdmi-xxx-xxx.img

这里详细记录一下前文提到的逆向分析设备树的方法,首先将官方提供的镜像烧录至板子中,(可参考上述路径选择性下载,建议选择的镜像版本与SDK生成的版本一致,不同版本的设备树会有些许差异,不便于分析具体的差异),板子成功启动后执行如下指令安装设备树编译器

sudo apt install device-tree-compiler

查看当前板子所用设备树文件内容

dtc -I fs -O dts /sys/firmware/devicetree/base # -I是大写的 i !!!

为便于查看可将上述指令结果输出到指定文件,该过程可能会产生大量警告日志,可不理会

touch /home/xxx/my_king3399_dts.dts # 创建一个空设备树文件

将设备树输出到该文件

dtc -I fs -O dts /sys/firmware/devicetree/base > /home/xxx/my_king3399_dts.dts

上述操作皆在板子上执行,随后打开主机进入目录~/ws/sdk/kernel/arch/arm64/boot/dts/rockchip/rk3399,打开king-rk3399.dts可以看到,

#include "rp-rk3399-board.dtsi"
......
#include "rp-audio-rt5651.dtsi"
#include "rp-pmu-rk808.dtsi"

#include "rp-gpio-key.dtsi"
#include "rp-adc-key.dtsi"
      
#include "rp-mipi-ov13850-camera.dtsi"

#include "rp-wifi-sdio.dtsi"  // <----------目标文件
#include "rp-bt-uart0.dtsi" 

#include "rp-sdcard-mmc1.dtsi"
#include "rp-gmac.dtsi"
......

从头文件不难看出rp-wifi-sdio.dtsi是我们需要关注的文件,在同级目录下打开该文件,内容如下,内部共有三个子节点,其中wireless_wlan为新添加的节点,&sdio0&pinctrl为引用节点,为便于理解,对各属性添加必要注释

/ {
    wireless_wlan: wireless-wlan {
        # 兼容性匹配检查用
        compatible = "wlan-platdata";
        # grf: general register file
        rockchip,grf = <&grf>;
        # wifi模块型号,这里填写ap6354也可正常使用
        wifi_chip_type = "ap6210";
        # 
        sdio_vref = <1800>;
        pinctrl-names = "default";
        pinctrl-0 = <&wifi_host_wake_irq>, <&wifi_enable_h>;
		# 中断控制引脚
        WIFI,host_wake_irq = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>; 
		# 电源控制引脚
        WIFI,poweren_gpio = <&gpio0 RK_PB2 GPIO_ACTIVE_HIGH>;
         # 节点状态可用
        status = "okay";
    };
};

# sdio0 = "/mmc@fe310000";
&sdio0 {
    # SDIO最大运行频率
    max-frequency = <150000000>;
	# 在初始化时是否限制发送sd指令
    no-sd;
	# 在初始化时是否限制发送mmc指令
    no-mmc;
	# 线宽,不配置则默认为1,可选择参数只有1、4和8
    bus-width = <4>;
	# 是否禁用写保护
    disable-wp;
	# 是否为高速设备
    cap-sd-highspeed;
	# 是否支持中断
    cap-sdio-irq;
	# 是否支持睡眠不断电 
    keep-power-in-suspend;
	# 插槽不可移动
    non-removable;
	#
    num-slots = <1>;
    pinctrl-names = "default";
    pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;
	# 设备是否支持 SDIO3.0 模式(频率 < 208M)
    sd-uhs-sdr104;
    status = "okay";
};

&pinctrl {
    wireless-wlan {
                wifi_host_wake_irq: wifi-host-wake-irq {
                        rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_down>;
                };
                wifi_enable_h: wifi-enable-h {
                        rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>;
                };
    };
};

与此同时打开前面逆向生成的设备树my_king3399_dts.dts,摘取部分与本文相关内容如下

	wireless-wlan {
		pinctrl-names = "default";
		pinctrl-0 = <0xeb 0xec>;
		WIFI,host_wake_irq = <0x40 0x03 0x00>;
		sdio_vref = <0x708>;
		wifi_chip_type = "ap6210";
		compatible = "wlan-platdata";
		status = "okay";
		rockchip,grf = <0x20>;
		# phandle : pointer handle,唯一标识符号,类似于地址/标签,便于调用
		phandle = <0x1ad>;
		WIFI,poweren_gpio = <0x40 0x0a 0x00>;
	};

	mmc@fe310000 {
		power-domains = <0x1f 0x1c>;
		fifo-depth = <0x100>;
		pinctrl-names = "default";
		pinctrl-0 = <0x25 0x26 0x27>;
		clock-names = "biu\0ciu\0ciu-drive\0ciu-sample";
		cap-sd-highspeed;
		no-mmc;
		bus-width = <0x04>;
		non-removable;
		resets = <0x08 0x79>;
		cap-sdio-irq;
		interrupts = <0x00 0x40 0x04 0x00>;
		clocks = <0x08 0x1ee 0x08 0x4d 0x08 0x9c 0x08 0x9d>;
		num-slots = <0x01>;
		keep-power-in-suspend;
		no-sd;
		compatible = "rockchip,rk3399-dw-mshc\0rockchip,rk3288-dw-mshc";
		status = "okay";
		disable-wp;
		reg = <0x00 0xfe310000 0x00 0x4000>;
		phandle = <0x100>;
		sd-uhs-sdr104;
		max-frequency = <0x8f0d180>;
		reset-names = "reset";
	};

    pinctrl {
		compatible = "rockchip,rk3399-pinctrl";
		rockchip,pmu = <0x9d>;
		ranges;
		rockchip,grf = <0x1f>;

		wireless-wlan {

			wifi-host-wake-irq {
				rockchip,pins = <0x00 0x03 0x00 0xd3>;
				phandle = <0xe7>;
			};

			wifi-enable-h {
				rockchip,pins = <0x00 0x0a 0x00 0xd2>;
				phandle = <0xe8>;
			};
		};
	};

不难看出,两个设备树文件的差别还是很大的,后者使用地址/数组来表示具体的属性值,并将设备树中该节点的所有属性列举出,结构上将所有设备节点存放在同一个根节点下,设备“树”名副其实

从模块/设备管理的角度来讲,后者显然是不可取的,各模块在设备树中的关联太强,在修改时很容易出错,但如果是进行分析比对,这无疑会提高效率,免去了在各文件中切换查找的繁琐的步骤,下图为本人wifi成功启用前后的区别,可以明显看出两者区别所在,第一处为模块的硬件地址,都是唯一的,不对wifi是否正常工作产生影响,第二处左侧为将“ap6210”修改为“ap6354”,,修改后重新编译也能够联网,通过上述分析能够得出wifi未能成功启动问题还在设备树上
dts区别对比

3 设备树属性及示例

上一小节提到设备树中存在大量属性,在分析/修改设备树时了解这些属性是必要的,网上关于这部分的资料很零散,本人对wifi进行调试时在这方面花费了不少精力,这里以wifi的部分属性为例,总结如何查看属性的用法

  1. 进入sdk内核设备树示例目录,该目录下有大量设备类型,常见的例如pinctrl、pwm、spi、iic等,我们的wifi使用的是sdio接口,属于mmc,除此之外有些wifi模块还可能使用usb或者pcie接口

    ~/ws/sdk/kernel/Documentation/devicetree/bindings/

  2. 找到mmc目录进入可以看到大量文件,从文件名不难猜测出文件与设备厂商相关,像atmel、hi、microchip、nvidia、ti等,大家应该都不陌生,我们所使用的wifi模块是正基(AMPAK)不在上述行列中,唯一与之有点关系的只有rockchip,打开rockchip-dw-mshc.yaml,可以看到如下这段话,大致内容是说rockchip使用的是synopsys(新思)控制器去操作mmc设备,该文件主要是添加了一些rockchip的特有属性,并给出了示例(能力有限,翻译的不准确,可自行查看该文件)

    title: 
    # 文件名“dw-mshc”与title缩写对应
    Rockchip designware mobile storage 
    host controller device tree bindings
    
    description:
    # 文件内容简述
    Rockchip uses the Synopsys designware
    mobile storage host controllerto interface
    a SoC with storage medium such as eMMC or
    SD/MMC cards.
    
    This file documents the combined properties
    for the core Synopsys dw mshccontroller 
    that are not already included in the 
    synopsys-dw-mshc-common.yamlfile and 
    Rockchip specific extensions.
    
  3. 文件中提到了一个参考文件“ref: synopsys-dw-mshc-common.yaml#",在同级目录下,打开该文件,内容与上一个文件类似,从title: Synopsys Designware Mobile Storage Host Controller Common Properties这句话可以了解到,这个文件是synopsys的移动存储主机控制器通用属性,可以理解为这个文件中的属性是synopsys的一些特有属性

  4. 同理,文件中同样提到了一个参考文件ref: "mmc-controller.yaml#",打开这个文件,摘取部分内容如下所示,从描述中可以得知,这个文件的所有属性是mmc设备通用的,不局限于某个厂商或平台,在这个文件中可以找到大多数wifi子节点中的属性,

    # mmc设备通用控制器
    title: 
    MMC Controller Generic Binding
    
    description: 
    These properties are common to 
    multiple MMC host controllers. 
    Any hostthat requires the respective 
    functionality should implement them 
    usingthese definitions.
    
    It is possible to assign a fixed index 
    mmcN to an MMC host controller(and the 
    corresponding mmcblkN devices) by defining 
    an alias in the/aliases device tree node.
    
  5. 在找到这些属性后还剩下最后的工作:修改与使用这些属性,下边列举了三个典型的属性,第一个是bus-width,该属性决定了mmc设备接口的通信硬线数量,类型为枚举,可选参数为1、4和8,如果未显示声明该属性则默认为是单线,king3399中该属性设置的为4

    第二个是max-frequency,该属性定义了总线的最大操作频率,数据类型为uint32,实际取值区间为(400000,200000000),我们使用wifi子节点中该参数设置为150000000;

    第三个是sd-uhs-sdr104,该属性决定了sdio的传输速度模式,类型为bool(flag),当声明后,表示该设备使用这种传输速度模式,这个属性的具体使用与介绍可参考文末脚注《Rockchip RK3399 - MMC&SD&SDIO基础》

    bus-width:
    	description:
    	Number of data lines.
    	$ref: /schemas/types.yaml#/definitions/uint32
    	enum: [1, 4, 8]
    	default: 1
    
    max-frequency:
    	description:
    	Maximum operating frequency of the bus.
    	$ref: /schemas/types.yaml#/definitions/uint32
    	minimum: 400000
    	maximum: 200000000
    
    sd-uhs-sdr104:
    	$ref: /schemas/types.yaml#/definitions/flag
    	description:
    	SD UHS SDR104 speed is supported.
    
  6. 通过上面的步骤能够找到大部分关于wifi的属性与用法介绍,然而还是有个别属性无法把握住,例如num-slots,网上也没有关于这个属性的介绍,这个就只能靠猜了,从字面意思理解就是SD卡插槽的数量,节点中的赋值是1,而king3399上的SD卡插槽正好是一个,当然这仅仅是个人推测,若是谁手中有多个插槽的板子可以试着看看这个属性是如何使用的

至此,关于wifi的设备树内容已经介绍完毕(由于属性众多,无法逐一列举,可参考上述方法查看具体属性的介绍与用法),下面表格中列举了上述三个文件中的所有属性名

rockchip-dw-mshc.yaml#synopsys-dw-mshc-common.yaml#mmc-controller.yaml#
compatibleinterrupts$nodenamedisable-wp
regresets#address-cellswp-gpios
interruptsreset-names#size-cellsno-1-8-v
clocksclock-frequencycap-mmc-highspeedbroken-cd
clock-namesfifo-depthcap-sd-highspeedcd-gpios
rockchip,default-sample-phasecard-detect-delaynon-removablewp-inverted
rockchip,desired-num-phasesdata-addrcd-debounce-delay-mscd-inverted
fifo-watermark-alignedsd-uhs-sdr12bus-width
dmassd-uhs-sdr25max-frequency
dma-namessd-uhs-sdr50mmc-ddr-1_2v
sd-uhs-sdr104mmc-ddr-1_8v
sd-uhs-ddr50mmc-ddr-3_3v
cap-power-off-cardcap-sdio-irq
cap-mmc-hw-resetfull-pwr-cycle
disable-cqe-dcmd:broken-hpi
wakeup-sourcecompatible
full-pwr-cycle-in-suspenddsr
mmc-hs400-enhanced-strobeno-sdio
fixed-emmc-driver-typeno-sd
post-power-on-delay-msno-mmc
keep-power-in-suspendsupports-cqe
mmc-hs200-1_2vmmc-supply
mmc-hs200-1_8vvqmmc-supply
mmc-hs400-1_2vmmc-pwrseq
mmc-hs400-1_8vreg
4 wifi部分内核配置

打开网盘中下述路径中的文件,该文件是对wifi部分的使用说明,包含本文前面的设备树部分,但该文件写的比较杂乱,准确来说rp/rk所有的官方文档都写的很差,感觉就像是工程师随手写的笔记,逻辑跳脱,内容陈旧

cdrom_king3399_new\02-软件文档\RK原厂文档\linux\cn\Linux\Wifibt\Rockchip_Developer_Guide_Linux_WIFI_BT_CN.pdf

关于wifi部分的内核配置部分,本人没有心得,仅仅是照着网上的资料看了看配置选项与配置文件,没有做任何修改,下边提到的几个配置文件将在文末提供下载链接,若手中设备wifi有问题可以参考这几个配置文件

首先是查看配置选择,进入~\ws\sdk\kernel目录,输入make menuconfig ARCH=arm64,在弹出的界面中进入如下目录

Device Drivers > Network device support > Wireless LAN > Rockchip Wireless LAN support >

本人此处的配置如下,仅供参考,若对某个选项有疑惑可以选择该并按下h,即可弹出相关的说明,界面中配置选项保存在~\ws\sdk\kernel\.config文件中,该文件不可手动修改,文件第一行有提到

Rockchip Wireless LAN support
[ ]   build wifi ko modules
[*]   Wifi load driver when kernel bootup
[ ]   Wifi generate random mac......
[*]   Broadcom Wireless Device Driver Support  ---> 
Broadcom Wireless Device Driver Support
<*>   ap6xxx wireless cards support
      Enable Chip Interface (SDIO bus interface support)  --->
(/vendor/etc/firmware/fw_bcmdhd.bin) Firmware path
(/vendor/etc/firmware/nvram.txt) NVRAM path
[ ]   Enable wlan1 support

此外打开编译日志~\ws\sdk\output\sessions\lastes\xx-kernel-build.log,可以看到如下一段内容,可以看出~ws\sdk\kernel\arch\arm64\configs\rockchip_wifi_builtin.config中的部分变量将~ws\sdk\kernel\.config的变量覆盖了

......
Using .config as base
Merging ./arch/arm64/configs/rockchip_wifi_builtin.config
Value of CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP is redefined by fragment ./arch/arm64/configs/rockchip_wifi_builtin.config:
Previous value: # CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP is not set
New value: CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP=y

Value of CONFIG_AP6XXX is redefined by fragment ./arch/arm64/configs/rockchip_wifi_builtin.config:
Previous value: # CONFIG_AP6XXX is not set
New value: CONFIG_AP6XXX=y
......

其中rockchip_wifi_builtin.config的内容如下

# CONFIG_WIFI_BUILD_MODULE is not set
CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP=y
CONFIG_AP6XXX=y

[1] Rockchip RK3399 - MMC&SD&SDIO基础

[2] 正基官网

[3] K3568外接AP6275S WIFI模块调试详解

[4] datasheet(ap6354/ap6210)PWD:wm8e


http://www.kler.cn/a/395083.html

相关文章:

  • C#中 layout的用法
  • MaxKB
  • 【CSS】什么是BFC?
  • Python Plotly 库使用教程
  • 任何使用 Keras 进行迁移学习
  • 硬件工程师之电子元器件—二极管(4)之热量对二极管温度特性的影响
  • 学习日志009--面向对象的编程
  • 前后端、网关、协议方面补充
  • 41页PPT | 华为业务流程架构全景视图:全业务域L1-L3级流程全案
  • python中父类和子类继承学习
  • Django处理前端请求的流程梳理
  • 通过命令学习k8s
  • ABAP开发学习——权限控制 实例1
  • PHP代码审计 - SQL注入
  • LeetCode面试经典150题C++实现,更新中
  • gcc 1.c和g++ 1.c编译阶段有什么区别?如何知道g++编译默认会定义_GNU_SOURCE?
  • Mysql篇-三大日志
  • Linux设置Nginx开机启动
  • http拉取git仓库,每次都要输入帐号密码,Ubuntu上记住帐号密码
  • 微积分复习笔记 Calculus Volume 1 - 5.5 Substitution
  • sqlserver 常用分页函数
  • ssh key的生成密钥
  • 区间数位和模板(贪心)
  • ROS Action
  • SQL 注入详解:原理、危害与防范措施
  • Oracle 11g rac 集群节点的修复过程