002 学习firefly-rk3399 wiki中gpio操作
- Docs » GPIO 使用
GPIO 使用
简介
GPIO, 全称 General-Purpose Input/Output(通用输入输出),是一种软件运行期间能够动态配置和控制的通用引脚。 RK3399 有 5 组 GPIO bank:GPIO0-GPIO4,每组又以 A0-A7, B0-B7, C0-C7, D0-D7 作为编号区分。所有的 GPIO 在上电后的初始状态都是输入模式,可以通过软件设为上拉或下拉,也可以设置为中断脚,驱动强度都是可编程的。 每个 GPIO 口除了通用输入输出功能外,还可能有其它复用功能,例如 GPIO2_A2,可以利用成以下功能:
- GPIO2_A2
- GIF_D2
每个 GPIO 口的驱动电流、上下拉和重置后的初始状态都不尽相同,详细情况请参考《RK3399 规格书》中的 “Chapter 10 GPIO” 一章。 RK3399 的 GPIO 驱动是在以下 pinctrl 文件中实现的:
kernel/drivers/pinctrl/pinctrl-rockchip.c
其核心是填充 GPIO bank 的方法和参数,并调用 gpiochip_add 注册到内核中。
Firefly-RK3399 开发板为方便用户开发使用,引出了一排通用的 GPIO 口,其对应引脚如下图:
找到原理图中J21信息如下:
其中TP_RST在原理图中信息如下:
在cpu的datasheet中查找V26脚,信息如下:
本文以 TP_RST(GPIO0_B4) 和 LCD_RST(GPIO4_D5) 这两个通用 GPIO 口为例写了一份简单操作 GPIO 口的驱动,在 SDK 的路径为:
kernel/drivers/gpio/gpio-firefly.c
以下就以该驱动为例介绍 GPIO 的操作。
输入输出
首先在 DTS 文件中增加驱动的资源描述:
kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly-demo.dtsi
gpio_demo: gpio_demo {status = "okay";compatible = "firefly,rk3399-gpio";firefly-gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>; /* GPIO0_B4 */firefly-irq-gpio = <&gpio4 29 IRQ_TYPE_EDGE_RISING>; /* GPIO4_D5 */};
这里定义了一个脚作为一般的输出输入口:
firefly-gpio GPIO0_B4
Firefly-RK3399 的 dts 对引脚的描述与 Firefly-RK3288 有所区别,GPIO0_B4 被描述为:<&gpio0 12 GPIO_ACTIVE_HIGH>,这里的 12 来源于:8+4=12,其中 8 是因为 GPIO0_B4 是属于 GPIO0 的 B 组,1x8*,如果是 A 组的话则为 0,0x8*,如果是 C 组则为 16,2x8,如果是 D 组则为 24,3x8,以此递推。而 4 是因为 B4 后面的 4。
datasheet中信息如下:
GPIO_ACTIVE_HIGH
表示高电平有效,如果想要低电平有效,可以改为:GPIO_ACTIVE_LOW
,这个属性将被驱动所读取。
然后在 probe 函数中对 DTS 所添加的资源进行解析,代码如下:
static int firefly_gpio_probe(struct platform_device *pdev)
{int ret;int gpio;enum of_gpio_flags flag;struct firefly_gpio_info *gpio_info;struct device_node *firefly_gpio_node = pdev->dev.of_node;printk("Firefly GPIO Test Program Probe\n");gpio_info = devm_kzalloc(&pdev->dev,sizeof(struct firefly_gpio_info *), GFP_KERNEL);if (!gpio_info) {return -ENOMEM;}gpio = of_get_named_gpio_flags(firefly_gpio_node, "firefly-gpio", 0, &flag);if (!gpio_is_valid(gpio)) {printk("firefly-gpio: %d is invalid\n", gpio); return -ENODEV;}if (gpio_request(gpio, "firefly-gpio")) {printk("gpio %d request failed!\n", gpio);gpio_free(gpio);return -ENODEV;}gpio_info->firefly_gpio = gpio;gpio_info->gpio_enable_value = (flag == OF_GPIO_ACTIVE_LOW) ? 0:1;gpio_direction_output(gpio_info->firefly_gpio, gpio_info->gpio_enable_value);printk("Firefly gpio putout\n");...
}
of_get_named_gpio_flags
从设备树中读取 firefly-gpio
和 firefly-irq-gpio
的 GPIO 配置编号(12和29)和标志(GPIO_ACTIVE_HIGH和IRQ_TYPE_EDGE_RISING)。
gpio_is_valid
判断该 GPIO 编号是否有效。
gpio_request
则申请占用该 GPIO。如果初始化过程出错,需要调用 gpio_free
来释放之前申请过且成功的 GPIO 。
gpio_direction_output
可以设置输出高还是低电平,这里默认输出从 DTS 获取得到的有效电平 GPIO_ACTIVE_HIGH
,即为高电平。
如果驱动正常工作,可以用万用表测得对应的引脚应该为高电平。
实际中如果要读出 GPIO,需要先设置成输入模式,然后再读取值:
int val;
gpio_direction_input(your_gpio);
val = gpio_get_value(your_gpio);
下面是常用的 GPIO API 定义:
#include <linux/gpio.h>
#include <linux/of_gpio.h>enum of_gpio_flags {OF_GPIO_ACTIVE_LOW = 0x1,
};
int of_get_named_gpio_flags(struct device_node *np, const char *propname, int index, enum of_gpio_flags *flags);
int gpio_is_valid(int gpio);
int gpio_request(unsigned gpio, const char *label);
void gpio_free(unsigned gpio);
int gpio_direction_input(int gpio);
int gpio_direction_output(int gpio, int v);
中断
在 Firefly 的例子程序中还包含了一个中断引脚,GPIO 口的中断使用与 GPIO 的输入输出类似,首先在 DTS 文件中增加驱动的资源描述:
kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly-port.dtsi
gpio {compatible = "firefly-gpio";firefly-irq-gpio = <&gpio4 29 IRQ_TYPE_EDGE_RISING>; /* GPIO4_D5 */
};
IRQ_TYPE_EDGE_RISING 表示中断由上升沿触发,当该引脚接收到上升沿信号时可以触发中断函数。 这里还可以配置成如下:
IRQ_TYPE_NONE //默认值,无定义中断触发类型
IRQ_TYPE_EDGE_RISING //上升沿触发
IRQ_TYPE_EDGE_FALLING //下降沿触发
IRQ_TYPE_EDGE_BOTH //上升沿和下降沿都触发
IRQ_TYPE_LEVEL_HIGH //高电平触发
IRQ_TYPE_LEVEL_LOW //低电平触发
然后在 probe 函数中对 DTS 所添加的资源进行解析,再做中断的注册申请,代码如下:
static int firefly_gpio_probe(struct platform_device *pdev)
{int ret;int gpio;enum of_gpio_flags flag;struct firefly_gpio_info *gpio_info;struct device_node *firefly_gpio_node = pdev->dev.of_node;...gpio_info->firefly_irq_gpio = gpio;gpio_info->firefly_irq_mode = flag;gpio_info->firefly_irq = gpio_to_irq(gpio_info->firefly_irq_gpio);if (gpio_info->firefly_irq) {if (gpio_request(gpio, "firefly-irq-gpio")) {printk("gpio %d request failed!\n", gpio); gpio_free(gpio); return IRQ_NONE;}ret = request_irq(gpio_info->firefly_irq, firefly_gpio_irq, flag, "firefly-gpio", gpio_info);if (ret != 0) free_irq(gpio_info->firefly_irq, gpio_info);dev_err(&pdev->dev, "Failed to request IRQ: %d\n", ret);}return 0;
}
static irqreturn_t firefly_gpio_irq(int irq, void *dev_id) //中断函数打印log
{printk("Enter firefly gpio irq test program!\n");return IRQ_HANDLED;
}
调用 gpio_to_irq
把 GPIO 的 PIN 值转换为相应的 IRQ 值。
调用 gpio_request
申请占用该 IO 口。
调用 request_irq
申请中断,如果失败要调用 free_irq
释放,该函数中 gpio_info-firefly_irq
是要申请的硬件中断号。
firefly_gpio_irq
是中断函数。
gpio_info->firefly_irq_mode
是中断处理的属性。
firefly-gpio
是设备驱动程序名称。
gpio_info
是该设备的 device
结构,在注册共享中断时会用到。
完整代码如下:
/** Driver for pwm demo on Firefly board.** Copyright (C) 2016, Zhongshan T-chip Intelligent Technology Co.,ltd.* Copyright 2006 JC.Lin** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License version 2 as* published by the Free Software Foundation.*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>struct firefly_gpio_info {int firefly_gpio;int gpio_enable_value;int firefly_irq_gpio;int firefly_irq;int firefly_irq_mode;
};static irqreturn_t firefly_gpio_irq(int irq, void *dev_id)
{printk("Enter firefly gpio irq test program!\n");return IRQ_HANDLED;
}static int firefly_gpio_probe(struct platform_device *pdev)
{int ret;int gpio;enum of_gpio_flags flag;struct firefly_gpio_info *gpio_info;struct device_node *firefly_gpio_node = pdev->dev.of_node;printk("Firefly GPIO Test Program Probe\n");gpio_info = devm_kzalloc(&pdev->dev,sizeof(struct firefly_gpio_info *), GFP_KERNEL);if (!gpio_info) {dev_err(&pdev->dev, "devm_kzalloc failed!\n");return -ENOMEM;}gpio = of_get_named_gpio_flags(firefly_gpio_node, "firefly-gpio", 0, &flag);//flag 即设备树种gpio的第三个参数“GPIO_ACTIVE_LOW”if (!gpio_is_valid(gpio)) {dev_err(&pdev->dev, "firefly-gpio: %d is invalid\n", gpio);return -ENODEV;}if (gpio_request(gpio, "firefly-gpio")) {dev_err(&pdev->dev, "firefly-gpio: %d request failed!\n", gpio);gpio_free(gpio);return -ENODEV;}gpio_info->firefly_gpio = gpio;gpio_info->gpio_enable_value = (flag == OF_GPIO_ACTIVE_LOW) ? 0:1;gpio_direction_output(gpio_info->firefly_gpio, gpio_info->gpio_enable_value);printk("Firefly gpio putout\n");
/*********************************************************************************************/gpio = of_get_named_gpio_flags(firefly_gpio_node, "firefly-irq-gpio", 0, &flag);printk("firefly:the gpio:%d\n",gpio);if (!gpio_is_valid(gpio)) {dev_err(&pdev->dev, "firefly-irq-gpio: %d is invalid\n", gpio);return -ENODEV;}gpio_info->firefly_irq_gpio = gpio;gpio_info->firefly_irq_mode = flag;gpio_info->firefly_irq = gpio_to_irq(gpio_info->firefly_irq_gpio);if (gpio_info->firefly_irq) {if (gpio_request(gpio, "firefly-irq-gpio")) {dev_err(&pdev->dev, "firefly-irq-gpio: %d request failed!\n", gpio);gpio_free(gpio);return IRQ_NONE;}ret = request_irq(gpio_info->firefly_irq, firefly_gpio_irq,flag, "firefly-gpio", gpio_info);if (ret != 0) {free_irq(gpio_info->firefly_irq, gpio_info);dev_err(&pdev->dev, "Failed to request IRQ: %d\n", ret);}}return 0;
}static struct of_device_id firefly_match_table[] = {{ .compatible = "firefly,rk3399-gpio",},{},
};static struct platform_driver firefly_gpio_driver = {.driver = {.name = "firefly-gpio",.owner = THIS_MODULE,.of_match_table = firefly_match_table,},.probe = firefly_gpio_probe,
};static int firefly_gpio_init(void)
{return platform_driver_register(&firefly_gpio_driver);
}
module_init(firefly_gpio_init);static void firefly_gpio_exit(void)
{platform_driver_unregister(&firefly_gpio_driver);
}
module_exit(firefly_gpio_exit);MODULE_AUTHOR("linjc <service@t-firefly.com>");
MODULE_DESCRIPTION("Firefly GPIO driver");
MODULE_ALIAS("platform:firefly-gpio");
MODULE_LICENSE("GPL");
实践操作:
通过git reset --hard命令同步最新代码。
用git log --oneline看历次提交信息。
root@ubuntu:~/proj/firefly-rk3399-Industry# git log --oneline
4aa96f4708 (HEAD -> firefly) 1.Add ROC-RK3399-PC-Pro device support 2.Add XC7160 mipi camera support 3.Add ec200T 4G dongle support 4.Add XM25QH128C Nor flash supports
bb81e222fe 1.Fix bcmdhd some bug 2.Close usb print
291f219487 1.Fix uboot emmc clk 2.Updtae bcmdhd driver 3.Add AP6398SV wifi support 4.Add ROC-RK3399-PC-Pro device 5.Add RKDocs
12ac733bd3 1.Udpate ap6256 firmware 2.Add AIO-3399CC device 3.Fix usb wifi bootup mode
7fb75f3835 1.Add CM256SM wifi support 2.Fix HDR format video playing green flash 3.Add focaltech touch support
7fc8869d2e 1.Face app update new version 2. Fix two USB cameras issue 3.Update all_v3.1 4.Add ScheduleOnOff
979e2f6841 1.Add R2 server product 2.Add MIPI JDM101007-BC40 support 3.Fix some Permission 4.Support NMEA Protocol GPS module for GPS, GLONASS, GALILEO, BEIDOU
8b286a5f67 1.Fix AIOC-3399J io-domain for spi2 transte 2.SERVER-R1 Add usb ethernet power pin control 3.Wiegand modify head data delay time
041f5bd233 1.Support Wifi AP6256 2.Face App update 3.Support rk structured light camera 4.SERVER fix some error
ece971d57d 1.Face app fix some issue and add identification function 2.AIO-3399C camera Compatible and fan support
6e665119cb 1.Add device rk3399-firefly-server-sub 2.face app update 3.Add AIO-3399JD4 lvds support 4.Add AIO-3399C-AI mipi screen support
39f31348ad 1.Add ttysWK nodes permisson 2.Fix 10.1 lvds screen parameter and dsi clock 3.Add eth mac address and serial number display 4.fix hdmi 4k resolution 5.Fix firefly api function
e15d58b4e2 (tag: public_b437a2676020a03854e555184641ec7e7bb3946c) 1.add JD4 device support 2.roc-rk3399pc+ lcd support 3.screen orientation issue
9888ad635e 1.ROC add edp dts 2.Add radar support 3.HDMIIN apk fix some issue 4.GTI 5801 firmware
258e4bbf26 1.optimize network connection 2.update OpenAI lib. 3.support radar detect 4.fix some issue of the displaying abnormal parts 5.support ROC-RK3399-PC-PLUS
8856fe97fa 1.update OpenAilib.apk ,bootanimation 2.update driver:led backlight wifi tp wiegand camera 3.update product AIOC-AI
08ada8868b (tag: Face-RK3399_Android7.1.2_DEFAULT_190702) Android7.1 Industry SDK init, support FaceX1 and AIO-3399C-AI
root@ubuntu:~/proj/firefly-rk3399-Industry#
安装gitk后,直接用gitk命令看每次提交的文件修改:
查看哪次提交了gpio-firefly.c文件:git log gpio-firefly.c
root@ubuntu:~/proj/firefly-rk3399-Industry/kernel/drivers/gpio# git log gpio-firefly.c
commit 8856fe97fafb4e0d7094104d0463f3a149109007
Author: zjy <service@t-firefly.com>
Date: Thu Aug 1 16:43:51 2019 +0800
1.update OpenAilib.apk ,bootanimation 2.update driver:led backlight wifi tp wiegand camera 3.update product AIOC-AI
root@ubuntu:~/proj/firefly-rk3399-Industry/kernel/drivers/gpio#
查看具体提交信息:gitk 8856fe97fafb4e0d7094104d0463f3a149109007
由上面可知,文件是一次性提交的。
用下面命令编译kernel和u-boot。
cd ~/proj/xxx/kernel/
make ARCH=arm64 firefly_defconfig
make -j8 ARCH=arm64 rk3399-firefly.img
cd ~/proj/xxx/u-boot/
make rk3399_defconfig
make ARCHV=aarch64 -j8
kernel编译log:
root@ubuntu:~/proj/firefly-rk3399-Industry/kernel# make ARCH=arm64 firefly_defconfig
#
# configuration written to .config
#
root@ubuntu:~/proj/firefly-rk3399-Industry/kernel# make -j8 ARCH=arm64 rk3399-firefly.img
scripts/kconfig/conf --silentoldconfig KconfigCHK include/config/kernel.releaseCHK include/generated/uapi/linux/version.hCHK include/generated/utsrelease.hCHK scripts/mod/devicetable-offsets.hDTC arch/arm64/boot/dts/rockchip/rk3399-firefly.dtbCHK include/generated/timeconst.hCHK include/generated/bounds.hCHK include/generated/asm-offsets.hCALL scripts/checksyscalls.sh
Pack to resource.img successed!Image: resource.img (with rk3399-firefly.dtb logo.bmp ) is ready
make[1]: 'include/generated/vdso-offsets.h' is up to date.CHK include/generated/compile.hGZIP kernel/config_data.gzCHK kernel/config_data.h
make[1]: 'arch/arm64/boot/Image' is up to date.Image: kernel.img is readyCHK include/config/kernel.releaseCHK include/generated/uapi/linux/version.hCHK include/generated/utsrelease.hCHK scripts/mod/devicetable-offsets.hCHK include/generated/timeconst.hCHK include/generated/bounds.hCHK include/generated/asm-offsets.hCALL scripts/checksyscalls.sh
make[2]: 'include/generated/vdso-offsets.h' is up to date.Building modules, stage 2.MODPOST 12 modulesImage: boot.img (with Image resource.img) is ready
root@ubuntu:~/proj/firefly-rk3399-Industry/u-boot#
u-boot编译log:
root@ubuntu:~/proj/firefly-rk3399-Industry/kernel# cd ../u-boot/
root@ubuntu:~/proj/firefly-rk3399-Industry/u-boot# make rk3399_defconfig
#
# configuration written to .config
#
root@ubuntu:~/proj/firefly-rk3399-Industry/u-boot# make ARCHV=aarch64 -j8
scripts/kconfig/conf --silentoldconfig KconfigCHK include/config.hGEN include/autoconf.mk.depGEN include/autoconf.mkCHK include/config/uboot.releaseCHK include/generated/timestamp_autogenerated.hUPD include/generated/timestamp_autogenerated.hCHK include/generated/version_autogenerated.hHOSTCC tools/dumpimage.oHOSTCC tools/image-host.oHOSTCC tools/mkimage.oHOSTCC tools/mkenvimage.oHOSTCC tools/loaderimage.oHOSTCC tools/boot_mergerHOSTLD tools/mkimageHOSTLD tools/dumpimageHOSTLD tools/mkenvimageHOSTLD tools/loaderimageHOSTLD tools/trust_mergerHOSTLD tools/checksum
tools/boot_merger.c: In function ‘initOpts’:
tools/boot_merger.c:491:14: warning: ‘_loader_v’ directive output may be truncated writing 9 bytes into a region of size between 1 and 256 [-Wformat-truncation=]"%s_loader_v%d.%02d.%d%02d.bin", gOpts.chip, v0, v1, v2, v3);^~~~~~~~~
In file included from /usr/include/stdio.h:862:0,from /root/proj/firefly-rk3399-Industry/u-boot/include/compiler.h:25,from /root/proj/firefly-rk3399-Industry/u-boot/include/libfdt_env.h:12,from <command-line>:0:
/usr/include/x86_64-linux-gnu/bits/stdio2.h:64:10: note: ‘__builtin___snprintf_chk’ output between 22 and 315 bytes into a destination of size 256return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~__bos (__s), __fmt, __va_arg_pack ());~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~CC board/rockchip/rk33xx/rk33xx.oLD board/rockchip/rk33xx/built-in.oCC board/rockchip/common/rkboot/fastboot.oCC common/main.oLD board/rockchip/common/built-in.oCC common/board_f.oCC common/cmd_version.oCC common/cmd_fastboot.oCC common/cmd_bootrk.oLD common/built-in.oCC lib/display_options.oLD lib/built-in.oLD u-bootOBJCOPY u-boot.bin
start=$(/root/proj/firefly-rk3399-Industry/u-boot/../prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-nm u-boot | grep __rel_dyn_start | cut -f 1 -d ' '); end=$(/root/proj/firefly-rk3399-Industry/u-boot/../prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-nm u-boot | grep __rel_dyn_end | cut -f 1 -d ' '); tools/relocate-rela u-boot.bin 0x00200000 $start $endOBJCOPY u-boot.srec
./tools/boot_merger --prepath tools/rk_tools/ ./tools/rk_tools/RKBOOT/RK3399MINIALL.ini
out:rk3399_loader_v1.24.126.bin
fix opt:rk3399_loader_v1.24.126.bin
merge success(rk3399_loader_v1.24.126.bin)
./tools/trust_merger --prepath tools/rk_tools/ ./tools/rk_tools/RKTRUST/RK3399TRUST.ini
out:trust.img
merge success(trust.img)
./tools/loaderimage --pack --uboot u-boot.bin uboot.imgload addr is 0x200000!
pack input u-boot.bin
pack file size: 554012(541 KB)
crc = 0xe0e83a0c
uboot version: U-Boot 2014.10-RK3399-06 (Sep 06 2022 - 22:32:33)
pack uboot.img success!
root@ubuntu:~/proj/firefly-rk3399-Industry/u-boot#
打包命令:
root@ubuntu:~/proj/firefly-rk3399-Industry# ./FFTools/mkupdate/mkupdate.sh -l rk3399_firefly-userdebug============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=7.1.2
TARGET_PRODUCT=rk3399_firefly
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm64
TARGET_ARCH_VARIANT=armv8-a
TARGET_CPU_VARIANT=cortex-a53
TARGET_2ND_ARCH=arm
TARGET_2ND_ARCH_VARIANT=armv7-a-neon
TARGET_2ND_CPU_VARIANT=cortex-a53.a57
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-5.4.0-124-generic-x86_64-with-Ubuntu-18.04-bionic
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=NHG47K
OUT_DIR=out
DEVICE_VERSION=
============================================
PRODUCT_FIREFLY_NAME=HDMI
TARGET_PRODUCT=rk3399_fireflyPRODUCT_MODEL=Firefly-RK3399
Android Firmware Package Tool v1.62
------ PACKAGE ------
Add file: ./package-file
Add file: ./Image/MiniLoaderAll.bin
Add file: ./Image/parameter.txt
Add file: ./Image/trust.img
Add file: ./Image/uboot.img
Add file: ./Image/misc.img
Add file: ./Image/resource.img
Add file: ./Image/kernel.img
Add file: ./Image/boot.img
Add file: ./Image/recovery.img
Add file: ./Image/system.img
Add file: ./Image/oem.img
Add CRC...
Make firmware OK!
------ OK ------
********RKImageMaker ver 1.63********
Generating new image, please wait...
Writing head info...
Writing boot file...
Writing firmware...
Generating MD5 data...
MD5 data generated successfully!
New image generated successfully!Making updateimg: rockdev/Image-rk3399_firefly/Firefly-RK3399_Industry7.1.2_HDMI_220907.img
root@ubuntu:~/proj/firefly-rk3399-Industry#
编译出的固件位置:
导出到Windows中用RKDevTool.exe下载测试:
firefly维基中Loader 升级模式
有关启动模式的介绍,请参阅《更新固件介绍》一章
简介
在 Loader 模式下,bootloader 会进入升级状态,等待主机命令,用于固件升级等。要进入 Loader 模式,必须让 bootloader 在启动时检测到 RECOVERY(恢复)键按下,且 USB 处于连接状态。
使设备进入升级模式的方法如下:一种方式是断开电源适配器
Type-C数据线连接好设备和主机。
按住设备上的 RECOVERY (恢复)键并保持。
插上电源
大约两秒钟后,松开 RECOVERY 键。另一种方式是接上电源适配器
Type-C数据线连接好设备和主机。
按住设备上的 RECOVERY (恢复)键并保持。
短按一下 RESET(复位)键。
大约两秒钟后,松开 RECOVERY 键。
升级前:
升级后:
重启后,抓取操作时的串口log:
波特率选择115200
调试结果:
无法开机,串口只有一点乱码,之后不打印信息。
重新下载官方固件包,再测试串口信息。
无法下载,loader模式出不来了。一直提示MASKROM设备。
等一分钟再重试,可以下载了。
因为个人电脑原因突然蓝屏了,重启电脑后重新下载,结果只执行一点信息就失败了,没有重启电脑前执行那么多。
开发板断电,等一分钟后重新下载。
重新插入USB+按recovery键+插入电源后,loader模式突然出来了。
这下应该能正常下载了。
下载官方固件后,自动重启。
抓取开机log:
结果全是乱码。
网上说rk3399默认波特率是1500000,我修改后还是乱码。
网上修改方案如下:
可能是usb转串口工具不支持1500000,只能通过kmsg看kernel log了。
office
里面没搜到gpio-firefly.c中相关log,怀疑没有编译进去。
但是上面提交记录中2019年这个文件就已经提交了,我下载的官方固件包是2021年的,应该包含了才对,除非里面特意去掉了这个驱动。
看了只能自己编译刷机了,之前只下载kernel.img,无法开机。
这次打包后下载整个img文件。
测试结果:
dmesg log中还是没有gpio-firefly.c中相关log
调试方案:
修改.c文件同目录下的Makefile,改为obj-m,编译出ko文件,push进机器中,执行insmod。
测试结果:
现象+log分析:
目前这个文件还是没法使用。
20220907 start
还是要想办法把串口log打印出来才行。
调试方案:
下载官网固件:
Firefly-RK3399_Industry7.1.2_HDMI_211215.img
查看串口设备:
rk3399_firefly:/dev # ls -la tty*
crw-rw-rw- 1 root root 5, 0 2013-01-18 08:51 tty
crw------- 1 root root 254, 0 2013-01-18 08:51 ttyFIQ0
crw-rw-rw- 1 bluetooth net_bt_stack 4, 64 2013-01-18 08:51 ttyS0
crw-rw-rw- 1 gps gps 4, 68 2013-01-18 08:51 ttyS4
查看串口log:
有串口boot log和kernel log。
下载之前0907编译的固件:
Firefly-RK3399_Industry7.1.2_HDMI_220907.img
查看串口设备:
rk3399_firefly:/dev # ls -la tty*
crw-rw-rw- 1 root root 5, 0 2013-01-18 08:52 tty
crw------- 1 root root 254, 0 2013-01-18 08:52 ttyFIQ0
crw-rw-rw- 1 bluetooth net_bt_stack 4, 64 2013-01-18 08:52 ttyS0
crw-rw-rw- 1 gps gps 4, 68 2013-01-18 08:52 ttyS4
查看串口log:
只有boot log,没有kernel log
下载之前0908编译的固件:
Firefly-RK3399_Industry7.1.2_HDMI_220908.img
查看串口设备:
rk3399_firefly:/dev # ls -la tty*
crw-rw-rw- 1 root root 5, 0 2013-01-18 08:52 tty
crw------- 1 root root 254, 0 2013-01-18 08:52 ttyFIQ0
crw-rw-rw- 1 bluetooth net_bt_stack 4, 64 2013-01-18 08:52 ttyS0
crw-rw-rw- 1 gps gps 4, 68 2013-01-18 08:52 ttyS4
rk3399_firefly:/dev #
查看串口log:
只有boot log,没有kernel log
下载之前0909编译的固件:
Firefly-RK3399_Industry7.1.2_HDMI_220909.img
修改内容:
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399-android.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3399-android.dtsi
index 4bc8254fbf..a427430297 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399-android.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399-android.dtsi
@@ -80,6 +80,7 @@fiq_debugger: fiq-debugger {compatible = "rockchip,fiq-debugger";rockchip,serial-id = <2>;rockchip,wake-irq = <0>;rockchip,irq-mode-enable = <0>; /* If enable uart uses irq instead of fiq */rockchip,baudrate = <1500000>; /* Only 115200 and 1500000 */pinctrl-names = "default";pinctrl-0 = <&uart2c_xfer>;interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH 0>;
+ status = "disabled";};reserved-memory {
diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly.dtsi
index c2fa96f9e8..4dc387728c 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly.dtsi
@@ -110,4 +110,9 @@};};+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2c_xfer>;
+ status = "disabled";
+};diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/kernel/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index 275a7479b5..9ad9bd16cf 100644
--- a/kernel/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/kernel/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -671,7 +671,7 @@uart2: serial@ff1a0000 {compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart";reg = <0x0 0xff1a0000 0x0 0x100>;clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;clock-names = "baudclk", "apb_pclk";interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH 0>;reg-shift = <2>;reg-io-width = <4>;pinctrl-names = "default";pinctrl-0 = <&uart2c_xfer>;
- status = "disabled";
+ status = "okay";};uart3: serial@ff1b0000 {
查看串口设备:
rk3399_firefly:/dev # ls -la tty*
crw-rw-rw- 1 root root 5, 0 2013-01-18 08:52 tty
crw-rw-rw- 1 bluetooth net_bt_stack 4, 64 2013-01-18 08:52 ttyS0
crw-rw-rw- 1 gps gps 4, 68 2013-01-18 08:52 ttyS4
查看串口log:
只有boot log,没有kernel log
现象+log分析:
这次修改后,ttyFiQ反而没有了。
网上有篇文章提到ttyFiQ:
https://www.codenong.com/cs108935413/
24、RK3399通过设备树来打开debug串口
• 1、修改chosen节点的bootargs
• 2、修改fiq_debugger节点
• 3、添加uart2使能
----------------------
1、修改chosen节点的bootargs
文件为:kernel/arch/arm64/boot/dts/rockchip/rk3399-linux.dtsi
修改为:
chosen {<!-- -->bootargs = "earlycon=uart8250,mmio32,0xff1a0000 swiotlb=1 console=ttyFIQ0 ro root=PARTLABEL=rootfs rootfstype=ext4 rootwait overlayroot=device:dev=PARTLABEL=userdata,fstype=ext4,mkfs=1 coherent_pool=1m systemd.gpt_auto=0 cgroup_enable=memory swapaccount=1";};
主要是添加console=ttyFIQ0
----------------------
2、修改fiq_debugger节点
fiq_debugger: fiq-debugger {<!-- -->//status = "disabled"; //这里要打开,不写默认为打开compatible = "rockchip,fiq-debugger";rockchip,serial-id = <2>;rockchip,signal-irq = <182>;rockchip,wake-irq = <0>;rockchip,irq-mode-enable = <1>; /* If enable uart uses irq instead of fiq */rockchip,baudrate = <1500000>; /* Only 115200 and 1500000 */pinctrl-names = "default";pinctrl-0 = <&uart2c_xfer>;};
3、添加uart2使能
&uart2 {<!-- -->//这里要将串口本身关闭才可以用debug口status = "disabled";
};
修改方案:
对照修改,发现只有“修改fiq_debugger节点”里面有“disable”其他已经有了。
调试结果:
查看串口设备:
rk3399_firefly:/dev # ls -la tty*
crw-rw-rw- 1 root root 5, 0 2013-01-18 08:52 tty
crw------- 1 root root 254, 0 2013-01-18 08:52 ttyFIQ0
crw-rw-rw- 1 bluetooth net_bt_stack 4, 64 2013-01-18 08:52 ttyS0
crw-rw-rw- 1 gps gps 4, 68 2013-01-18 08:52 ttyS4
rk3399_firefly:/dev #
查看串口log:
终于有kernel log了。
[ 861.211355] android_work: sent uevent USB_STATE=DISCONNECTED
[ 861.213663] configfs-gadget gadget: unbind function 'mtp'/ffffffc0f1d4a000
[ 861.213720] configfs-gadget gadget: unbind function 'Function FS Gadget'/ffffffc0eef88838
[ 861.213793] android_work: did not send uevent (0 0 (null))
[ 861.419180] android_work: did not send uevent (0 0 (null))
[ 861.486848] android_work: sent uevent USB_STATE=CONNECTED
[ 861.495674] configfs-gadget gadget: high-speed config #1: b
[ 861.496229] android_work: sent uevent USB_STATE=CONFIGURED
[ 861.570169] mtp_open
[ 861.743471] fusb302 4-0022: connection has disconnected
[ 861.763602] cdn-dp fec00000.dp: [drm:cdn_dp_pd_event_work] Not connected. Disabling cdn
[ 861.789500] dwc3 fe800000.dwc3: dwc3 gadget stop timeout
[ 861.789610] rockchip-dwc3 usb@fe800000: USB unconnected
[ 861.789683] android_work: sent uevent USB_STATE=DISCONNECTED
[ 861.790806] configfs-gadget gadget: unbind function 'mtp'/ffffffc0f1d4a000
[ 861.790847] configfs-gadget gadget: unbind function 'Function FS Gadget'/ffffffc0efb73438
[ 861.790900] android_work: did not send uevent (0 0 (null))
[ 861.792585] mtp_release
总结:
修改文件:
20220910 19:12