news 2026/4/17 10:01:17

保姆级教程:手把手教你修改RK3588的U-Boot,提前点亮LED或控制风扇(GPIO配置篇)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
保姆级教程:手把手教你修改RK3588的U-Boot,提前点亮LED或控制风扇(GPIO配置篇)

保姆级教程:手把手教你修改RK3588的U-Boot,提前点亮LED或控制风扇(GPIO配置篇)

在嵌入式开发中,能够掌握U-Boot阶段的硬件控制能力,意味着你可以在系统启动的最早期就对硬件进行干预。想象一下,当你的RK3588开发板刚上电,U-Boot还在加载时,就能通过LED灯的状态来指示启动进度,或者提前启动散热风扇为即将运行的高负载任务做好准备——这种"掌控全局"的感觉,正是嵌入式开发的魅力所在。

本文将带你从零开始,完成在RK3588开发板上通过U-Boot控制GPIO的完整流程。不同于简单的代码片段展示,我们会用详细的步骤截图、命令行操作和实际效果演示,确保即使是没有Rockchip平台开发经验的新手也能轻松跟上。我们将重点解决三个核心问题:如何理解RK3588特殊的GPIO编号规则、如何定位并修改U-Boot的关键代码、以及如何验证修改是否生效。

1. 理解RK3588的GPIO编号体系

在开始修改代码前,我们必须先搞清楚RK3588的GPIO编号规则。与常见的简单数字编号不同,Rockchip芯片采用了一种分层编号系统,这让很多刚接触该平台的开发者感到困惑。

RK3588的GPIO控制器分为5个bank(GPIO0-GPIO4),每个bank包含4个group(A-D),每个group又有8个pin(0-7)。这种结构可以用GPIO<bank>_<group><pin>的形式表示,例如GPIO4_D5表示:

  • Bank编号:4(GPIO4)
  • Group编号:3(D对应3,A=0,B=1,C=2,D=3)
  • Pin编号:5(D5中的5)

要将这种表示法转换为U-Boot中使用的绝对编号,需要经过两步计算:

  1. 计算group内的相对编号:number = group * 8 + pin
  2. 计算全局绝对编号:global_number = bank * 32 + number

以GPIO4_D5为例:

number = 3 * 8 + 5 = 29 global_number = 4 * 32 + 29 = 157

为了方便查阅,以下是RK3588常用GPIO的编号对照表:

GPIO名称BankGroupPin绝对编号
GPIO0_A00000
GPIO0_A70077
GPIO0_B301311
GPIO4_D5435157
GPIO4_C6426150

提示:开发板原理图上标注的GPIO名称通常采用GPIO<bank>_<group><pin>格式,务必先确认你要控制的GPIO在原理图上的准确名称。

2. 准备开发环境与源码

在修改U-Boot前,我们需要准备好开发环境和RK3588的Linux SDK源码。以下是详细步骤:

  1. 安装交叉编译工具链

    sudo apt-get install gcc-aarch64-linux-gnu
  2. 获取Linux SDK源码

    git clone https://github.com/rockchip-linux/rkbin.git git clone https://github.com/rockchip-linux/u-boot.git
  3. 配置环境变量

    export CROSS_COMPILE=aarch64-linux-gnu- export ARCH=arm64
  4. 确认开发板配置: 进入u-boot目录,查看RK3588的默认配置文件:

    cd u-boot ls configs/rk3588_*defconfig

    通常会看到类似rk3588_defconfigrk3588_evb_defconfig的文件,这取决于你的具体开发板型号。

3. 定位并修改U-Boot的关键代码

