坚持高质量原创,拒绝内容堆砌,喜欢的话点击上方星标,更新第一时间收到提醒,谢谢关注!
最近在准备BSP系列的内容,在bringup 3399板子的时候踩了不少坑,这篇我想分享一下在Linux下,对应工具的下载编译以及烧录镜像完整流程,我们依旧秉承着超详细流程分享的理念,保证跟着做是现象都是完全可复现的。这个分享的目的主要是想:
为有rk3399开发需求的朋友提供参考
分享我作为芯片原厂BSP工程师在bringup过程中解决问题的思路
结合我多年工作经验,聊聊为什么有的主机厂的开源资料指导性很差?
开始之前先打一个广告,最近公众号没有更新的主要原因是我正在准备BSP驱动的内容,这个系列将会带大家从零开始Bringup一块开发板,从使用官方固件到替换自己的源码固件,使用最新的uboot以及linux内核,学习buildroot等使用,然后针对各个控制器,如I2C、SPI、USB、PCIE、MIPI等等,深入的讲解驱动。
我会结合我多年芯片原厂BSP工程师的经验,站在芯片原厂的角度完整的学习BSP的开发内容,最终可以自己完成一款ARM V8架构的SDK的搭建。
我不仅会给展示完整的Bringup过程,更会详细讲解这些步骤的意义是什么,而不是让大家傻瓜式的跟着操作。BootROM中运行了什么程序?什么是SPL?uboot的功能?我们执行的烧录脚本中又做了哪些工作?等等。
这些内容未来将会在知识星球中以订阅制的方式持续更新,内容实用且价格实惠,加群会有额外优惠,欢迎关注也感谢大家的支持。
rk3399是一块比较成熟开发板,在2020年左右用于许多中高端嵌入式设备中,如机顶盒、智能门锁、医疗器械等。我使用Nanopc-T4作为开发板,主机厂商是友善之臂,官网地址为:https://wiki.friendlyelec.com/wiki/index.php/NanoPC-T4/zh
拿到一块开发板,了解了SoC以及板载硬件后,第一件事就是要学会如何烧录镜像。官方提供了多种烧录和启动的方法,这些我们会放在以后的系列中一一讲解,我们本文重点介绍Linux下的烧录方法。
首先我们先获取一个官方提供的固件,官方提供了多种固件和镜像,可以根据需要自行选择,我选择了一个friendlycore的版本,这是友善之臂基于ubuntu20.04的内核开发的镜像。

下载镜像后内容如下,可以看到是一个比较标准的SDK的镜像包,包括SPL、uboot、rootfs、userdata以及分区表等等。

我们看到官方的镜像包中只有一个exe文件,这是Windows的烧录工具,Windows工具有图形化界面使用相对友好。友善之臂的官方资料中也没有提及Linux工具的使用,看起好像不太推荐Linux的样子。。。

但是我们作为BSP开发者,绝大多数开发环境都会在Linux中,所以使用Linux的烧录工具进行更新镜像可以免去在Windows与Linux间反复切换的麻烦。并且友善之臂的工具包中确实提供了Linux的烧录工具upgrade_tool

但是文档却写的非常的简单,如果照着文档操作你会发现进行十分困难。既没有表明这些镜像的来源以及用途,所谓的问题处理,甚至都没说遇到什么问题需要进行处理。。。

使用工具自带的参数提示试了一下,在板子进入到maskroom模式使用 upgrade_tool LD确实能显示出设备:


这里顺便介绍一下,NanoPC-T4进入maskroom的方法是板子下电之后按住boot键超过5秒后给板子上电即可,上下电可以通过插拔电源线,按power键或者像我是用了一个远程插座操作比较方便。
之后按照文档操作使用upgrade_tool工具会遇到各类问题

但是报错信息很模糊,按照提示查看保存的upgrade_tool的log的报错只看到usb初始化失败,具体原因报错写的不是很清楚。

