news 2026/10/15 23:55:11

RK3229开发指南实战:从SDK编译到设备树调试的完整闭环与避坑记录

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RK3229开发指南实战:从SDK编译到设备树调试的完整闭环与避坑记录

简介:瑞芯微RK3229软件开发指南(V1.03,2017年11月)是面向软件开发工程师与技术工程师的官方技术文档,重点讲解Linux 3.10内核下Android 6.0.1和7.1.2双系统的开发、编译、烧写与调试流程,并内置DDR、NAND、eMMC、WiFi/BT等硬件兼容性支持列表,帮助开发者在选型阶段规避兼容性风险。资源包仅含1个PDF文件,压缩包约1.61MB,文档目录清晰,并附有工具索引,方便快速定位所需章节。目前已有623人学习,适用于嵌入式产品研发、Android系统定制及量产调试等场景。文档详细说明了系统分区大小配置、ODEX预编译、禁用SELinux、Box产测工具、Jack-server配置、USB默认开启ADB调试、Android 7.1开机视频功能、低内存优化方案,以及DRM Widevine level 1配置等关键开发者特性;同时覆盖工具版本更新、开机logo限制、序列号与Mac烧写工具的更新说明,整体贯穿从硬件适配、软件构建到生产测试的完整流程,是RK3229项目开发中极具参考价值的官方指南。

1. 拿到《Rockchip RK3229 软件开发指南 V1.03-201711241》,先别急着敲命令

第一次拿到《Rockchip RK3229 软件开发指南 V1.03-201711241》这类文档时,如果只把它当成一份照着敲命令的说明书,后面八成要返工。这份指南真正的价值在于三件事:把 RK3229 这颗四核 A7 平台的存储分区讲清楚,把从编译到烧录的开发闭环串起来,再告诉你每个外设节点在设备树里该怎么写。版本号里的 201711241 这个日期,能帮你判断 SDK 基线和交叉编译工具链的适用范围,而不是在新主机上盲目编译。

需要它的读者也比较明确:做 OTT 盒子、投影仪、广告机,或者想拿嵌入式 Linux 平台练手入门的开发者。你关心的不是 RK3229 能不能跑,而是串口点亮之前少踩几个坑、改完配置之后知道去哪验证。这篇文章就把这套流程拆开讲透。

2. 开工前先读版本号与存储布局:把 RK3229 的边界画出来

拿到文档的第一件事不是装环境,而是先确认它对应的 SDK 基线。V1.03-201711241 这个编号里的日期,说明这份指南对应的 SDK 快照在 2017 年底附近。这意味着源码里的内核版本、U-Boot 版本、编译工具链版本都有一个固定的时间坐标。你手头拿到的 SDK 分支如果和这个日期差得太远,后面所有编译报错都难定位,因为你根本不知道是代码问题还是版本错配。

这一章先把三个边界画清楚:版本基线怎么确认、编译主机怎么准备、存储分区表怎么读。这三件事都做完,你才算是真正开工。

2.1 从 V1.03-201711241 看 SDK 基线与工具链适用范围

RK 系列的软件开发指南一般会把 SDK 的获取方式、目录结构、构建命令写清楚,但版本号里的时间信息才是最有用的。201711241 基本可以理解为 2017 年 11 月 24 日发布的版本,对应的 SDK 里内核大概率是 4.4 这条长期维护分支。这套老代码对编译主机的默认要求是有特定范围的,拿现在的新系统直接编,往往会卡在环境检查阶段。

我拿到 SDK 源码后的习惯是先确认三件事,再决定要不要动代码。下面这几个命令就是干这个的:

# 进到 SDK 根目录后先确认三件事 head -n 5 kernel/Makefile # Linux 主版本号,比如 4.4 cat kernel/.config | grep CONFIG_LOCALVERSION # 内核本地版本后缀 gcc --version | head -n 1 # 主机编译器的版本

这三条命令的逻辑很简单:先看内核源码的 Makefile 确认大版本,再看 .config 里有没有厂商加的 localversion 后缀,最后看宿主机 gcc 版本。为什么要关心宿主机 gcc?因为老 SDK 的构建脚本里如果有版本检查逻辑,新 gcc 会直接让编译在早期阶段失败,典型报错包括无法识别的命令行选项、隐式函数声明这类看起来莫名其妙的提示。

