当前位置: 首页 > article >正文

Linux第93步_Linux内核的LED灯驱动

Linux内核的LED灯驱动采用platfomm框架,因此我们只需要按照要求在“设备树文件”中添加相应的LED节点即可。

1 、通过“linux内核图形化配置界面”令“CONFIG_LEDS_GPIO=y”

1)、打开终端,输入“cd linux/atk-mp1/linux/my_linux/linux-5.4.31/回车”,切换到“linux/atk-mp1/linux/my_linux/linux-5.4.31/”目录;输入“make menuconfig回车”,打开linux内核图形化配置界面:

2)、移动“向下光标键”至“Device Drivers”,见下图:

3)、按“回车键”,得到下图:

4)、移动“向下光标键”至“LED Support”,见下图:

5)、按“回车键”,得到下图:

6)、移动“向下光标键”至“LED Support for GPIO connected LEDs”,见下图:

7)、按下“Y”键,使此选项前面变为“<*>”,即选中Linux内核自带的LED驱动。然后按“TAB键”至“Exit”,再按“回车”退出,直至到达下面这个界面:

8)、按“TAB键”至“Save”,按下“回车”,得到下面的界面。

9)、输入“./arch/arm/configs/stm32mp1_atk_defconfig”,移动“向下光标键”至“Ok”,得到下图:

10)、按“回车”,保存完成。得到下面的界面。

11)、按“回车”,退出。

12)、按两次“ESC键”,得到下图:

2、打开“./arch/arm/configs/stm32mp1_atk_defconfig”,查看“CONFIG_LEDS_GPIO=y”。

1)、输入“vi  ./arch/arm/configs/stm32mp1_atk_defconfig回车”,打开“stm32mp1_atk_defconfig”文件,见下图:

2)、按“ESC键”,按下“/”,后,输入“CONFIG_LEDS_GPIO回车”,搜索“CONFIG_LEDS_GPIO”,见下图:

3)、发现“CONFIG_LEDS_GPIO=y”,按“ESC键”,按“:q!回车”,不保存退出;

3、查看LED灯驱动文件“/home/zgq/linux/atk-mp1/linux/my_linux/linux-5.4.31/drivers/leds/ leds-gpio.c”

1)、使用虚拟机中的VSCode打开文件夹“/home/zgq/linux/atk-mp1/linux/my_linux/linux-5.4.31/drivers/leds”,见下图:

2)、点击“确定”,然后打开“leds-gpio.c”和“Makefile”,并在“Makefile”中搜索“CONFIG_LEDS_GPIO”,见下图:

在前面的配置中,“CONFIG_LEDS_GPIO”被定义了,则输出“leds-gpio.o”。

3)、打开“leds-gpio.c”,找到“of_device_id of_gpio_leds_match[]”,见下图:

下面是驱动的匹配表:

static const struct of_device_id of_gpio_leds_match[] = {

{ .compatible = "gpio-leds", },/*这是驱动中的compatible属性*/

{}, /*这是一个空元素,在编写of_device_id时最后一个元素一定要为空*/

};

下面是platform driver驱动结构体变量

static struct platform_driver gpio_led_driver = {

.probe = gpio_led_probe,/*probe函数为gpio_led_probe()*/

.shutdown = gpio_led_shutdown,

.driver = {

.name = "leds-gpio",/*指定驱动名字为“leds-gpio”*/

.of_match_table = of_gpio_leds_match,

},

}

4)、打开“include/linux/platform_device.h”文件,查看“module_platform_driver”。见下图:

“module_platform_driver函数”用来向linux内核注册platform驱动,这是一个宏。

#define module_platform_driver(__platform_driver) \

module_driver(__platform_driver, platform_driver_register, \

platform_driver_unregister)

#define module_driver(__driver, __register, __unregister, ...) \

static int __init __driver##_init(void) \