RK3588的GPIO初始化代码位于U-Boot的board.c文件中。按照以下步骤进行修改:

  1. 找到目标文件

    u-boot/arch/arm/mach-rockchip/board.c
  2. 定位rk_board_init函数: 这个函数是U-Boot初始化阶段会调用的一个弱符号函数,正是我们添加GPIO控制代码的理想位置。

  3. 添加GPIO控制代码: 以下是控制GPIO4_D5(绝对编号157)的完整示例:

    __weak int rk_board_init(void) { printf("Initializing custom GPIOs...\n"); // 控制GPIO4_D5(绝对编号157) if (gpio_request(157, "sys_led") == 0) { gpio_direction_output(157, 1); // 设置为输出模式,初始高电平 gpio_set_value(157, 0); // 输出低电平,点亮LED } else { printf("Failed to request GPIO 157\n"); } return 0; }

    代码解析:

    • gpio_request:申请GPIO使用权,防止冲突
    • gpio_direction_output:设置GPIO为输出模式
    • gpio_set_value:设置输出电平(0=低,1=高)
  4. 添加头文件(如果IDE提示未定义): 在文件顶部添加:

    #include <asm/gpio.h> #include <common.h>

4. 编译与烧写U-Boot

修改完成后,需要重新编译U-Boot并烧写到开发板:

  1. 配置编译选项

    make rk3588_defconfig
  2. 启动编译

    make -j$(nproc)

    编译完成后,会在u-boot目录下生成u-boot.bin文件。

  3. 烧写到开发板: 使用Rockchip提供的upgrade_tool工具进行烧写:

    sudo upgrade_tool ul u-boot.bin

    或者通过TF卡启动方式更新:

    sudo dd if=u-boot.bin of=/dev/sdX seek=64

    (将/dev/sdX替换为你的TF卡设备名)

5. 验证GPIO控制效果

烧写完成后,给开发板上电,可以通过以下方式验证GPIO控制是否生效:

  1. 观察LED状态: 如果你控制的是LED连接的GPIO,上电后应该能立即看到LED状态变化。

  2. 使用万用表测量: 将万用表调到电压档,测量GPIO引脚对地电压:

    • 高电平:约3.3V
    • 低电平:约0V
  3. U-Boot命令行验证: 如果开发板支持U-Boot命令行,可以尝试:

    gpio status -a

    这个命令会列出所有GPIO的状态,找到你控制的GPIO编号确认其状态。

6. 进阶技巧与故障排除

在实际项目中,你可能会遇到各种特殊情况。以下是几个常见问题的解决方案:

  1. GPIO无法控制

    • 检查原理图确认GPIO没有被其他功能复用(如I2C、SPI等)
    • 使用gpio_request的返回值判断是否申请成功
    • 确认开发板的硬件版本和GPIO连接方式
  2. 需要控制多个GPIO

    // 控制LED和风扇的示例 #define SYS_LED_GPIO 157 #define FAN_CTRL_GPIO 158 __weak int rk_board_init(void) { // 初始化系统LED if (gpio_request(SYS_LED_GPIO, "sys_led") == 0) { gpio_direction_output(SYS_LED_GPIO, 0); } // 初始化风扇控制 if (gpio_request(FAN_CTRL_GPIO, "fan_ctrl") == 0) { gpio_direction_output(FAN_CTRL_GPIO, 1); // 默认关闭风扇 } return 0; }
  3. 动态控制GPIO: 如果需要根据条件动态控制GPIO,可以在U-Boot命令行中添加自定义命令:

    static int do_led_ctrl(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { if (argc != 2) return CMD_RET_USAGE; int value = simple_strtol(argv[1], NULL, 10); gpio_set_value(SYS_LED_GPIO, value); return CMD_RET_SUCCESS; } U_BOOT_CMD( led, 2, 1, do_led_ctrl, "Control system LED", "<0|1> - Set LED off(0) or on(1)" );

    编译烧写后,在U-Boot命令行中可以输入:

    led 1 # 点亮LED led 0 # 关闭LED

7. 实际应用场景示例

让我们看一个实际项目中非常有用的应用场景:通过LED指示启动阶段。

__weak int rk_board_init(void) { // 初始化阶段LED快速闪烁 for (int i = 0; i < 5; i++) { gpio_request(SYS_LED_GPIO, "sys_led"); gpio_direction_output(SYS_LED_GPIO, 1); gpio_set_value(SYS_LED_GPIO, 0); mdelay(100); gpio_set_value(SYS_LED_GPIO, 1); mdelay(100); gpio_free(SYS_LED_GPIO); } return 0; } __weak int last_stage_init(void) { // 系统即将启动内核时,LED常亮 gpio_request(SYS_LED_GPIO, "sys_led"); gpio_direction_output(SYS_LED_GPIO, 1); gpio_set_value(SYS_LED_GPIO, 0); return 0; }

这段代码实现了:

  1. 在U-Boot早期初始化阶段,LED快速闪烁5次
  2. 在即将启动内核前,LED变为常亮
  3. 这样通过LED的行为就能直观判断系统启动到了哪个阶段

注意:mdelay函数需要包含#include <linux/delay.h>头文件,且在某些U-Boot版本中可能需要使用udelay代替。

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

用SG90舵机+OLED表情包打造会卖萌的STM32机器人(附表情动画代码)

用SG90舵机OLED表情包打造会卖萌的STM32机器人 当冰冷的机械结构遇上生动的表情动画&#xff0c;一个会卖萌的机器人就此诞生。本文将带你深入探索如何通过STM32微控制器驱动SG90舵机&#xff0c;并结合OLED屏幕实现丰富的表情动画效果&#xff0c;打造一个既实用又有趣的互动机…

作者头像 李华
网站建设 2026/4/17 9:54:32

八大网盘直链解析工具终极指南:告别下载限速的完整解决方案

八大网盘直链解析工具终极指南&#xff1a;告别下载限速的完整解决方案 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云盘 /…

作者头像 李华
网站建设 2026/4/17 9:54:32

EPC发布用于机器人和轻型电动车的5kW氮化镓三相逆变器

Efficient Power Conversion (EPC) 推出了两款基于氮化镓&#xff08;GaN&#xff09;技术的高功率密度三相逆变器评估板&#xff08;EPC9186HC2/HC3&#xff09;&#xff0c;专为5kW级别的电机驱动设计&#xff0c;旨在满足机器人及轻型电动交通领域的严苛运动控制需求。该产品…

作者头像 李华
网站建设 2026/4/17 9:52:29

AnyCrawl入门教程:10分钟学会网页内容提取

AnyCrawl入门教程&#xff1a;10分钟学会网页内容提取 【免费下载链接】AnyCrawl AnyCrawl &#x1f680;: A Node.js/TypeScript crawler that turns websites into LLM-ready data and extracts structured SERP results from Google/Bing/Baidu/etc. Native multi-threading…

作者头像 李华