【问题标题】:Extending u-boot functionality扩展 u-boot 功能
【发布时间】:2020-02-14 23:39:51
【问题描述】:

我需要为 u-boot 添加一些新功能,例如按下指定按钮以使用闪烁的 LED 作为设备响应来设置我的设备。问题是我不在 u-boot 开始执行 C 代码的地方。我应该修改什么文件?

我使用 STM32F429I-Discovery 进行测试,并且已经安装了使用 buildroot 运行内核所需的一切。其中一个 LED (GPIO_13) 不断闪烁,因此,我尝试搜索提供此类功能的代码。看起来 led.c 和 gpio_led.c 必须这样做,但更改它们没有任何效果。

更新。

好吧,我试图深入研究触发器,但看起来修改 .dts 文件对 LED 闪烁没有影响。在相应的 heartbeat-trigger 中注释代码会关闭 LED,但是没有 GPIO 选择,所以我无法将绿色 LED 更改为红色 LED。在 .dts 文件中将“linux,default-trigger”移动到 GPIO14 后,我使用 buildroot 重新编译 u-boot 和 linux,但没有任何变化。这是我的更改(我从 stm32f746-disco.c 中获取了一些代码):

stm32f429-disco.dts

/dts-v1/;
#include "stm32f429.dtsi"
#include "stm32f429-pinctrl.dtsi"
#include <dt-bindings/input/input.h>

/ {
    model = "STMicroelectronics STM32F429i-DISCO board";
    compatible = "st,stm32f429i-disco", "st,stm32f429";

    chosen {
        bootargs = "root=/dev/ram";
        stdout-path = "serial0:115200n8";
    };

    memory {
    reg = <0x90000000 0x800000>;
    };

    aliases {
        serial0 = &usart1;
    };

    leds {
        compatible = "st,leds";
        red {
            gpios = <&gpiog 14 0>;
            linux,default-trigger = "heartbeat";
        };
        green {
            gpios = <&gpiog 13 0>;
        };
    };

    gpio_keys {
        compatible = "gpio-keys";
        #address-cells = <1>;
        #size-cells = <0>;
        autorepeat;
        button@0 {
            label = "User";
            linux,code = <KEY_HOME>;
            gpios = <&gpioa 0 0>;
        };
    };

    /* This turns on vbus for otg for host mode (dwc2) */
    vcc5v_otg: vcc5v-otg-regulator {
        compatible = "regulator-fixed";
        gpio = <&gpioc 4 0>;
        regulator-name = "vcc5_host1";
        regulator-always-on;
    };
};

&clk_hse {
    clock-frequency = <8000000>;
};

stm32f429-discovery.c

#include <common.h>
#include <dm.h>
#include <ram.h>
#include <spl.h>
#include <asm/io.h>
#include <asm/armv7m.h>
#include <asm/arch/stm32.h>
#include <asm/arch/gpio.h>
#include <asm/arch/stm32_periph.h>
#include <asm/arch/stm32_defs.h>
#include <asm/gpio.h>

DECLARE_GLOBAL_DATA_PTR;

int dram_init(void)
{
    int rv;
    struct udevice *dev;

    rv = uclass_get_device(UCLASS_RAM, 0, &dev);
    if (rv) {
        debug("DRAM init failed: %d\n", rv);
        return rv;
    }

    if (fdtdec_setup_memory_size() != 0)
        rv = -EINVAL;

    return rv;
}

int dram_init_banksize(void)
{
    fdtdec_setup_memory_banksize();

    return 0;
}

u32 get_board_rev(void)
{
    return 0;
}

int board_early_init_f(void)
{
    return 0;
}

int board_init(void)
{
    gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;

    struct gpio_desc gpio = {};
    int node, offset_node;

    node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "st,leds");
    offset_node = fdt_subnode_offset(gd->fdt_blob, node, "green");
    if (node < 0)
        return -1;

    gpio_request_by_name_nodev(offset_to_ofnode(offset_node), "gpios", 0, &gpio, GPIOD_IS_OUT);

    if (dm_gpio_is_valid(&gpio)) {
        dm_gpio_set_value(&gpio, 1);
    }

    return 0;
}

#ifdef CONFIG_MISC_INIT_R
int misc_init_r(void)
{
    char serialno[25];
    uint32_t u_id_low, u_id_mid, u_id_high;

    if (!env_get("serial#")) {
        u_id_low  = readl(&STM32_U_ID->u_id_low);
        u_id_mid  = readl(&STM32_U_ID->u_id_mid);
        u_id_high = readl(&STM32_U_ID->u_id_high);
        sprintf(serialno, "%08x%08x%08x",
        u_id_high, u_id_mid, u_id_low);
        env_set("serial#", serialno);
    }

    return 0;
}

【问题讨论】:

    标签: embedded embedded-linux boot gpio u-boot


    【解决方案1】:

    LED 在设备树中定义(U-Boot 文件 arch/arm/dts/stm32f429-disco.dts,Linux 内核文件 arch/arm/boot/dts/stm32f429-disco.dts)

            leds {
                    compatible = "gpio-leds";
                    red {
                            gpios = <&gpiog 14 0>;
                    };
                    green {
                            gpios = <&gpiog 13 0>;
                            linux,default-trigger = "heartbeat";
                    };
            };
    

    在 Linux 中,您可以通过写入适当的触发器文件来更改触发器。这应该是

    /sys/class/leds/green/触发器

    GPIO的U-Boot驱动是drivers/gpio/stm32_gpio.c

    您可以使用函数 dm_gpio_set_value() 将 GPIO 设置为输入,并使用 dm_gpio_get_value() 读取值。

    您可能希望使用 board/st/stm32mp1/stm32mp1.c 的 FASTBOOT 部分作为模板。

    【讨论】:

    • 它确实做了一些事情。然而,我打破了我的 buildroot,但这是我第一次成功地改变了板上的某些东西。我只需要研究如何正确地重建一切。非常感谢! :)
    • 我更新了问题。看起来 .dts 文件中的更改未应用。甚至删除 "linux,default-trigger = "heartbeat";"不会阻止绿色 LED 闪烁。重建 u-boot .dts 后更新。也许我做错了什么?
    • U-Boot 包含一个设备树,用于使用“驱动程序模型”初始化驱动程序。通常,您不会使用此设备树来引导 Linux,而是从文件中加载 Linux 附带的设备树并将其地址传递给 U-Boot 引导命令。 - 所以,请你检查一下你操纵了两个设备树中的哪一个。
    • 你说得对,我使用了错误的 .dts 文件,现在我可以更改闪烁的 LED 颜色了。但我仍然无法在使用 uboot 启动时打开任何 LED。我正在寻找可以让我从设备树中解析 GPIO 的方法(更新了代码),但它不起作用。
    【解决方案2】:

    您应该在 board.c 文件中添加 u-boot 功能。可以在以下位置找到:u-boot/board/stm/stm32f429-discovery/board.c

    您可能需要更改其他设置,这可以在头文件中完成。这个文件可以找到:u-boot/include/configs/stm32f429-discovery.h

    【讨论】:

    • 非常感谢!剩下的唯一事情就是以某种方式到达引脚以切换它,但这是另一个主题的问题。 :)
    猜你喜欢
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 2011-10-10
    • 2018-02-12
    • 1970-01-01
    相关资源
    最近更新 更多