{ \

return __register(&(__driver) , ##__VA_ARGS__); \

} \

module_init(__driver##_init); \

static void __exit __driver##_exit(void) \

{ \

__unregister(&(__driver) , ##__VA_ARGS__); \

} \

module_exit(__driver##_exit);

因此module_platform_driver(gpio_led_driver)展开后,就是:

static int __init gpio_led_driver_init(void)

{

  return platform_driver_register (&(gpio_led_driver));

   //向Linux内核注册一个platform驱动

}

module_init(gpio_led_driver_init);

static void __exit gpio_led_driver_exit(void)

{

  platform_driver_unregister (&(gpio_led_driver) );

  //卸载一个platform驱动

}

module_exit(gpio_led_driver_exit);

4、分析“leds-gpio.c”文件

// SPDX-License-Identifier: GPL-2.0-only

/*

 * LEDs driver for GPIOs

 *

 * Copyright (C) 2007 8D Technologies inc.

 * Raphael Assenat <raph@8d.com>

 * Copyright (C) 2008 Freescale Semiconductor, Inc.

 */

#include <linux/err.h>

#include <linux/gpio.h>

#include <linux/gpio/consumer.h>

#include <linux/kernel.h>

#include <linux/leds.h>

#include <linux/module.h>

#include <linux/of.h>

#include <linux/platform_device.h>

#include <linux/property.h>

#include <linux/slab.h>

struct gpio_led_data {

struct led_classdev cdev;

struct gpio_desc *gpiod;

u8 can_sleep;

u8 blinking;

gpio_blink_set_t platform_gpio_blink_set;

};

static inline struct gpio_led_data *

cdev_to_gpio_led_data(struct led_classdev *led_cdev)

{

return container_of(led_cdev, struct gpio_led_data, cdev);

}

static void gpio_led_set( struct led_classdev *led_cdev,

                       enum led_brightness value)

{

struct gpio_led_data *led_dat = cdev_to_gpio_led_data(led_cdev);

int level;

if (value == LED_OFF)

level = 0;

else

level = 1;

if (led_dat->blinking) {

led_dat->platform_gpio_blink_set(led_dat->gpiod, level,

 NULL, NULL);

led_dat->blinking = 0;

} else {

if (led_dat->can_sleep)

gpiod_set_value_cansleep(led_dat->gpiod, level);

else

gpiod_set_value(led_dat->gpiod, level);

}

}

static int gpio_led_set_blocking(struct led_classdev *led_cdev,

enum led_brightness value)

{

gpio_led_set(led_cdev, value);

return 0;

}

static int gpio_blink_set(struct led_classdev *led_cdev,

unsigned long *delay_on, unsigned long *delay_off)

{

struct gpio_led_data *led_dat = cdev_to_gpio_led_data(led_cdev);

led_dat->blinking = 1;

return led_dat->platform_gpio_blink_set(led_dat->gpiod, GPIO_LED_BLINK,

delay_on, delay_off);

}

static int create_gpio_led(const struct gpio_led *template,

struct gpio_led_data *led_dat, struct device *parent,

struct fwnode_handle *fwnode, gpio_blink_set_t blink_set)

{

struct led_init_data init_data = {};

int ret, state;

led_dat->cdev.default_trigger = template->default_trigger;

led_dat->can_sleep = gpiod_cansleep(led_dat->gpiod);

if (!led_dat->can_sleep)

led_dat->cdev.brightness_set = gpio_led_set;

else

led_dat->cdev.brightness_set_blocking = gpio_led_set_blocking;

led_dat->blinking = 0;

if (blink_set) {

led_dat->platform_gpio_blink_set = blink_set;

led_dat->cdev.blink_set = gpio_blink_set;

}

if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) {

state = gpiod_get_value_cansleep(led_dat->gpiod);

if (state < 0)

return state;

} else {

state = (template->default_state == LEDS_GPIO_DEFSTATE_ON);

}

led_dat->cdev.brightness = state ? LED_FULL : LED_OFF;

if (!template->retain_state_suspended)

led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;

if (template->panic_indicator)

led_dat->cdev.flags |= LED_PANIC_INDICATOR;

if (template->retain_state_shutdown)

led_dat->cdev.flags |= LED_RETAIN_AT_SHUTDOWN;

ret = gpiod_direction_output(led_dat->gpiod, state);

if (ret < 0)

return ret;

if (template->name) {

led_dat->cdev.name = template->name;

ret = devm_led_classdev_register(parent, &led_dat->cdev);

} else {

init_data.fwnode = fwnode;

ret = devm_led_classdev_register_ext(parent, &led_dat->cdev,

     &init_data);

}

return ret;

}

struct gpio_leds_priv {

int num_leds;

struct gpio_led_data leds[];

};

static inline int sizeof_gpio_leds_priv(int num_leds)

{

return sizeof(struct gpio_leds_priv) +

(sizeof(struct gpio_led_data) * num_leds);

}

static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)

{

struct device *dev = &pdev->dev;

struct fwnode_handle *child;

struct gpio_leds_priv *priv;

int count, ret;

count = device_get_child_node_count(dev);//统计子节点量

if (!count)

return ERR_PTR(-ENODEV);

priv = devm_kzalloc(dev, sizeof_gpio_leds_priv(count), GFP_KERNEL);

if (!priv)

return ERR_PTR(-ENOMEM);

device_for_each_child_node(dev, child) {

struct gpio_led_data *led_dat = &priv->leds[priv->num_leds];

struct gpio_led led = {};

const char *state = NULL;

/*

 * Acquire gpiod from DT with uninitialized label, which

 * will be updated after LED class device is registered,

 * Only then the final LED name is known.

 */

led.gpiod = devm_fwnode_get_gpiod_from_child(dev, NULL, child,

     GPIOD_ASIS,

     NULL);

if (IS_ERR(led.gpiod)) {

fwnode_handle_put(child);

return ERR_CAST(led.gpiod);

}

led_dat->gpiod = led.gpiod;

fwnode_property_read_string(child, "linux,default-trigger",

    &led.default_trigger);

if (!fwnode_property_read_string(child, "default-state",

 &state)) {

if (!strcmp(state, "keep"))

led.default_state = LEDS_GPIO_DEFSTATE_KEEP;

else if (!strcmp(state, "on"))

led.default_state = LEDS_GPIO_DEFSTATE_ON;

else

led.default_state = LEDS_GPIO_DEFSTATE_OFF;

}

if (fwnode_property_present(child, "retain-state-suspended"))

led.retain_state_suspended = 1;

if (fwnode_property_present(child, "retain-state-shutdown"))

led.retain_state_shutdown = 1;

if (fwnode_property_present(child, "panic-indicator"))

led.panic_indicator = 1;

ret = create_gpio_led(&led, led_dat, dev, child, NULL);

if (ret < 0) {

fwnode_handle_put(child);

return ERR_PTR(ret);

}

/* Set gpiod label to match the corresponding LED name. */

gpiod_set_consumer_name(led_dat->gpiod,

led_dat->cdev.dev->kobj.name);

priv->num_leds++;

}

return priv;

}

static const struct of_device_id of_gpio_leds_match[] = {

{ .compatible = "gpio-leds", }, /*这是驱动中的compatible属性*/

{}, /*这是一个空元素,在编写of_device_id时最后一个元素一定要为空*/

};

MODULE_DEVICE_TABLE(of, of_gpio_leds_match);

static struct gpio_desc *gpio_led_get_gpiod(struct device *dev, int idx,

    const struct gpio_led *template)

{

struct gpio_desc *gpiod;

unsigned long flags = GPIOF_OUT_INIT_LOW;

int ret;

/*

 * This means the LED does not come from the device tree

 * or ACPI, so let's try just getting it by index from the

 * device, this will hit the board file, if any and get

 * the GPIO from there.

 */

gpiod = devm_gpiod_get_index(dev, NULL, idx, flags);

if (!IS_ERR(gpiod)) {

gpiod_set_consumer_name(gpiod, template->name);

return gpiod;

}

if (PTR_ERR(gpiod) != -ENOENT)

return gpiod;

/*

 * This is the legacy code path for platform code that

 * still uses GPIO numbers. Ultimately we would like to get

 * rid of this block completely.

 */

/* skip leds that aren't available */

if (!gpio_is_valid(template->gpio))

return ERR_PTR(-ENOENT);

if (template->active_low)

flags |= GPIOF_ACTIVE_LOW;

ret = devm_gpio_request_one(dev, template->gpio, flags,

    template->name);

if (ret < 0)

return ERR_PTR(ret);

gpiod = gpio_to_desc(template->gpio);

if (!gpiod)

return ERR_PTR(-EINVAL);

return gpiod;

}

static int gpio_led_probe(struct platform_device *pdev)

{

struct gpio_led_platform_data *pdata = dev_get_platdata(&pdev->dev);

struct gpio_leds_priv *priv;

int i, ret = 0;

if (pdata && pdata->num_leds)/*非设备树方式*/

    {

priv = devm_kzalloc(&pdev->dev,

                           sizeof_gpio_leds_priv(pdata->num_leds),

         GFP_KERNEL);

if (!priv) return -ENOMEM;

priv->num_leds = pdata->num_leds;

for (i = 0; i < priv->num_leds; i++)

       {

         const struct gpio_led *template = &pdata->leds[i];

         struct gpio_led_data *led_dat = &priv->leds[i];

         if (template->gpiod)led_dat->gpiod = template->gpiod;

         else 

          led_dat->gpiod = gpio_led_get_gpiod(&pdev->dev,i, template);

         if (IS_ERR(led_dat->gpiod))

         {

           dev_info(&pdev->dev, "Skipping unavailable LED gpio %d (%s)\n",template->gpio, template->name);

 continue;

  }

ret=create_gpio_led(template, led_dat,&pdev->dev, NULL,pdata->gpio_blink_set);

if (ret < 0) return ret;

}

}

else/*采用设备树*/

{

priv = gpio_leds_create(pdev);

if (IS_ERR(priv)) return PTR_ERR(priv);

}

platform_set_drvdata(pdev, priv);

return 0;

}

static void gpio_led_shutdown(struct platform_device *pdev)

{

struct gpio_leds_priv *priv = platform_get_drvdata(pdev);

int i;

for (i = 0; i < priv->num_leds; i++) {

struct gpio_led_data *led = &priv->leds[i];

if (!(led->cdev.flags & LED_RETAIN_AT_SHUTDOWN))

gpio_led_set(&led->cdev, LED_OFF);

}

}

static struct platform_driver gpio_led_driver = {

.probe = gpio_led_probe,

.shutdown = gpio_led_shutdown,

.driver = {

.name = "leds-gpio",

.of_match_table = of_gpio_leds_match,

},

};

module_platform_driver(gpio_led_driver);

MODULE_AUTHOR("Raphael Assenat <raph@8d.com>, Trent Piepho <tpiepho@freescale.com>");

MODULE_DESCRIPTION("GPIO LED driver");

MODULE_LICENSE("GPL");

MODULE_ALIAS("platform:leds-gpio");

5、修改设备树

在“leds-gpio.c”中,驱动匹配表如下:

static const struct of_device_id of_gpio_leds_match[] = {

{ .compatible = "gpio-leds", },/*这是驱动中的compatible属性*/

{}, /*这是一个空元素,在编写of_device_id时最后一个元素一定要为空*/

};

1)、打开虚拟机上“VSCode”,点击“文件”,点击“打开文件夹”,点击“zgq”,点击“linux”,点击“atk-mp1”,点击“linux”,点击“my_linux”,点击“linux-5.4.31”,点击“确定”,见下图:

2)、点击“转到”,点击“转到文件”,输入stm32mp15-pinctrl.dtsi回车”,打开设备树文件stm32mp15-pinctrl.dtsi。找到“pinctrl”节点,然后添加内容如下:

led_pins_a: gpioled-0 {/*"led_pins_a既是标号也是节点*/

  pins {

pinmux = <STM32_PINMUX('I', 0, GPIO)>,/*设置PI0复用为GPIO功能*/

         <STM32_PINMUX('F', 3, GPIO)>;/*设置PF3复用为GPIO功能*/

drive-push-pull;/*设置引脚为推挽输出*/

bias-pull-up;/*设置引脚内部上拉*/

output-high; /*输出高电平*/

slew-rate = <0>;/*设置引脚的速度为0档,0最慢,3 最高*/

};

};

key_pins_a: key_pins-0 {/*"led_pins_a既是标号也是节点*/

  pins1 {

pinmux = <STM32_PINMUX('G', 3, GPIO)>, /* KEY0 */

         <STM32_PINMUX('H', 7, GPIO)>; /* KEY1 */

bias-pull-up; /*设置引脚内部上拉*/

slew-rate = <0>;/*设置引脚的速度为0档,0最慢,3 最高*/

    };

  pins2 {

pinmux = <STM32_PINMUX('A', 0, GPIO)>; /* WK_UP */

bias-pull-down; /*内部下拉*/

slew-rate = <0>;/*设置引脚的速度为0档,0最慢,3 最高*/

    };

};

电气属性