交叉编译工具链同理。RK 的老 SDK 常见做法是在 SDK 里放一套预编译的交叉工具链,基于 gcc 4.9 或 5.x。你不需要重新造轮子,直接用 SDK 自带的工具链就好。如果文档里写了工具链路径,优先用那个路径下的编译器,而不是系统自带的 arm-linux-gnueabihf-gcc,版本不一致会导致内核编译产物和 rootfs 的 ABI 对不上。

2.2 编译主机与依赖:在 Ubuntu 上把环境一次备好

RK 老 SDK 的编译环境推荐用 Ubuntu 16.04 或 18.04,原因很简单:这个年代的 SDK 依赖 python2、libncurses5 这些老库,新系统默认不再提供。如果你只有新版本 Ubuntu,也要尽量让编译跑在兼容环境里,比如用 Docker 跑一个老系统容器。不要直接在 macOS 上编整个 SDK,文件系统大小写敏感、符号链接处理这些问题会在意想不到的地方卡你半天。

依赖安装看起来繁琐,但一次性做对能省掉后面大量的排错时间。这里列一组常见的最小依赖:

sudo apt-get install -y git ssh make gcc libssl-dev bc \ libncurses5-dev lib32z1 lib32stdc++6 python2.7 # 新系统如果没有 python2,用 update-alternatives 设置默认 sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1

每组依赖都有它的用处:make 和 gcc 是构建基础,libssl-dev 是给内核和 U-Boot 的证书/签名功能用的,bc 是内核 Kconfig 脚本的依赖,libncurses5-dev 是 menuconfig 界面需要的,lib32z1 和 lib32stdc++6 则是给 64 位主机编译 32 位工具链用的。python2 是老 SDK 里很多脚本的运行环境,没有它,repo 同步或部分打包脚本会直接报 No module named 错误。

环境就绪后,SDK 源码的同步通常走 repo 工具。repo 是管理多 git 仓库组合的常用工具,RK 的 SDK 就把 kernel、uboot、buildroot 等拆成多个仓库:

mkdir -p ~/rk3229 && cd ~/rk3229 # <internal-sdk-server> 是你们内部或厂商提供的 SDK 服务端地址 repo init -u <internal-sdk-server> -b <sdk-branch-name> repo sync -j4 # 首次同步别用太高并行度,网络中断容易留下半成品仓库

repo sync 的 -j4 是并行任务数。首次同步时我一般不会开 -j8 以上,因为仓库太多、连接不稳定时,高并行度反而容易让某些子仓库拉取中断,最后你还要重新 sync 补齐。等首次同步完整跑过后,后续增量同步再适当调高并行度不迟。

提示:SDK 源码加编译产物建议预留 30GB 以上磁盘空间。老 SDK 的资源占用不算夸张,但 rootfs 构建目录和镜像文件叠在一起,空间紧张时会莫名编译失败。

2.3 先读懂 parameter 分区表:改错一个 offset 整盘报废

RK 平台的烧录和启动都依赖 parameter 文件,它描述了存储介质上的分区布局。这个文件同时被烧录工具和 U-Boot 读取,所以哪怕只改错一个分区起始位置,轻则某个分区数据错乱,重则设备无法启动,只能重新走烧录流程。拿到开发板的第一件事,我建议先把原始 parameter 备份一份,这是你的后悔药。

典型的 RK3229 分区表字段如下,单位通常是 block,一个 block 对应一个扇区的大小,实际换算以 SDK 里的说明为准:

分区名常见大小作用
uboot0x00002000U-Boot 镜像与环境变量区域
misc0x00002000启动模式标记,比如 recovery/正常启动切换
resource0x00010000存放 dtb 与开机 logo 资源
kernel0x00008000内核镜像
boot0x00010000Android 风格的 boot.img(含 ramdisk),Linux SDK 也会沿用
recovery0x00010000恢复系统
rootfs0x00080000根文件系统
usrdata0x00080000用户数据区

