初探linuxサブシステムセットのledサブシステム(三)
5751 ワード
W杯が終わり、ドイツの戦車が強力な神杯を獲得し、アルゼンチンは結局失敗した.3年、5年、あるいは10年後、ブラジルワールドカップの準優勝は誰なのか分からないかもしれないが、いつもチャンピオンが誰なのか覚えている.どんな試験のように、試合のように、第一は永遠に人々に覚えられているので、私たちはすべて第一を探して、第一を渇望して、毎回の追跡の中で、成者は王の敗者のために寇です.第1の位置にあって、永远に下のが自分を超えることができることを心配して、それによって生きてとても疲れて、第2は永远に第1を胜ち取りたくて、同じく生きてとても疲れて、时には、考えて、人の一生の中で、成功は本当にそんなに重要ですか?金持ちは本当にそんなに重要ですか?菊の東の垣根の下で、悠然と南山を見るのも詩的ではないか.たくさん話したから、ledサブシステムを書き続けましょう.
前にledサブシステムに関する多くの知識を書いたが、今やっとleds-gpioの分析を始めることができる.cこれが駆動されました.
platformドライバを登録しました.
platform_driver_register(&gpio_led_driver);
platformバスはあまり言わないので、自分のプラットフォームの下にplatform deviceを追加すればいいです.
デバイスとdirverが一致するとdriverのprobe関数が呼び出され、ここで呼び出されるのは次の関数です.
static int __devinit gpio_led_probe(struct platform_device *pdev)
{
structgpio_led_platform_data *pdata = pdev->dev.platform_data;
struct gpio_leds_priv*priv;
int i, ret = 0;
if (pdata &&pdata->num_leds) {
priv =kzalloc(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++) {
ret= create_gpio_led(&pdata->leds[i],
&priv->leds[i],
&pdev->dev,pdata->gpio_blink_set);
if(ret < 0) {
/*On failure: unwind the led creations */
for(i = i - 1; i >= 0; i--)
delete_gpio_led(&priv->leds[i]);
kfree(priv);
returnret;
}
}
} else {
priv =gpio_leds_create_of(pdev);
if (!priv)
return-ENODEV;
}
platform_set_drvdata(pdev,priv);
return 0;
}
platformのデバイスのデータを取得し、create_gpio_led、ここでは多くの歌ledを登録することができて、具体的なleds-gpioのplatformデータは参考することができます
http://blog.csdn.net/eastmoon502136/article/details/37569789.
次にcreateを見てみましょうgpio_ledという関数.
static int __devinit create_gpio_led(const struct gpio_led*template,
struct gpio_led_data*led_dat, struct device *parent,
int (*blink_set)(unsigned,int, unsigned long *, unsigned long *))
{
int ret, state;
led_dat->gpio = -1;
/* skip leds thataren't available */
if(!gpio_is_valid(template->gpio)) {
printk(KERN_INFO"Skipping unavailable LED gpio %d (%s)
",
template->gpio,template->name);
return 0;
}
ret =gpio_request(template->gpio, template->name);
if (ret < 0)
return ret;
led_dat->cdev.name= template->name;
led_dat->cdev.default_trigger= template->default_trigger;
led_dat->gpio =template->gpio;
led_dat->can_sleep= gpio_cansleep(template->gpio);
led_dat->active_low= template->active_low;
led_dat->blinking =0;
if (blink_set) {
led_dat->platform_gpio_blink_set= blink_set;
led_dat->cdev.blink_set= gpio_blink_set;
}
led_dat->cdev.brightness_set= gpio_led_set;
if(template->default_state == LEDS_GPIO_DEFSTATE_KEEP)
state =!!gpio_get_value(led_dat->gpio) ^ led_dat->active_low;
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;
ret =gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state);
if (ret < 0)
goto err;
INIT_WORK(&led_dat->work,gpio_led_work);
ret =led_classdev_register(parent, &led_dat->cdev);
if (ret < 0)
goto err;
return 0;
err:
gpio_free(led_dat->gpio);
return ret;
}
struct gpio_led_data {
struct led_classdevcdev;
unsigned gpio;
struct work_structwork;
u8 new_level;
u8 can_sleep;
u8 active_low;
u8 blinking;
int(*platform_gpio_blink_set)(unsigned gpio, int state,
unsignedlong *delay_on, unsigned long *delay_off);
};
gpioを申請し、いくつかの変数と関数ポインタの付与に対して、最後にledデバイスを登録します.
アプリケーション・レイヤの呼び出しについて:
例えばplatformデバイスに登録しました
Static struct gpio_led gpio_leds[] = {
{
.name=”my-led”,
.default_trigger= “timer”,
.gpio= 30,
.active_low= 1,
.default_state= LEDS_GPIO_DEFSTATE_OFF,
}
};
では/sys/class/leds/の下にmy-ledディレクトリがあり、ディレクトリの下に2つのファイルdelay_が作成されます.onとdelay_off.
に合格
echo 100 >/sys/class/leds/my-led/delay_on
echo 100 >/sys/class/leds/my-led/delay_off
点滅する時間を制御します.
cat /sys/class/leds/my-led/delay_on
cat /sys/class/leds/my-led/delay_off
を選択して、現在のdelay_を取得します.onとdelay_offの値
ledサブシステムについて簡単に紹介します.