类型

作用

bias-disable

bootlean

禁止使用内部偏置电压

bias-pull-down

bootlean

内部下拉

bias-pull-up

bootlean

内部上拉

drive-push-pull

bootlean

推挽输出

drive-open-drain

bootlean

开漏输出

output-low

bootlean

输出低电平

output-high

bootlean

输出高电平

slew-rate

enum

引脚的速度,可设置:0~3,0最慢,3 最高

2)、点击“转到”,点击“转到文件”,输入stm32mp157d-atk.dts回车”,打开设备树文件stm32mp157d-atk.dts

3)、根节点“/”下创建一个名为“dtsleds”的子节点,添加内容如下:

dtsleds{

  compatible = "gpio-leds";/*设置属性compatible的值为"gpio-leds"*/

  pinctrl-0 = <&led_pins_a>;

  /*表示取led_pins_a标号所在子节点的硬件信息*/

  led0 {

label = "red_led";

gpios = <&gpioi 0 GPIO_ACTIVE_LOW>;

/*“&gpioi”表示led-gpio引脚所使用的IO属于GPIOI组*/

/*“0’表示GPIOI组的第0号IO,即PI0引脚*/

/*“GPIO_ACTIVE_LOW”表示低电平有效,“GPIO_PULL_UP”表示上拉*/

    default-state = "off";

};

led1 {

  label = "green_led";

  gpios = <&gpiof 3 GPIO_ACTIVE_LOW>;

  /*“&gpiof”表示led-gpio引脚所使用的IO属于GPIOF组*/

  /*“3’表示GPIOF组的第3号IO,即PF3引脚*/

  /*“GPIO_ACTIVE_LOW”表示低电平有效,“GPIO_PULL_UP”表示上拉*/

  default-state = "off";

  };

};