这个表格只是常见示例,你手上的板子可能不一样。怎么确认当前真实分区?进到 U-Boot 命令行里直接看:

# 在 U-Boot 命令行下执行 mmc part printenv bootcmd

mmc part 会打印 eMMC 的分区表,printenv bootcmd 告诉你启动时执行的命令。很多启动问题的第一步排查都从这里开始,而不是直接怀疑内核。之前见过有人把 uboot 分区从 0x2000 改到 0x3000,结果环境变量保存区域被挤到下一个分区的头部,系统能起来但每次改环境变量都会把 resource 分区头部覆盖,最后 logo 和 dtb 全坏。这就是没理解 partition offset 的后果。

3. 按指南跑通第一次全量编译与烧录:三条命令和一个易错点

环境就绪、分区表心里有数之后,就可以走第一次编译了。RK 的 Linux SDK 习惯用 build.sh 作为统一构建入口,文档里的流程大体一致:选择板级配置,逐步编 uboot、kernel、rootfs,最后打包固件。第一次编译的重点不是追求速度,而是确认整条链路通。

这一章我会把全量编译、单独编译、烧录三步拆开,每一步都给出命令和参数含义。你照着跑完一遍,RK3229 的开发闭环就立住了。

3.1 全量构建:build.sh 的常用工作流

全量编译的入口是 build.sh,它是一层封装,把 U-Boot、内核、rootfs 的构建命令统一起来。第一次跑建议按顺序走,不要跳步:

cd ~/rk3229 ./build.sh lunch # 选择板级 config,列表里选 rk3229 对应项 ./build.sh uboot # 编译 U-Boot,产物 uboot.img ./build.sh kernel # 编译内核与 dtb,产物 kernel.img 和 dtb 文件 ./build.sh rootfs # 生成根文件系统镜像,耗时最长 ./build.sh firmware # 汇总各分区镜像到 rockdev/ 目录

lunch 这一步是交互式的,它会列出 SDK 预置的板级配置。你要选带 rk3229 字符的那一项,选错配置会导致内核 defconfig 不对,后面外设全乱。uboot 编译一般几分钟,kernel 取决于主机性能,rootfs 构建最慢,因为它会从头构建整套用户态软件包。

build.sh firmware 是最后一步,它会把前面生成的各分区镜像按照 parameter 文件汇总到 rockdev/Image-rk3229/ 目录下。完成后你会看到 boot.img、recovery.img、rootfs.img、uboot.img、resource.img 这一堆文件。这里要注意:firmware 打包依赖前面的编译产物存在,如果你只编了 kernel 就执行 firmware,它可能拿旧的 uboot.img 混进去,最后烧出来的系统里各组件版本不一致。

3.2 单独编一个分区镜像:改完一处不必等全量

日常迭代开发不需要每次都全量编译,RK SDK 支持单独重编某个组件。这个习惯能显著节省时间,但前提是你知道每个命令的产物是什么,以及产物最终去哪。

# 单独重编内核 ./build.sh kernel # 把内核 Image 和 dtb 打包进 boot.img 与 resource.img ./mkimage.sh # 重编 U-Boot 时只需要 ./build.sh uboot

mkimage.sh 这一步特别关键。RK 平台的内核启动依赖 boot.img 里的内核镜像和 resource.img 里的 dtb,你改了设备树后只重编 kernel 是不够的,必须执行 mkimage.sh 把 dtb 打包进 resource.img,否则烧录后设备树还是旧的。这是新手最容易漏的一步,也是后面第 5 章会展开的坑。

单独编译产物路径也需要熟悉:U-Boot 的产物在 uboot/ 目录下,内核 Image 在 kernel/arch/arm/boot/ 下,dtb 在 kernel/arch/arm/boot/dts/ 下。打包脚本会从这些固定路径取文件,所以不要手动改名或搬动中间产物,否则 mkimage.sh 会打包到陈旧文件。

3.3 烧录:loader 模式、分区与串口波特率

编译通过只是第一步,把镜像烧进板子才算闭环。RK 平台有两种常见烧录状态:loader 模式和 maskrom 模式。loader 模式是正常开发烧录用的,进入方式一般是上电时按住特定按键,或者在 U-Boot 命令行里执行对应的命令;maskrom 模式用于救砖,和本文主题关系不大,这里只提一句。

