T113 烧录led灯

问题/功能背景描述

提出此问题的背景:使用SD卡或者U盘烧写镜像时只能看着串口终端是否烧写完成,在批量烧写时不方便,所以通过led灯的闪烁来判断烧写是否完成。

1. 烧录led灯实现函数

int sprite_led_init(void)
{
user_gpio_set_t gpio_init;
int ret   = 0;
int delay = 0;

sprite_led_status = 1;

//正常工作时,灯闪烁的时间
ret = script_parser_fetch("/soc/card_boot", "sprite_work_delay",
 (void *)&delay, 0);

if (!delay) {
delay = 500;
}

pr_msg("try sprite_led_gpio config\n");
memset(&gpio_init, 0, sizeof(user_gpio_set_t));

//配置输出gpio口
ret = fdt_get_one_gpio(FDT_PATH_CARD_BOOT, "sprite_gpio0", &gpio_init);
if (!ret) {
if (gpio_init.port) {
sprite_led_hd = sunxi_gpio_request(&gpio_init, 1);
if (!sprite_led_hd) {
pr_err("reuqest gpio for led failed\n");
return 1;
}

TIMER0.data     = (unsigned long)&TIMER0;
TIMER0.expires  = delay;
TIMER0.function = sprite_timer_func;
//init_timer(&TIMER0);
add_timer(&TIMER0);

tick_printf("sprite_led_gpio start\n");
return 0;
}
}
return 0;
}
 

1.1. 代码解析

这段代码是一个函数 sprite_led_init,用于初始化一个 LED 灯的 GPIO 控制。

  1. 变量初始化和设置

user_gpio_set_t gpio_init;
int ret   = 0;
int delay = 0;
sprite_led_status = 1;

    • gpio_init 是一个结构体类型 user_gpio_set_t,用于存储 GPIO 初始化的参数。
    • ret 和 delay 是整型变量,ret 用于存储函数返回值,delay 用于存储灯闪烁的时间。
    • sprite_led_status 被设置为 1,可能是用来记录 LED 灯的状态。
  1. 读取灯闪烁时间

ret = script_parser_fetch("/soc/card_boot", "sprite_work_delay", (void *)&delay, 0);

    • 从 /soc/card_boot 这个路径下的配置文件中读取 sprite_work_delay 的值,这个值用于设定 LED 灯闪烁的时间。如果读取失败或者值为 0,则将 delay 设置为默认值 500。
  1. GPIO 初始化和配置

pr_msg("try sprite_led_gpio config\n");
memset(&gpio_init, 0, sizeof(user_gpio_set_t));

    • 输出日志信息,表示正在尝试配置 LED 的 GPIO。
    • 使用 memset 将 gpio_init 结构体清零,确保初始化时各字段的初始状态。
  1. 获取 GPIO 配置

ret = fdt_get_one_gpio(FDT_PATH_CARD_BOOT, "sprite_gpio0", &gpio_init);

    • 调用 fdt_get_one_gpio 函数从设备树中获取 sprite_gpio0 的配置信息,填充到 gpio_init 结构体中。
  1. GPIO 请求

if (!ret) {
    if (gpio_init.port) {
        sprite_led_hd = sunxi_gpio_request(&gpio_init, 1);
        if (!sprite_led_hd) {
            pr_err("reuqest gpio for led failed\n");
            return 1;
        }
        // 成功请求到 GPIO 后,设置定时器和回调函数
        TIMER0.data     = (unsigned long)&TIMER0;
        TIMER0.expires  = delay;
        TIMER0.function = sprite_timer_func;
        add_timer(&TIMER0);  // 启动定时器
        tick_printf("sprite_led_gpio start\n");
        return 0;
    }
}

    • 如果成功获取了 GPIO 的配置信息 (ret 为 0),并且 gpio_init.port 不为 0,则表示获取到了有效的 GPIO 口。
    • 调用 sunxi_gpio_request 函数请求这个 GPIO 口。如果请求失败 (sprite_led_hd 为 0),则打印错误信息并返回 1。
    • 如果成功请求到 GPIO 口,则设置定时器 TIMER0:
      • 将定时器的数据域、超时时间和回调函数设置好。
      • 调用 add_timer 启动定时器。
      • 输出日志信息表示 GPIO 初始化成功,并返回 0 表示初始化成功。
  1. 函数返回
    • 如果无法获取或配置 GPIO (ret 不为 0 或者 gpio_init.port 为 0),则直接返回 0,表示初始化失败或者无需进一步处理。

这段代码的主要功能是根据设备树中的配置,初始化一个 GPIO 控制的 LED 灯,并设置定时器来控制 LED 的闪烁频率。

2. 定时函数

static void sprite_timer_func(void *p)
{
gpio_write_one_pin_value(sprite_led_hd, sprite_led_status,
"sprite_gpio0");
sprite_led_status = (~sprite_led_status) & 0x01;

//printf("sprite_time_func\n");
del_timer(&TIMER0);
add_timer(&TIMER0);
return;
}

2.1. 代码解析
  1. 函数定义

static void sprite_timer_func(void *p)

    • sprite_timer_func 是一个静态函数,返回类型为 void,接受一个 void* 类型的参数 p,通常用于传递定时器的上下文信息,但在这段代码中没有使用该参数。
  1. GPIO 控制

gpio_write_one_pin_value(sprite_led_hd, sprite_led_status, "sprite_gpio0");

    • gpio_write_one_pin_value 函数用于控制一个 GPIO 引脚的输出电平。
    • sprite_led_hd 是之前初始化时获取的 GPIO 控制句柄。
    • sprite_led_status 是一个变量,用来记录当前 LED 灯的状态,通过该变量来控制 GPIO 引脚的输出状态。
  1. LED 状态切换

sprite_led_status = (~sprite_led_status) & 0x01;

    • 这行代码通过按位取反和按位与操作,实现 LED 状态的切换。如果 sprite_led_status 当前为 0,则取反后变为 1;如果当前为 1,则取反后变为 0。
  1. 定时器操作

del_timer(&TIMER0);
add_timer(&TIMER0);

    • del_timer(&TIMER0) 用于删除当前定时器 TIMER0,确保在重新添加之前没有冲突。
    • add_timer(&TIMER0) 重新添加定时器 TIMER0,以便在下一次定时器超时后再次调用 sprite_timer_func 函数,从而实现周期性的 LED 灯闪烁效果。
  1. 函数返回

return;

    • 函数结束并返回,没有返回值。

这段代码的作用是在定时器超时时被调用,用于控制一个 GPIO 引脚,通过改变引脚的输出状态来实现 LED 灯的周期性闪烁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值