gpio-keys {

  compatible = "gpio-keys";

  pinctrl-names = "default";

  pinctrl-0 = <&key_pins_a>;

  autorepeat;

  key0 {

   label = "GPIO Key L";

   linux,code = <KEY_L>;

   gpios = <&gpiog 3 GPIO_ACTIVE_LOW>;

};

key1 {

  label = "GPIO Key S"; 15 linux,code = <KEY_S>;

  gpios = <&gpioh 7 GPIO_ACTIVE_LOW>;

};

wkup {

  label = "GPIO Key Enter";

  linux,code = <KEY_ENTER>;

  gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>;

  gpio-key,wakeup;

  };

};

key0 {

compatible = "zgq,key";/*设置属性compatible的值为"zgq,led"*/

status = "okay";/*设置属性status的值为"okay"*/

pinctrl-names = "default";

pinctrl-0 = <&key_pins_a>;

key-gpio = <&gpiog 3 GPIO_ACTIVE_LOW>;

/*“&gpiog”表示key-gpio引脚所使用的IO属于GPIOG组*/

/*“3’表示GPIOG组的第3号IO,即PG3引脚*/

/*“GPIO_ACTIVE_LOW”表示低电平有效,“GPIO_PULL_UP”表示上拉*/

interrupt-parent = <&gpiog>;/*指定父中断器为&gpiog*/

/*通过interrupt-parent属性指定pinctrl所有子节点的中断父节点为 gpiog*/

interrupts = <3 IRQ_TYPE_EDGE_FALLING>;

/*“3’表示GPIOG组的第3号IO,即PG3引脚*/

/*IRQ_TYPE_EDGE_FALLING为下降沿触发*/

};