Linux 下烧录常走 upgrade_tool 这套命令行工具,Windows 下对应的是图形化工具。下面是一条完整的烧录流程:

# 列出当前连接的设备 sudo upgrade_tool LD # 逐个烧录分区,分区名必须与 parameter 一致 sudo upgrade_tool DI -p parameter.txt sudo upgrade_tool DI -uboot uboot.img sudo upgrade_tool DI -resource resource.img sudo upgrade_tool DI -kernel boot.img sudo upgrade_tool DI -rootfs rootfs.img # 烧完复位设备 sudo upgrade_tool RD

LD 是 List Device,先确认主机识别到了板子。DI 是 Download Image,-p 对应 parameter 分区,-uboot 对应 uboot 分区,以此类推。RD 是 Reset Device。这里最大的易错点在于分区名要和 parameter 文件里的完全一致,如果你 parameter 里叫 system 而烧录命令写的是 rootfs,工具会报找不到分区,或者更糟,写进一个不存在的地址导致启动失败。

注意:新板子第一次烧录,我建议把所有分区完整烧一遍,不要只烧你改的那个分区。因为出厂板子上的参数可能有细微差异,全量烧一遍能确保整个系统的基线一致。

串口波特率在这里也要提一句:RK3229 的 U-Boot 和内核默认 console 串口波特率是 1500000,不是常见的 115200。如果你用 115200 去连,看到的是乱码,还会误以为板子没启动。

4. 文档里真正值钱的章节:RK3229 的设备树、显示与视频解码

编译和烧录跑通后,真正的开发工作才刚开始。软件开发指南里最值得细读的,不是前面的环境搭建,而是设备树和外设适配部分。RK3229 是一颗多媒体定位的芯片,显示、视频解码、常用外设这几块配置直接决定产品体验。

这一章选三个高频场景展开:HDMI 显示链路、MPP 视频解码、常用外设的 DTS 写法。每部分都会给出配置示例和验证方法。

4.1 从 hdmi 节点读懂 RK3229 的显示链路

RK3229 的显示输出主要是 HDMI,部分方案会带 CVBS。HDMI 在设备树里涉及两个层面:一个是 HDMI 控制器本身的节点,另一个是显示子系统的节点。常见配置如下:

&hdmi { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&hdmi_irq &hdmi_hpd>; rockchip,hdmi_audio = <0>; }; &display_subsystem { status = "okay"; };

pinctrl-0 里声明了 hdmi_irq 和 hdmi_hpd 两组引脚复用配置。hdmi_hpd 是热插拔检测引脚,如果这里配错 GPIO,显示器接上后系统感知不到连接,表现得就像黑屏。所以拿到一个不亮的 HDMI 问题,我一般先查这组 pinctrl,再查上层状态。

系统起来后,验证 HDMI 是否真的识别到了显示器:

cat /sys/class/drm/card0-HDMI-A-1/status cat /sys/class/drm/card0-HDMI-A-1/modes dmesg | grep -i hdmi

status 输出 connected 才说明 HPD 正常,modes 会列出显示器支持的分辨率。如果 status 一直是 disconnected,大概率是引脚或硬件问题;如果是 connected 但没画面,再查分辨率是否超出 HDMI 输出能力。RK3229 的 HDMI 输出标称支持 4K@30,但视频解码能力最高到 1080P,这个差异要心里有数。

4.2 MPP 视频解码:硬解不是默认打开的

RK 平台的视频硬解统一走 MPP(Media Process Platform),对应库是 libmpp。RK3229 支持 H.264/H.265 的 1080P 硬解,但注意:硬解能力不是系统默认打开的,你的应用层代码必须显式调用 MPP 接口。

MPP 的基本调用流程很固定,代码结构上大概是:

#include "rockchip/mpp_buffer.h" #include "rockchip/mpp_dec.h" // 1. 创建解码器实例 MppDec dec = NULL; mpp_dec_init(&dec, MPP_VIDEO_CodingHEVC); // 2. 配置解码参数:宽高、格式、帧率 MppDecCfg cfg; mpp_dec_ctrl(dec, MPP_DEC_SET_CFG, &cfg); // 3. 喂入编码数据包 mpp_dec_send_packet(dec, packet); // 4. 取回解码帧 MppFrame frame; mpp_dec_get_frame(dec, &frame);

这里 MPP_VIDEO_CodingHEVC 是 H.265 的解码类型,H.264 对应 MPP_VIDEO_CodingH264。mpp_dec_init 负责分配解码器资源,mpp_dec_send_packet 是输入侧,mpp_dec_get_frame 是输出侧。MPP 的接口在不同 SDK 版本里有细节差异,所以写代码前先翻 SDK 里带的头文件,以源码声明为准。

硬解最常见的坑是 buffer 管理。MPP 为了性能会做 buffer 复用,如果你的业务逻辑把解码帧直接跨线程使用,要留意 buffer 生命周期。开发指南里对编解码格式支持范围的描述通常比较保守,实际是否支持某种编码 profile,要以 SDK 里 MPP 的 media 类型列表为准。

4.3 常用外设的 DTS 写法:GPIO、I2C、PWM

RK3229 的外设配置都在设备树里完成,最常见的是 GPIO、I2C、PWM 这三种。下面给一个组合示例,包含 PWM 和 I2C 总线挂接外设的写法:

&pwm0 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pwm0_pin>; }; &i2c1 { status = "okay"; clock-frequency = <400000>; tmp102: tmp102@48 { compatible = "ti,tmp102"; reg = <0x48>; }; };

pwm0 节点里 pinctrl-0 声明了 PWM 输出引脚;i2c1 节点里 clock-frequency 设为 400000,也就是 400kHz 快速模式。你在自己的板子上要把挂接器件的 reg 地址改成实际地址,0x48 只是示例。

验证这些配置是否生效的常规手段:

cat /sys/kernel/debug/gpio # 查看 GPIO 申请状态 cat /sys/kernel/debug/pwm # 查看 PWM 是否 enable i2cdetect -y 1 # 扫描 i2c1 总线上的设备地址

如果在 i2cdetect 里看不到设备地址,先看总线上有没有上拉电阻,再看设备地址是否冲突。如果 GPIO 怎么拉都无效,优先检查这个引脚是不是被其他节点复用占用了,比如 pinctrl 冲突,这是嵌入式开发里非常常见的静默故障。

5. 避坑记录:RK3229 五个典型的翻车场景与排查

这一章记录五个在 RK3229 开发中高频出现的翻车场景。每条都按现象、原因、解决三个部分展开,只讲我见过的真实情况和排查路径,不列理论清单。做这个平台时,这些坑你早晚会碰到。

5.1 串口完全无日志

现象:板子电源灯亮,串口终端一片空白,按重启键也没有任何输出。

原因:最常见的是串口波特率配错。RK3229 的 console 串口波特率是 1500000,很多人按习惯设成 115200,收到的就是乱码或者完全空白。第二个常见原因是 TX/RX 接反,第三个是 UART2 的引脚被复用成其他功能。

解决:先把串口参数改成 1500000 8N1 再试。如果还是没输出,把串口线的 TX 和 RX 短接做一次自发自收测试,能收到自己发的内容就说明线材没问题。最后检查板级 DTS 里 uart2 节点的 pinctrl 是否有其他外设占用了对应引脚。

5.2 改了 DTS 却不生效

现象:在设备树里加了一个 i2c1 节点,烧录后系统起来,/sys 下找不到对应的 i2c 设备。

原因:RK3229 的 dtb 文件打包在 resource 分区里,不是跟着 kernel 分区走。很多新手只重编了 kernel.img 就烧录,dtb 根本没更新。还有一重原因是 mkimage.sh 打包时取的是编译目录里旧的 dtb 文件。

解决:改 dts 后必须重新执行 mkimage.sh,然后同时烧 kernel 和 resource 两个分区。烧完以后用设备树加载的节点验证:

ls /sys/firmware/devicetree/base/i2c@* cat /proc/device-tree/i2c@*/status

