Linux LED 驱动之 heartbeat

1. 前言

限于作者能力水平,本文可能存在的谬误,因此而给读者带来的损失,作者不做任何承诺。

2. 背景

要在 S5P4418 的开发板上,驱动一个 LED 灯,用作系统工作状态的心跳灯,内核版本为 Linux 3.4.yLED 灯的硬件设计为:

GPIOC17连接到LED灯:拉低GPIO,灯变亮,拉高GPIO,灯熄灭。

3. 实现

初始的想法是,通过workqueuetimer定期控制 GPIO 电平状态,从而控制连接到 GPIOLED 的亮灭。按这个思路,需要实现一个完整的驱动,但经过摸索后发现,内核已经为我们提供了类似的驱动,我们只需要做简单的适配就可以了。经过斟酌,我们选用了 heartbeat 算法的 LED 驱动,其使用workqueue实现其功能。接下来我们看如何适配该驱动到我们的 LED 硬件。

3.1 LED 灯驱动 GPIOC17 平台适配

由于 GPIOC17 是具备复用功能,首先我们要将它配置成工作在 GPIO 模式。修改文件arch/arm/plat-s5p4418/nanopi2/include/cfg_gpio.h

#define PAD_GPIOC17     (PAD_MODE_OUT | PAD_FUNC_ALT1 | 
			       PAD_LEVEL_LOW  | PAD_PULL_OFF | 
			       PAD_STRENGTH_0)

3.2 创建 GPIO LED 驱动设备对象

GPIO LED 驱动实现在文件drivers/leds/leds-gpio.c,使用该驱动,要创建一个该驱动的设备对象。修改文件arch/arm/plat-s5p4418/nanopi2/device.c

#if defined(CONFIG_LEDS_GPIO)
#include <linux/leds.h>
static struct gpio_led board_leds[] = {
	{
		.name		 = "led1",
		.gpio		 = (PAD_GPIO_B + 12),
		.active_low	 = 1,
		.default_trigger = "heartbeat",
	}, {
		.name		 = "led2",
		.gpio		 = (PAD_GPIO_B + 11),
		.active_low	 = 1,
		.default_trigger = "none",
	}, { /* 添加作为系统心跳灯的GPIO LED */
		.name		 = "led3", /* 名称 */
		.gpio		 = (PAD_GPIO_C + 17), /* 指定灯控制GPIOC */
		.active_low	 = 1, /* 低电平点亮灯 */
		/* 灯的控制算法,可以有更多选择。参看 drivers/leds/trigger 目录 */
		.default_trigger = "heartbeat", 
	}, 
};

static struct gpio_led_platform_data gpio_led_pdata = {
	.num_leds	= ARRAY_SIZE(board_leds),
	.leds		= board_leds,
};

/* 添加作为系统心跳灯的GPIO LED驱动设备对象 */
static struct platform_device gpio_led_device = {
	.name		= "leds-gpio",
	.id			= -1,
	.dev		= {
		.platform_data	= &gpio_led_pdata,
	},
};
#endif

当然,使用内核 GPIO LED 灯驱动的前提是,开启配置项 CONFIG_LEDS_GPIO

posted @ 2025-04-08 09:04  JiMoKuangXiangQu  阅读(56)  评论(0)    收藏  举报