4)、编译设备树

在VSCode终端,输入“make dtbs回车”,执行编译设备树

②输入“ls arch/arm/boot/uImage -l

查看是否生成了新的“uImage”文件

③输入“ls arch/arm/boot/dts/stm32mp157d-atk.dtb -l

查看是否生成了新的“stm32mp157d-atk.dtb”文件

5)、拷贝输出的文件:

①输入“cp arch/arm/boot/uImage /home/zgq/linux/atk-mp1/linux/bootfs/ -f回车”,执行文件拷贝,准备烧录到EMMC;

②输入“cp arch/arm/boot/dts/stm32mp157d-atk.dtb /home/zgq/linux/atk-mp1/linux/bootfs/ -f回车”,执行文件拷贝,准备烧录到EMMC

③输入“cp arch/arm/boot/uImage /home/zgq/linux/tftpboot/ -f回车”,执行文件拷贝,准备从tftp下载;

④输入“cp arch/arm/boot/dts/stm32mp157d-atk.dtb /home/zgq/linux/tftpboot/ -f回车”,执行文件拷贝,准备从tftp下载;

⑤输入“ls -l /home/zgq/linux/atk-mp1/linux/bootfs/回车”,查看“/home/zgq/linux/atk-mp1/linux/bootfs/”目录下的所有文件和文件夹

⑥输入“ls -l /home/zgq/linux/tftpboot/回车”,查看“/home/zgq/linux/tftpboot/”目录下的所有文件和文件夹

⑦输入“chmod 777 /home/zgq/linux/tftpboot/stm32mp157d-atk.dtb回车

给“stm32mp157d-atk.dtb”文件赋予可执行权限

⑧输入“chmod 777 /home/zgq/linux/tftpboot/uImage回车 ,给“uImage”文件赋予可执行权限

⑨输入“ls /home/zgq/linux/tftpboot/回车”,查看“/home/zgq/linux/tftpboot/”目录下的所有文件和文件夹

5)、查看“/sys/bus/platform/devices/dtsleds”这个目录是否存在

我们在设备树文件stm32mp157d-atk.dts根节点“/”下创建过“dtsleds”子节点,因此,需要给开发板上电,查看是否有“dtsleds”这个目录。

①用新的umage和stm32mpl57d-atk.dtb启动开发板。

输入“root回车”。

③输入“cd /sys/bus/platform/devices/dtsleds

切换/sys/bus/platform/devices/dtsleds目录。若可以切换,说明有这个“dtsleds”这个目录。

④输入“ls回车

⑤输入“cd /sys/devices/platform/dtsleds/leds

切换/sys/devices/platform/dtsleds/leds目录。

⑥输入“ls *led -l回车”。

⑦输入“echo 1 > /sys/class/leds/red_led/brightness”,打开LED0;

⑧输入“echo 1 > /sys/class/leds/green_led/brightness,打开LED1;

⑨输入“echo 0 > /sys/class/leds/red_led/brightness”,关闭LED0;

⑩输入“echo 0 > /sys/class/leds/green_led/brightness,关闭LED1;

5、将LEDO作为Linux系统心跳指示灯

5)、修改设备树

如果在“led1”里增加“linux,default-trigger = "heartbeat";

dtsleds{

compatible = "gpio-leds";

       /*设置属性compatible的值为"gpio-leds"*/

pinctrl-0 = <&led_pins_a>;

       /*表示取led_pins_a标号所在子节点的硬件信息*/

led0 {

      label = "red_led";

      gpios = <&gpioi 0 GPIO_ACTIVE_LOW>;

/*“&gpioi”表示led-gpio引脚所使用的IO属于GPIOI组*/

/*“0’表示GPIOI组的第0号IO,即PI0引脚*/

/*“GPIO_ACTIVE_LOW”表示低电平有效,“GPIO_PULL_UP”表示上拉*/

      default-state = "off";

};

led1 {

       label = "green_led";

       gpios = <&gpiof 3 GPIO_ACTIVE_LOW>;

  /*“&gpiof”表示led-gpio引脚所使用的IO属于GPIOF组*/

  /*“3’表示GPIOF组的第3号IO,即PF3引脚*/

  /*“GPIO_ACTIVE_LOW”表示低电平有效,“GPIO_PULL_UP”表示上拉*/

             linux,default-trigger = "heartbeat";

      default-state = "off";

};

};