如果节点下没有你新增的子节点,说明设备树没加载进去,回去检查 resource 分区是否烧对。

5.3 HDMI 黑屏但系统在跑

现象:串口日志显示系统正常启动,进程都在跑,但 HDMI 接显示器没画面。

原因:HPD 引脚配置错误导致连接状态检测失败,或者 EDID 读取失败导致没有任何输出模式可用。还有一种容易被忽略的情况是 HDMI 线太长或质量差,导致时钟信号不稳,系统偶尔能识别偶尔黑屏。

解决:先看连接状态和模式列表。如果 status 是 disconnected,检查 hdmi 节点的 pinctrl-0 里的 hdmi_hpd 是否与实际硬件连接一致。换一台显示器和一根短 HDMI 线也是必要的排除步骤,不要一上来就怀疑 SoC 配置,很多玄学问题最后都出在线材上。

5.4 烧录成功但反复重启

现象:烧录过程没报错,但上电后 U-Boot 起来,内核跑一会儿又回到 U-Boot,循环往复。

原因:最常见的是 parameter 分区表和镜像实际大小不匹配。比如 parameter 里 kernel 分区大小是 0x8000,但实际 kernel.img 的大小超出了这个范围,导致 rootfs 起始位置被覆盖,内核挂载根文件系统时读到损坏数据。

解决:用 mmc part 在 U-Boot 下核对真实分区表,再对比 parameter 文件里的声明。如果确实超了,重新分区并全量烧录。注意这里的全量烧录一定要先烧 parameter 再烧各分区镜像,顺序颠倒可能让新分区表覆盖掉还没烧完的数据。

5.5 编译报错行号与文档对不上

现象:按指南里的代码片段手动修改后编译,报错行号和文档里的示意图对不上,有时还出现中文注释乱码。

原因:SDK 的实际代码分支和文档版本不一致,V1.03-201711241 对应的可能是某个内部分支,而你拿到的分支已经合入了其他改动。另外老 SDK 有些源码是 GBK 注释,在 UTF-8 环境下编译会出现乱码导致的解析错误。

解决:先确认 SDK 分支和文档日期是否匹配。代码合入时不要整段复制文档内容,手动按上下文合入关键改动。对于乱码,用 file 命令检查源文件编码,统一转成 UTF-8 无 BOM 后再编译。

6. 用一组验证命令把 RK3229 的启动流程从黑匣子变成可对比的数据

开发进行到中后期,你面对的问题不再是怎么把系统跑起来,而是系统跑起来后怎么确认当前状态是真的符合预期。RK3229 这类平台的很多现象看起来像玄学,但如果你有一套固定的验证流程,绝大多数问题都能定位到具体环节。

6.1 先建立串口日志基线

我拿到新板子后的第一个动作,永远是抓一份完整的启动日志存档,从 U-Boot 第一行输出到内核启动完成。这份日志是后面所有排查的参照物。具体操作是在串口工具之外再开一个终端用 script 记录带时间戳的日志:

# 终端一:连接串口 minicom -D /dev/ttyUSB0 -b 1500000 # 终端二:把所有串口输出带时间戳存盘 script /tmp/rk3229-boot-$(date +%Y%m%d).log

串口连接用 minicom,-D 指定设备节点,-b 指定波特率,RK3229 固定用 1500000。script 命令记录的是整个终端的输入输出,日志文件会以当前日期命名。这样做的价值在于:系统出现问题后,你能拿当前日志和基线日志做 diff,哪里变了心里有数。

6.2 验证配置是否真生效的检查顺序

改配置后不能只凭一句“我感觉应该生效了”就继续往下走。我常用四个检查入口,按顺序排查:

检查项入口预期结果
内核 cmdline/proc/cmdlineconsole=ttyS2,1500000 且包含你的附加参数
设备树节点/sys/firmware/devicetree/base/你新增的 i2c/pwm 节点存在且 status 为 okay
时钟频率/sys/kernel/debug/clk/clk_summaryDDR、GPU、VPU 频率符合文档标称值
加载日志dmesg对应的驱动 probe 成功,无 error/warning

