原文**
(1)參考s3c24xx-led.c
(2)關鍵點就是led_classdev_register ,用這個led驅動框架中的註冊介面去註冊我們的led驅動,
我們通過看sys/class/leds/目錄下的有沒有我們註冊的這個裝置驅動的名字。
(3)我們呼叫led_classdev_register這個led驅動框架中的註冊led驅動的函式,是通過填充好的struct led_classdev這個型別的結構體,去註冊的。
這個struct led_classdev結構體中,有一些這個驅動的名字,和操作這個驅動的讀或寫函式指標,寫led硬體對應的是void(*brightness_set)(struct led_classdev *led_cdev,
enum led_brightness brightness);這個成員指向的函式,我們需要提供乙個對應的能操作led硬體的函式型別的函式填充進去。
這個struct led_classdev結構體還有乙個成員brightness;這個成員是將來在我們讀這個led硬體的時候,讀取出來的值.
這個struct led_classdev結構體還有乙個成員name,就是硬體的名字,將來會在sys/class/leds/目錄下出現,比如是whyx210-led
使用者是怎麼去讀或寫led硬體的呢,這部分是在led-class.c中,led驅動框架幫我們完成好了,在核心驅動框架建立起來之後,也就是執行了led-class.c中的
static int __init leds_init(void)函式後,這個函式中的leds_class = class_create(this_module, "leds");這個語句,會幫我們建立乙個裝置類,在sys/cla
ss/目錄下,建立的裝置類名字是leds,並且在這個函式中又通過leds_class->dev_attrs = led_class_attrs;這個語句,將led_class_attrs,這個所有led裝置
通有的屬性和方法加上了。這個led_class_attrs是乙個結構體,
static struct device_attribute led_class_attrs = ;
這個結構體中的brightness max_brightness trigger等,將來就會在sys/class/leds/whyx210-led/目錄下出現,這些就是這個硬體擁有的屬性檔案。
在這個結構體struct device_attribute中可以看出brightness這個屬性檔案,有led_brightness_show和led_brightness_store,分別對應的就是讀這個led硬體
和寫這個led硬體。而max_brightness這個屬性檔案,有led_max_brightness_show,所以max_brightness這個檔案只可以讀,可以讀取到led硬體當前的值。
led_brightness_show led_brightness_store led_max_brightness_show這三個就是這個硬體的操作方法。可以通過寫或讀這兩個brightness max_brightness
檔案,來使用,方法決定了我們可以這麼去操作這個硬體。
這三個方法對應的就是三個函式,比如led_brightness_store這個寫方法,這個函式裡面有乙個函式led_set_brightness,這個函式中有一條語句led_cdev->brightness_set(led_cdev, value);,並且led_cdev這個結構體也是
struct led_classdev型別的,所以最後我們使用者去通過brightness這個屬性檔案去寫led硬體的時候,會去執行led_brightness_storew這個方法,這個方法中,又
通過呼叫led_set_brightness這個函式,這個函式中通過led_cdev->brightness_set(led_cdev, value);這條語句,最終對應到了struct led_classdev結構體中的brightness_set這個函式指標變數,而這個函式指標變數在我們填充那個結構體
struct led_classdev中的brightness_set函式指標時,就已經繫結好了我們寫的那個寫操作硬體的函式了。所以這一條線就打通了.
**如下:#include
#include
#include
#include //ioremap和iounmap的標頭檔案writel等
#include
#include
#define gpj0cons5pv210_gpj0con//這個巨集是在gpio-bank.h中定義的,是虛擬位址,這個巨集還用到了regs-gpio.h中的巨集,
//以此類推。
#define gpj0dats5pv210_gpj0dat
static struct led_classdev myled;
//這個函式繫結到了struct led_classdev這個結構體型別的myled變數中的brightness_set成員,當我們使用者寫這個led硬體的時候,因為是用led驅動框架
//寫的led驅動,所以我們是通過led驅動框架中的brightness這個檔案,去寫或這個讀led硬體的,應為這個檔案在驅動框架中具有了可讀可寫的屬性,是在
//struct //device_attribute結構中擁有的,並且最終繫結了到了這個裝置類中。所以最後我們使用者去通過brightness這個屬性檔案去寫led硬體的時候,會去執行led_br//ightness_store這個方法,這個方法中,又
//通過呼叫led_set_brightness這個函式,這個函式中通過led_cdev->brightness_set(led_cdev, value);這條語句,最終對應到了struct //led_classdev結構體中的brightness_set這個函式指標變數,而這個函式指標變數在我們填充那個結構體
//struct led_classdev中的brightness_set函式指標時,就已經繫結好了我們寫的那個寫操作硬體的函式了。所以這一條線就打通了.value就是使用者要寫的值
//value是列舉,是enum led_brightness型別的列舉,這個列舉有三個值,分別是led_off = 0 led_*** = 122 led_full = 255,
static void whyx210_led_set(struct led_classdev *led_cdev, enum led_brightness value)
else if (value == led_full)
}static int __init whyx210_led_init(void)
printk(kern_info "led_classdev_register success %s\n", myled.name);
return 0;
}static void __init whyx210_led_exit(void)
module_init(whyx210_led_init);
module_exit(whyx210_led_exit);
module_author("why <[email protected]>");
module_description("whyx210 led driver");
module_license("gpl");
module_alias("whyx210_led");
驅動框架7 使用gpiolib完成led驅動
1 第1步 使用gpio request申請要使用的乙個gpio 2 第2步 gpio direction input gpio direction output 設定輸入 輸出模式 3 第3步 設定輸出值gpio set value 獲取io口值gpio get value。1 在led1上編寫 ...
基於led框架的驅動分析
本文的led驅動使用了核心提供的led框架介面,這種驅動實現與普通字元裝置驅動有著本質的區別。此外還融合了platform和gpiolib,需要結合這兩者來分析本驅動。該驅動本質是 通過讀寫 sys class leds 內的檔案,觸發led classdev 裝置體 內的函式,從而實現操作硬體。整...
嵌入式Linux驅動開發案例流程 LED驅動
本文主要是以乙個最簡單的led驅動開發流程,來窺探一下linux驅動開發為何物。基本流程 1.編寫驅動檔案 x.c 這個檔案的主要作用是對裝置硬體初始化,主要是 init 其中也包括裝置的註冊。對file operations結構體進行初始化,這個初始化是核心,其實是對open.write.read...