由于我有一些芯片的bringup经验,并且对USB的开发比较了解,所以其实到这里我已经大概猜到是什么原因了,其实原因并不复杂,这个我们在放在后面讲解。我们就假设没有经验继续去摸索。
那既然主机厂release的工具使用方法不明确,并且也没有源码,那我们就去芯片原厂也就是RK的官方看看是否有对应的工具。
rkdeveloptool是Rockchip提供的一个与Rockusb设备进行通信的工具,通过该工具我们可以将镜像文件下载到开发板的eMMC。它被认为是upgrade_tool的一个开源版本,只有很少区别。
官网介绍:https://opensource.rock-chips.com/wiki_Rkdeveloptool
要使用rkdeveloptool进行升级,首先要知道rkdeveloptool是基于什么情况下才会起作用的,是在SoC进入MASKROM模式后而且跟主机通过USB连接,因为这个时候主板的DDR并没有初始化,而升级过程是需要很大的内存空间的,所以升级之前第一步要做的就是执行rkdeveloptool db rkxx_loader_vx.xx.bin,这个固件中包括了DDR和USB的硬件初始化和驱动,也是这个阶段必须需要依赖的硬件。
如果不执行db命令的话其他的命令则无法执行,因为没有做内存初始化工作。
编译工具需要安装以下的依赖:
sudo apt-get install libudev-dev libusb-1.0-0-dev dh-autoreconfsudo apt-get install pkg-config libusb-1.0sudo apt-get install autoconf开源工具
git clone https://github.com/rockchip-linux/rkdeveloptool.git --depth 1在rkdeveloptool中使用autoreconf -i或者使用目录中的autogen.sh,生成configure

执行conigure,使用最新的源码配置可能会遇到下面的问题:

根本原因是工具版本和源码不兼容导致的,可以对configure.ac进行如下修改:

修改的部分贴在这里供大家复制:
cc@cc-LEGION-REN9000K-34IRZ:~/corechip_rk3399_sdk/rkdeveloptool$ git diffdiff --git a/configure.ac b/configure.acindex c21355d..63710d2 100644--- a/configure.ac+++ b/configure.ac@@ -1,11 +1,23 @@ dnl Copyright (C) 2017 Trevor Woerner <twoerner@gmail.com>+dnl Override _AC_INIT_DIRCHECK to handle cases where ls -di returns non-zero exit code+dnl but still produces valid output (e.g., when stdout is redirected)+m4_defun([_AC_INIT_DIRCHECK],+[ac_pwd=`pwd` && test -n "$ac_pwd" &&+ac_ls_di=`ls -di . 2>/dev/null`; test $? -eq 0 || test -n "$ac_ls_di" || ac_ls_di=`stat -c %i . 2>/dev/null` || ac_ls_di= &&+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di . 2>/dev/null`; test $? -eq 0 || test -n "$ac_pwd_ls_di" || ac_pwd_ls_di=`stat -c %i . 2>/dev/null` || ac_pwd_ls_di= &&+test -n "$ac_ls_di" && test -n "$ac_pwd_ls_di" ||+ AC_MSG_ERROR([working directory cannot be determined])+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||+ AC_MSG_ERROR([pwd does not report name of working directory])+])+ AC_INIT([Rockchip rkdeveloptool], 1.32, [Eddie Cai <eddie.cai.linux@gmail.com>], rkdeveloptool) AC_PREREQ([2.68]) AC_CONFIG_SRCDIR(main.cpp) AC_CONFIG_AUX_DIR(cfg) AM_INIT_AUTOMAKE([foreign no-dist-gzip dist-bzip2 1.9])-AM_CONFIG_HEADER(cfg/config.h)+AC_CONFIG_HEADERS([cfg/config.h]) SUBDIRS=""修改完后,删除刚才生成的configure,再执行一遍autoreconf -i或autogen.sh重新生成configure,再次执行即可完成配置:

配置完成后进行编译即可得到rkdeveloptool
cc@cc-LEGION-REN9000K-34IRZ:~/corechip_rk3399_sdk/rkdeveloptool$ makecc@cc-LEGION-REN9000K-34IRZ:~/corechip_rk3399_sdk/rkdeveloptool$ sudo make install
使用官方的rkdeveloptool并参考手册没有再遇到问题了,官方提到的rkxx_loader_vx.xx.bin我没有单独去下载,友善之臂的开发包里提供了MiniLoaderall.bin,其实是一样的,都是我说的DDR和USB的固件。
Maskroom的原理就是人为的把Flash(Nor Flash、Nand Flash和eMMC等存储设备)的CLK时钟引脚与地线短接。使得CPU读取Flash失败,CPU转而初始化USB端口,进入Maskrom升级模式。

libusb_open() 打开设备失败,典型:权限不足 / 设备被占用,我们刚才的err = -3就是这种,刚才遇到的问题最简单的方法就是使用sudo执行命令就可以解决这个问题。

如果是 claim_interface failed,多半是被驱动/进程占用:先关闭其它烧录工具/adb之类,再拔插设备重试。
镜像烧录完成后即可正常进入系统,接上 HDMI也有图形化界面显示,串口日志如下:


我还基于这个工具写了一个脚本进行一键烧录,方便未来开发,这个我之后也会放到知识星球中。
我们其实也完全可以在uboot中支持USB驱动和fastboot功能,自己开发一个烧录工具。

最后想和大家聊聊为什么有的主机厂商的发布sdk和公开文档指导性非常差,可能有的朋友会想是不是因为自己不够专业导致的。但是大家其实也可以看到我刚才演示这仅仅一个工具的使用的过程,我已经有着多年芯片厂工作经验以及USB的开发经验,文档描述不清的时候,也还是会踩坑。
我做这个BSP系列其实也是因为有很多朋友私信和留言,想要一个能实战的bringup教程,想必大家也有不少人已经吃过不少主机厂的苦头。但是为什么会这样呢?按照我的经验我认为大概有以下几个原因:
硬件和系统开发能力从芯片厂到主机厂再到设备厂商是逐级下降的,所以也会导致代码和文档质量下降
程序员间广泛流传的一句话:程序员最讨厌写文档,也最讨厌别人不写文档
很多你认为的光鲜亮丽的大厂里面,可能某个模块和功能只是一两个应届生开发出来的。亦或是一个经验丰富的工程师身兼多个模块的开发和维测工作。多个模块都在排期集成发版测试的节点,如果这时候你的领导和你说,我们还得开源个工具并且写好文档,你会怎么做呢?你觉得领导是否会照着你的文档操作一遍,来检查你写的开源文档指导性强不强吗?
哈哈,偶尔喜欢聊聊职场也挺有意思的,那么再说回来我们平时学习工作中遇到类似文档不清楚,遇到问题无从下手的情况怎么办?
首先就是尽量去找芯片厂商的资料,芯片原厂提供的资料和代码是相对权威的
工具和软件尽遇到问题尽量找到源码,尤其现在AI越来越发达的情况下,只要有源码即使是你不熟悉的方向,也可以依靠AI来帮你分析问题。如果没有源码又没有清晰的文档指导的情况下,遇到问题真的很难解决
Bringup的难点就在于对于硬件、软件和工具的不熟悉,出现问题不知道是哪一方面的问题,所以就要把问题分类解决。例如我们Linux烧录遇到问题,我们可以先从Windows上尝试,这样首先可以来定位是USB硬件问题?线材问题?工具问题?缩小范围才方便解决问题,任何情况下都要先找到一个稳定能使用的版本,再基于这个版本去进行调试和探索,否则变量太多出现问题是无法定位的。
- END -
如果有什么问题,欢迎添加我的微信讨论。我建了一个小群,后面会陆续加一些我身边认识的行业大佬,都是来自一线大厂P7以上的工程师,任何有关行业、工作、跳槽的问题都可以在群里讨论~~
现在加群等开通知识星球后还会有额外优惠哦~