检查顺序有讲究:先看 cmdline 确认内核启动参数有没有进去,再看设备树节点确认硬件描述对不对,然后看时钟树确认实际频率,最后看 dmesg 确认驱动行为。这四层都对了,改动才算真正生效。如果设备树节点能看到,但驱动 probe 失败,问题就在驱动和引脚配置,而不是设备树语法。

6.3 判断这份指南值不值得继续深挖

RK3229 这个平台值不值得投入,我的判断标准很简单:按官方默认配置能不能完整跑通一遍。如果 SDK 自带配置能编译、烧录、启动、显示一条龙走通,说明这个方案是成熟的,后续你能把精力放在业务逻辑上;如果默认配置本身就起不来,那后续的坑会比代码量更消耗时间。

我现在的习惯是拿到任何新平台,第一件事永远是串口、分区表、烧录三件事跑通,存档基线日志,然后才开始写业务代码。这个习惯帮我在 RK3229 上排掉过很多看起来无解的启动问题,也让我有底气说:这个平台的绝大多数玄学,其实都是验证手段不够。希望这篇笔记能帮你在踩坑之前先看到坑在哪。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 23:52:44

JDK 1.8.0_281 升级实战:从选包到回退的完整指南

简介&#xff1a;JDK1.8.0_281 是 Java 8 系列中稳定性较高的一个长期支持版本&#xff0c;面向需要在本地搭建 Java 开发或运行环境的开发者、运维人员及计算机专业学生&#xff0c;可解决旧项目依赖特定 8u 版本、编译与调试环境不统一等问题。压缩包为 gz 格式&#xff0c;解…

作者头像 李华
网站建设 2026/10/15 23:52:20

CSAPP Datalab位操作实验:13个函数实现与避坑指南

简介&#xff1a;CSAPP Datalab 实验报告是一份面向《深入理解计算机系统》课程学习者与自学者的完整解题笔记&#xff0c;针对 Datalab 中的每个必做函数给出实现思路、位级推导和边界条件判断&#xff0c;重点覆盖位操作、补码表示、逻辑判断、条件运算、浮点定标与类型转换等…

作者头像 李华
网站建设 2026/10/15 23:50:01

MyBatis两大痛点:XML特殊符号转义与批量写入性能优化

做MyBatis开发这几年&#xff0c;最常见的报错其实不在复杂SQL的业务逻辑里&#xff0c;而在一个不起眼的细节&#xff1a;XML里写了个小于号&#xff0c;整个Mapper就编译不通过&#xff1b;最拖慢系统性能的也往往不是慢查询&#xff0c;而是一层for循环里反复执行单条insert…

作者头像 李华
网站建设 2026/10/15 23:47:03

C语言OJ字符统计题三次WA复盘:输入输出边界与fgets陷阱全解析

很多练C语言的同学都绕不过某高校SSE在线练习平台这道坎&#xff0c;尤其是C语言部分的编程练习38&#xff0c;江湖人称“看起来五分钟能写完&#xff0c;提交三次不一定过”。题目本身一句话&#xff1a;输入一行字符&#xff0c;分别统计英文字母、数字、空格和其他字符的个数…

作者头像 李华
网站建设 2026/10/15 23:47:03

SpringBoot+Vue产业园区智慧公寓管理系统架构与实践解析

搞产业园区智慧公寓管理系统这套源码的人&#xff0c;十个里有八个是冲着SpringBootVue这个组合来的&#xff0c;但真正把项目跑起来之后&#xff0c;能把它当成“能用的产品”去改的&#xff0c;可能连一半都没有。这倒不是代码多难写&#xff0c;而是这类系统跟普通出租屋管理…

作者头像 李华
网站建设 2026/10/15 23:47:02

PyTorch深度学习实战:从动态图原理到生产部署的避坑指南

1. 为什么“pytorch”这个标题值得单独拎出来聊如果你在技术社区里闲逛&#xff0c;看到有人只甩出一个词——“pytorch”&#xff0c;然后底下跟了一堆讨论&#xff0c;千万别觉得这是水帖。这个词背后藏着的&#xff0c;是一整套从研究原型到生产部署的完整技术栈&#xff0c…

作者头像 李华