软件开发指导
源码编译
编译环境要求
编译主机需在ubuntu系统中进行,且版本需Ubuntu 20.04以上,笔者主机系统为Ubuntu 20.04
主机需可连接外网,因为编译系统过程需要下载某些文件。
下载源码包
下载rk3506源码包,路径为:3.软件资料–>3.1源码–>rk3506-buildroot-20250606.tar.xz
创建编译目录:
mkdir -p ~/my-work/RK3506/02_sources/
把源码放到刚创建的目录中,并进行解压:
tar xvf rk3506-buildroot-20250606.tar.xz -C ~/my-work/RK3506/02_sources/
依赖安装
首次编译可能需要安装某些依赖,下面给出主机可能需要安装的某些依赖:
sudo dpkg --add-architecture i386
sudo apt-get install git bc bison build-essential curl flex g++-multilib gcc-multilib gnupg gperf imagemagick lib32ncurses5-dev lib32readline-dev lib32z1-dev liblz4-tool libncurses5-dev libsdl1.2-dev libssl-dev libxml2 libxml2-utils lzop pngcrush rsync schedtool squashfs-tools xsltproc yasm zip \
zlib1g-dev device-tree-compiler expect g++ patchelf gawk texinfo chrpath diffstat binfmt-support qemu-user-static live-build fakeroot cmake ssh make gcc g++ unzip ncurses-dev python3-pip libncurses5 libc6:i386 genext2fs \
u-boot-tools mtools parted libudev-dev libusb-1.0-0-dev autoconf autotools-dev libsigsegv2 m4 intltool libdrm-dev sed binutils wget libglib2.0-dev libgtk2.0-dev libglade2-dev cvs mercurial gcc-arm-none-eabi gcc-arm-linux-gnueabi openjdk-8-jdk subversion asciidoc w3m dblatex graphviz device-tree-compiler flex bison openssl libssl-dev unzip git-lfs ccache libelf-dev default-jdk mtd-utils scons
SDK配置加载
首次编译需要加载SDK配置文件,进入rk3506_sdk目录,输入如下命令加载配置文件:
./build.sh buildroot-config
整体编译
运行整体编译(编译时间较长),输入如下命令:
./build.sh
编译成功后在rockdev/目录下可看到相关镜像,其中update.img是所有镜像的集合
单独编译uboot
编译前可先清除生成文件
cd u-boot/
make clean
2.回到SDK主目录,并进行uboot单独编译
cd ../
./build.sh uboot
单独编译Kernel
编译前可先清除生成文件
cd kernel/
make clean
回到SDK主目录,并进行kernel单独编译
cd ../
./build.sh kernel
单独编译recovery
在SDK主目录下输入如下命令:
./build.sh recovery
单独编译buildroot
在SDK主目录下输入如下命令:
./build.sh rootfs
打包固件
在SDK主目录下输入如下命令:
./build.sh firmware
打包update.img
在SDK下的output/update/Image目录里可以看到打包好的镜像update.img
在SDK主目录下输入如下命令:
./build.sh updateimg
完成上述操作后可按照刷机手册重新刷机
最后提示用户应该重新刷机测试
开发指导
UBOOT板级文件
U-boot板级文件:u-boot/board/rockchip/myzr_rk3506
U-boot板级配置文件:include/configs/myzr_rk3506.h
U-boot板级编译配置文件:configs/myzr_rk3506_defconfig
Linux内核板级文件
内核板级编译配置文件:kernel-6.1/arch/arm/configs/rk3506_defconfig
内核板级设备树文件:kernel-6.1/arch/arm/boot/dts/rockchip/myzr-rk3506-*.dts
GPIO
简介
GPIO是General Purpose I/O的缩写,即通用输入输出端口,简单来说就是MCU/CPU可控制的引脚, 这些引脚通常有多种功能,最基本的是高低电平输入检测和输出,部分引脚还会与主控器的片上外设绑定, 如作为串口、I2C、网络、电压检测的通讯引脚。Linux提供了GPIO子系统驱动框架,使用该驱动框架即可灵活地控制板子上的GPIO。
引脚命名规则
RK3562的GPIO分为4组(GPIO0~GPIO3),每组又以 A0~A7, B0~B7, C0~C7, D0~D7 作为编号区分。例如
GPIO0_C2表示第0组(GPIO0)的C组第2个引脚。
GPIO3_B5表示第3组(GPIO3)的B组第5个引脚。
GPIO引脚编号的计算公式
bank:GPIO组号(0~3)。
group:字母对应的组内序号(A=0,B=1,C=2,D=3)。
X:组内具体编号(0~7)。
number:组内编号,通过以下公式计算:
GPIO 小组编号计算公式:number = group * 8 + X
GPIO pin 编号计算公式:pin = bank * 32 + number
下面演示GPIO0_C2 pin脚计算方法:
bank = 4 (GPIO4)。
group = 1(B组对应1)。
X = 5 (B5的5)。
number = group * 8 + X = 2 * 8 + 2 = 18。
pin = bank*32 + number= 0 * 32 + 18 = 18。
通过/sys/class/gpio目录控制GPIO
在Linux中,最常见的读写GPIO方式就是用GPIO sysfs interface, 是通过操作 /sys/class/gpio 目录下的 export 、 unexport 、gpio{N}/direction, gpio{N} /value (用实际引脚号替代{N})等文件实现的,经常出现shell脚本里面。
echo 18 > /sys/class/gpio/export #使能引脚GPIO0_C2
echo out > gpio18/direction # 设置引脚为输出模式
echo 1 > gpio18/value # 设置引脚为高电平
cat /sys/class/gpio/gpio18/value # 读取引脚的值
echo 18 > /sys/class/gpio/unexport # 释放GPIO
注意事项:部分GPIO无法导出可能被复用为其他功能(如UART、I2C),需通过设备树确认实际用途。
UART
设备树配置
&uart3 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&rm_io14_uart3_tx &rm_io15_uart3_rx>;
};
pinctrl-0 = <&rm_io14_uart3_tx &rm_io15_uart3_rx>;的作用,绑定UART3的TX/RX引脚到rm_io14,15复用组。
uart3m0_xfer在rk3506-pinctrl-rmio.dtsi中已定义:
rm_io14_uart3_tx: rm-io14-uart3-tx {
rockchip,pins =
<0 RK_PB6 20 &pcfg_pull_none>;
};
rm_io15_uart3_rx: rm-io15-uart3-rx {
rockchip,pins =
<0 RK_PB7 21 &pcfg_pull_up>;
};
设备树配置好之后,UART3在系统中注册为/dev/ttyS3,可通过ls /dev/ttyS*验证。
调试工具
将uart3的rx tx短接,利用文件系统内放置的测试文件进行收发测试:
=====> Input:
# /myzr_test/uart/serial_test.out /dev/ttyS3 "myzr"
=====> Output:
Starting send data...finish
Starting receive data:
ASCII: 0x6d Character: m
ASCII: 0x79 Character: y
ASCII: 0x7a Character: z
ASCII: 0x72 Character: r
ASCII: 0x0 Character:
CAN
CAN 简介
CAN(Controller Area Network)总线,即控制器局域网总线,是一种有效支持分布式控制或实时控制的串行通信网络。CAN总线是一种在汽车上广泛采用的总线协议,被设计作为汽车环境中的微控制器通讯。 如果想了解更多的内容可以参考CAN应用报告
DTS 节点配置
公共配置 kernel/arch/arm/boot/dts/rk3506.dtsi
can0: can@ff320000 {
compatible = "rockchip,rk3506-canfd", "rockchip,rk3576-canfd";
reg = <0xff320000 0x1000>;
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru CLK_CAN0>, <&cru HCLK_CAN0>;
clock-names = "baudclk", "apb_pclk";
resets = <&cru SRST_CAN0>, <&cru SRST_H_CAN0>;
reset-names = "can", "can-apb";
status = "disabled";
};
板级配置 arch/arm/boot/dts/rockchip/myzr-rk3506-ek200.dts
&can0 {
status = "okay";
assigned-clocks = <&cru CLK_CAN0>;
assigned-clock-rates = <200000000>;
pinctrl-names = "default";
pinctrl-0 = <&rm_io19_can0_tx &rm_io20_can0_rx>;
};
CAN通信测试
使用 candump 和 cansend 工具进行收发报文测试即可,
#在收发端关闭can0设备
ip link set can0 down
#在收发端设置比特率为250Kbps
ip link set can0 type can bitrate 250000 dbitrate 1000000 fd on
#在收发端打开can0设备
ip link set can0 up
#在接收端执行candump,阻塞等待报文
candump can0
#在发送端执行cansend,发送报文
cansend can0 123#1122334455667788
更多指令
1、 ip link set canX down //关闭can设备;
2、 ip link set canX up //开启can设备;
3、 ip -details link show canX //显示can设备详细信息;
4、 candump canX //接收can总线发来数据;
5、 ifconfig canX down //关闭can设备,以便配置;
6、 ip link set canX up type can bitrate 250000 //设置can波特率
7、 conconfig canX bitrate + 波特率;
8、 canconfig canX start //启动can设备;
9、 canconfig canX ctrlmode loopback on //回环测试;
10、canconfig canX restart // 重启can设备;
11、canconfig canX stop //停止can设备;
12、canecho canX //查看can设备总线状态;
13、cansend canX --identifier=ID+数据 //发送数据;
14、candump canX --filter=ID:mask //使用滤波器接收ID匹配的数据
报文发送后很久才接收到,或者接收不到。
检查总线 CAN_H 和 CAN_L, 杜邦线是否松动或者接反。
Ethernet
开发板有俩个网口:J14、J15,以J14说明,J15同理
俩个网口都支持连接外网。
dts 配置
1.1 公共的配置
kernel-6.1/arch/arm/boot/dts/rockchip/rk3506.dtsi
gmac0: ethernet@ff4c8000 {
compatible = "rockchip,rk3506-gmac", "snps,dwmac-4.20a";
reg = <0xff4c8000 0x2000>;
interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq", "eth_wake_irq";
rockchip,grf = <&grf>;
clocks = <&cru CLK_MAC0>, <&cru CLK_MAC0_PTP>,
<&cru PCLK_MAC0>, <&cru ACLK_MAC0>;
clock-names = "stmmaceth", "ptp_ref",
"pclk_mac", "aclk_mac";
resets = <&cru SRST_A_MAC0>;
reset-names = "stmmaceth";
snps,mixed-burst;
snps,tso;
snps,axi-config = <&gmac0_stmmac_axi_setup>;
snps,mtl-rx-config = <&gmac0_mtl_rx_setup>;
snps,mtl-tx-config = <&gmac0_mtl_tx_setup>;
phy-mode = "rmii";
status = "disabled";
mdio0: mdio {
compatible = "snps,dwmac-mdio";
#address-cells = <0x1>;
#size-cells = <0x0>;
};
gmac0_stmmac_axi_setup: stmmac-axi-config {
snps,wr_osr_lmt = <4>;
snps,rd_osr_lmt = <8>;
snps,blen = <0 0 0 0 16 8 4>;
};
gmac0_mtl_rx_setup: rx-queues-config {
snps,rx-queues-to-use = <1>;
queue0 {
status = "okay";
};
};
gmac0_mtl_tx_setup: tx-queues-config {
snps,tx-queues-to-use = <1>;
queue0 {
status = "okay";
};
};
};
1.2 板级的配置
kernel-6.1/arch/arm/boot/dts/rockchip/myzr-gmac0-100m.dtsi
&gmac0 {
status = "okay";
phy-mode = "rmii";
clock_in_out = "output";
snps,reset-gpio = <&nca9555_gpio IO_00 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 10000 100000>;
compatible = "rockchip,rk3506-gmac", "snps,dwmac-4.20a";
tx_delay = <0x1a>;
rx_delay = <0x21>;
phy-handle = <&rmii_phy0>;
pinctrl-names = "default";
pinctrl-0 = <ð_rmii0_miim_pins
ð_rmii0_tx_bus2_pins
ð_rmii0_rx_bus2_pins
ð_rmii0_clk_pins>;
};
网口没有自动获取ip
等待或者电脑网络适配器能上网的网口关掉共享给以太网网口并重新开启共享,再重启板子便能自动获取ip。
I2C
I2C 子系统架构概述
在 RK3506 平台中,I2C 控制器基于标准 Linux I2C 框架实现,其核心分为硬件抽象层(适配器驱动)和设备驱动层。硬件层通过 i2c_adapter 抽象 I2C 总线控制器,设备层通过 i2c_client 描述从机设备,两者通过 i2c_driver 实现驱动逻辑。RK3562 的 I2C 控制器支持多主模式、时钟分频(最高 400kHz)及中断/DMA 传输,其物理层遵循开漏输出特性,通过 GPIO 复用实现 SCL/SDA 信号。
I2C设备树配置
以I2C1上挂载gt9触摸芯片为例,打开myzr-lcd-mipi-7-1024-600.dtsi进行配置
&i2c2 {
status = "okay";
pinctrl-names = "default";
goodix_ts: goodix_ts@5d {
compatible = "goodix,gt9xx";
reg = <0x5d>;
gtp_resolution_x = <1024>;
gtp_resolution_y = <600>;
gtp_int_tarigger = <1>;
gtp_change_x2y = <0>;
gtp_overturn_x = <0>;
gtp_overturn_y = <0>;
gtp_send_cfg = <1>;
gtp_touch_wakeup = <1>;
goodix_rst_gpio = <&gpio0 RK_PA7 GPIO_ACTIVE_HIGH>;
goodix_irq_gpio = <&gpio0 RK_PA6 IRQ_TYPE_EDGE_FALLING>;
goodix,cfg-group0 = [ //old touch
...
];
goodix,cfg-group5 = [ //new touch
...
];
};
};
在该节点中, 内核通过compatible字符串匹配驱动。例如,驱动代码中gt9xx.c需定义相同的 of_device_id 表:
static struct of_device_id goodix_ts_dt_ids[] = {
{ .compatible = "goodix,gt9xx" },
{ }
};
设备在 I2C 总线上的地址(0x5d),驱动通过 i2c_client 结构体获取reg地址。而pinctrl-*引用 touch_gpio 节点来配置 GPIO 的复用功能和电气属性。
驱动与设备树匹配,compatible 值与驱动匹配时,内核调用 .probe() 函数,在probe函数中驱动将会从设备树获取配置包括引脚配置,芯片型号等信息。
当设备在i2c上注册成功,利用指令:
i2cdetect -y 1
可以看到i2c1上地址5d出现字母“UU”,代表该设备在i2c上成功挂载。