原文地址 http://blog.csdn.net/yuanlulu/article/details/6438847
gpio-led架構 /driver/leds/leds-gpio.c下實現了gpio-led架構。這個gpio-led架構的作用是把傳入的gpio連接埠資訊,註冊成 led_classdev。
資料結構 平台裝置相關的gpio led資料結構 /include/linux/leds.h struct gpio_led {
const char *name; //名字
char *default_trigger; //預設觸發器的名字
unsigned gpio; //使用的gpio編號
u8 active_low; //如果為真則邏輯1代表低電平
};
struct gpio_led_platform_data {
int num_leds; //gpio led的數量
struct gpio_led *leds; //指向要註冊的 gpio_led數組
int (*gpio_blink_set)(unsigned gpio, //硬體閃爍加速設定,可以為NULL
unsigned long *delay_on,
unsigned long *delay_off);
};
如何註冊gpio-led平台裝置 例子如下: #define GPIO_LED3 138
#define GPIO_LED4 139
static struct gpio_led gpio_leds[] = {
{
.name = "led3",
.default_trigger = "heartbeat",
.gpio = GPIO_LED3,
.active_low = 1,
.default_state = LEDS_GPIO_DEFSTATE_OFF,
},
{
.name = "led4",
.gpio = GPIO_LED4,
.active_low = 1,
.default_state = LEDS_GPIO_DEFSTATE_OFF,
},
};
static struct gpio_led_platform_data gpio_led_info = {
.leds = gpio_leds,
.num_leds = ARRAY_SIZE(gpio_leds),
};
static struct platform_device leds_gpio = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &gpio_led_info,
},
}; 最後調用platform_device_register(&leds_gpio)將LED裝置註冊到核心中。註冊之前一定要保證編號為138和139的兩個連接埠是可用的。 成功註冊之後,系統中便會出現名為led3和led4的兩個led_classdev了。由於是用gpio類比led,所以對gpio-led設定的亮度,只要不是0就是全亮(gpio只有兩個狀態)。 對於可能睡眠的gpio,gpio-led會藉助於工作隊列去設定亮度,所以不用擔心會被阻塞。
default-on觸發器 在/driver/leds/ledtrig-default-on.c中實現了一個名為“default-on”的觸發器。這個觸發器只定義了activate成員函數 。它的 activate函數的定義如下: static void defon_trig_activate(struct led_classdev *led_cdev)
{
led_set_brightness(led_cdev, LED_FULL);
} 也就是說,點亮led只能是最亮的亮度,無法調節。一旦ledl_classdev與之建立了串連,就一直處於最亮的狀態,直到取消和觸發器的串連。
心跳燈觸發器 在/driver/leds/ledtrig-heartbeat.c中定義了一個名為"heartbeat"的心跳觸發器,它可以控制所有與之建立串連的led會不停的閃爍。這個觸發器用來指示核心是否已經掛掉。如果與之建立串連的led不再閃爍了,說明核心已經掛掉了。這就是“心跳”的含義,和從人的心臟是否跳動來判斷人是否死亡的原理是類似的。
IDE硬碟指示燈觸發器 在/driver/leds/ledtrig-ide-disk.c中定義了一個名為“ide-disk”的IDE硬碟指示燈觸發器,與之建立串連的led可以指示硬碟的忙碌狀態。這個觸發器並沒有active介面,因此不會自動閃爍。當核心中的其他模組調用以下函數的時候硬碟指示燈就會亮閃一下: void ledtrig_ide_activity(void); 這個函數是全域函數,核心空間都可以調用。每調用一次就閃爍一下。具體怎麼用,完全依賴於IDE驅動。 可以有多個led_classdev和這個觸發器建立串連。每次調用 ledtrig_ide_activity,所有與之串連的led都會閃爍一下。 使用 ledtrig_ide_activity這個函數的模組應該包含<linux/leds.h>這個標頭檔。
閃爍定時觸發器 在/driver/leds/ledtrig-timer.c中定義了一個名為“timer”的觸發器。當某個led_classdev與之串連後,這個觸發器會在/sys/class/leds/<device>/下建立兩個屬性檔案delay_on/delay_off。使用者空間往這兩個檔案中寫入資料後,相應的led會按照設定的高低電平的時間(單位毫秒)來閃爍。如果led_classdev註冊了硬體閃爍的介面led_cdev->blink_set就是用硬體控制閃爍,否則用軟體定時器來控制閃爍。
led_classdev的sysfs屬性檔案 現在假設有一個名為“REDLED”的led_classdev被註冊了,那麼會出現/sys/class/leds/REDLED這個目錄,這個目錄下預設有brightness和trigger這兩個屬性檔案,分別可以設定/讀取led的亮度和觸發器。如果和觸發器 “timer”建立了串連,還會有delay_on和delay_off,這兩個檔案用於設定/讀取閃爍的熄滅和點亮的時間,單位是毫秒。
LED子系統的使用 系統定義了四個預設觸發器:default_on、心跳觸發器、硬碟燈觸發器、閃爍觸發器。除了硬碟燈觸發器,其他觸發器沒有留從其它核心模組訪問的介面。led子系統的目的主要是給使用者空間控制led的。當然可以定義自己的觸發器並留給其它模組訪問的介面。