见下图:

    重新编译“设备树”,使用新的设备树启动Linux系统,LEDO就会闪烁,作为系统心跳指示灯,表示系统正在运行。

在VSCode终端,输入“make dtbs回车”,执行编译设备树

②输入“ls arch/arm/boot/uImage -l

查看是否生成了新的“uImage”文件

③输入“ls arch/arm/boot/dts/stm32mp157d-atk.dtb -l

查看是否生成了新的“stm32mp157d-atk.dtb”文件

5)、拷贝输出的文件:

①输入“cp arch/arm/boot/uImage /home/zgq/linux/atk-mp1/linux/bootfs/ -f回车”,执行文件拷贝,准备烧录到EMMC;

②输入“cp arch/arm/boot/dts/stm32mp157d-atk.dtb /home/zgq/linux/atk-mp1/linux/bootfs/ -f回车”,执行文件拷贝,准备烧录到EMMC

③输入“cp arch/arm/boot/uImage /home/zgq/linux/tftpboot/ -f回车”,执行文件拷贝,准备从tftp下载;

④输入“cp arch/arm/boot/dts/stm32mp157d-atk.dtb /home/zgq/linux/tftpboot/ -f回车”,执行文件拷贝,准备从tftp下载;

⑤输入“ls -l /home/zgq/linux/atk-mp1/linux/bootfs/回车”,查看“/home/zgq/linux/atk-mp1/linux/bootfs/”目录下的所有文件和文件夹

⑥输入“ls -l /home/zgq/linux/tftpboot/回车”,查看“/home/zgq/linux/tftpboot/”目录下的所有文件和文件夹

⑦输入“chmod 777 /home/zgq/linux/tftpboot/stm32mp157d-atk.dtb回车

给“stm32mp157d-atk.dtb”文件赋予可执行权限

⑧输入“chmod 777 /home/zgq/linux/tftpboot/uImage回车 ,给“uImage”文件赋予可执行权限

⑨输入“ls /home/zgq/linux/tftpboot/回车”,查看“/home/zgq/linux/tftpboot/”目录下的所有文件和文件夹

给开发板重新上电,发现led1闪烁。


http://www.kler.cn/a/401733.html

相关文章:

  • 【leetcode 02】27. 移除元素
  • 用Ruby编写一个自动化测试脚本,验证网站登录功能的正确性。
  • 【青牛科技】视频监控器应用
  • go-zero(二) api语法和goctl应用
  • 第23次CCF计算机软件能力认证
  • 【网络云计算】2024第48周-技能大赛-初赛篇
  • 甲骨文云服务器 (Oracle Cloud) 终极防封、防回收的教程!
  • 【鸿蒙开发】第十三章 ArkTS基础类库-容器(数据结构)
  • 用pandoc工具实现ipynb,md,word,pdf之间的转化
  • Vue3 -- 搭建项目路由【vue-router!!!】
  • Qt 文件管理
  • 网络编程-002-UDP通信
  • vscode使用ssh配置docker容器环境
  • Unity类银河战士恶魔城学习总结(P128 Switch UI with KeyBoard用键盘切换UI)
  • 【QT实战】加解密文件夹之————应用程序获取管理员权限
  • 365天深度学习训练营-第P5周:Pytorch实现运动鞋识别
  • 【STM32】在 STM32 USB 设备库添加新的设备类
  • 使用 helm 部署 gitlab
  • 投资策略规划最优决策分析
  • c++实现B树(下)
  • 【论文笔记】Towards Privacy-Aware Sign Language Translation at Scale
  • 手摸手5-springboot开启打印sql完整语句
  • ARM 架构(Advanced RISC Machine)精简指令集计算机(Reduced Instruction Set Computer)
  • qt之QFTP对文件夹(含嵌套文件夹和文件)、文件删除下载功能
  • HTTP 响应头 Deprecation 字段在 API 版本迭代的应用
  • PHP 数组