• 初探linux子系统集之led子系统(三)【转】


    本文转载自:http://blog.csdn.net/eastmoon502136/article/details/37822837

            世界杯结束了,德国战车夺得了大力神杯,阿根廷最终还是失败了。也许3年,5年,或者10年后,人们就不知道巴西世界杯的亚军是谁,但是总是会记得冠军是谁。就像什么考试,比赛,第一永远会被人们所记住,所以我们都想去追寻第一,渴望第一,在一次次的追寻中,成者为王败者为寇。而处在第一的位置,永远担心下面的会超越自己,从而活得很累,而第二永远想争取第一,也活得很累,有时候,想想,人一生当中,成功真的就那么重要吗?富有真的那么重要吗?采菊东篱下,悠然见南山不是也很有诗意吗?说了好多,还是继续写led子系统吧。

            前面写了很多关于led子系统的相关知识,现在终于可以开始分析leds-gpio.c这个驱动了。

            注册了platform驱动。

             platform_driver_register(&gpio_led_driver);

            platform总线就不多说了,在自己的平台下添加platform device就可以了。

             当device和dirver匹配后,就会调用driver的probe函数,这里调用的是下面这个函数。

    [html] view plain copy
     
    1. static int __devinit gpio_led_probe(struct platform_device *pdev)  
    2. {  
    3.          structgpio_led_platform_data *pdata = pdev->dev.platform_data;  
    4.          struct gpio_leds_priv*priv;  
    5.          int i, ret = 0;  
    6.    
    7.          if (pdata &&pdata->num_leds) {  
    8.                    priv =kzalloc(sizeof_gpio_leds_priv(pdata->num_leds),  
    9.                                      GFP_KERNEL);  
    10.                    if (!priv)  
    11.                             return-ENOMEM;  
    12.    
    13.                    priv->num_leds= pdata->num_leds;  
    14.                    for (i = 0;i priv->num_leds; i++) {  
    15.                             ret= create_gpio_led(&pdata->leds[i],  
    16.                                                      &priv->leds[i],  
    17.                                                      &pdev->dev,pdata->gpio_blink_set);  
    18.                             if(ret 0) {  
    19.                                      /*On failure: unwind the led creations */  
    20.                                      for(i = i - 1; i >= 0; i--)  
    21.                                                delete_gpio_led(&priv->leds[i]);  
    22.                                      kfree(priv);  
    23.                                      returnret;  
    24.                             }  
    25.                    }  
    26.          } else {  
    27.                    priv =gpio_leds_create_of(pdev);  
    28.                    if (!priv)  
    29.                             return-ENODEV;  
    30.          }  
    31.    
    32.          platform_set_drvdata(pdev,priv);  
    33.    
    34.          return 0;  
    35. }  



    获取platform里的device的数据,然后create_gpio_led,这里可以注册很多歌led,具体的leds-gpio的platform数据可以参考

    http://blog.csdn.net/eastmoon502136/article/details/37569789

    接着看一下create_gpio_led这个函数。

    [html] view plain copy
     
    1. static int __devinit create_gpio_led(const struct gpio_led*template,  
    2.          struct gpio_led_data*led_dat, struct device *parent,  
    3.          int (*blink_set)(unsigned,int, unsigned long *, unsigned long *))  
    4. {  
    5.          int ret, state;  
    6.    
    7.          led_dat->gpio = -1;  
    8.    
    9.          /* skip leds thataren't available */  
    10.          if(!gpio_is_valid(template->gpio)) {  
    11.                    printk(KERN_INFO"Skipping unavailable LED gpio %d (%s) ",  
    12.                                      template->gpio,template->name);  
    13.                    return 0;  
    14.          }  
    15.    
    16.          ret =gpio_request(template->gpio, template->name);  
    17.          if (ret 0)  
    18.                    return ret;  
    19.    
    20.          led_dat->cdev.name= template->name;  
    21.          led_dat->cdev.default_trigger= template->default_trigger;  
    22.          led_dat->gpio =template->gpio;  
    23.          led_dat->can_sleep= gpio_cansleep(template->gpio);  
    24.          led_dat->active_low= template->active_low;  
    25.          led_dat->blinking =0;  
    26.          if (blink_set) {  
    27.                    led_dat->platform_gpio_blink_set= blink_set;  
    28.                    led_dat->cdev.blink_set= gpio_blink_set;  
    29.          }  
    30.          led_dat->cdev.brightness_set= gpio_led_set;  
    31.          if(template->default_state == LEDS_GPIO_DEFSTATE_KEEP)  
    32.                    state =!!gpio_get_value(led_dat->gpio) ^ led_dat->active_low;  
    33.          else  
    34.                    state =(template->default_state == LEDS_GPIO_DEFSTATE_ON);  
    35.          led_dat->cdev.brightness= state ? LED_FULL : LED_OFF;  
    36.          if(!template->retain_state_suspended)  
    37.                    led_dat->cdev.flags|= LED_CORE_SUSPENDRESUME;  
    38.    
    39.          ret =gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state);  
    40.          if (ret 0)  
    41.                    goto err;  
    42.                     
    43.          INIT_WORK(&led_dat->work,gpio_led_work);  
    44.    
    45.          ret =led_classdev_register(parent, &led_dat->cdev);  
    46.          if (ret 0)  
    47.                    goto err;  
    48.    
    49.          return 0;  
    50. err:  
    51.          gpio_free(led_dat->gpio);  
    52.          return ret;  
    53. }  



    [html] view plain copy
     
    1.    
    2. struct gpio_led_data {  
    3.          struct led_classdevcdev;  
    4.          unsigned gpio;  
    5.          struct work_structwork;  
    6.          u8 new_level;  
    7.          u8 can_sleep;  
    8.          u8 active_low;  
    9.          u8 blinking;  
    10.          int(*platform_gpio_blink_set)(unsigned gpio, int state,  
    11.                             unsignedlong *delay_on, unsigned long *delay_off);  
    12. };  
    13.    



    申请gpio,以及对于一些变量和函数指针的赋值,最后注册led设备。

    关于应用层的调用:

    比如我们在platform设备中注册了

    [html] view plain copy
     
    1. Static struct gpio_led gpio_leds[] = {  
    2.          {  
    3.                    .name=”my-led”,  
    4.                    .default_trigger= “timer”,  
    5.                    .gpio= 30,  
    6.                    .active_low= 1,  
    7.                    .default_state= LEDS_GPIO_DEFSTATE_OFF,  
    8. }  
    9. };  



    那么在/sys/class/leds/下会有my-led目录,在目录下面会创建两个文件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子系统就简单的介绍到这里了。

  • 相关阅读:
    垂死挣扎还是涅槃重生 -- Delphi XE5 公布会归来感想
    自考感悟,话谈备忘录模式
    [每日一题] OCP1z0-047 :2013-07-26 alter table set unused之后各种情况处理
    Java实现 蓝桥杯 算法提高 p1001
    Java实现 蓝桥杯 算法提高 拿糖果
    Java实现 蓝桥杯 算法提高 拿糖果
    Java实现 蓝桥杯 算法提高 求arccos值
    Java实现 蓝桥杯 算法提高 求arccos值
    Java实现 蓝桥杯 算法提高 因式分解
    Java实现 蓝桥杯 算法提高 因式分解
  • 原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/6945119.html
Copyright © 2020-2023  润新知