初探linuxサブシステムセットのledサブシステム(一)

6394 ワード

プログラミングの最初の例helloworldのように、埋め込み式を学び、単片機、fpgaなどの最初の例はランプを点灯することです.膨大なlinuxシステムでは、もちろん文字デバイスドライバを作成して、私たちが必要とするledランプを実現することもできますし、gpioポート、アプリケーションを直接利用してピン制御を高くすることもできます.しかし、linuxシステム自体がもともとledサブシステムを持っている以上、よく利用することができます.メリットは言うまでもなく、主にアプリケーション層にとって、異なるプラットフォームはlinuxのledサブシステムを使用しており、アプリケーションは何の変更もせず、新しいプラットフォームで実行でき、移植性が良い.
linuxのledサブシステムのソースコードパス:
                   Include/Linux/leds.h
                  /drivers/leds

まずledサブシステムの主なファイルを見てみましょう.
# LED Core
obj-$(CONFIG_NEW_LEDS)                        +=led-core.o
obj-$(CONFIG_LEDS_CLASS)                 += led-class.o
obj-$(CONFIG_LEDS_TRIGGERS)              +=led-triggers.o
 
# LED PlatformDrivers
obj-$(CONFIG_LEDS_GPIO)                        += leds-gpio.o
 
# LED Triggers
obj-$(CONFIG_LEDS_TRIGGER_TIMER) +=ledtrig-timer.o
obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK)      +=ledtrig-ide-disk.o
obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) +=ledtrig-heartbeat.o
obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) +=ledtrig-backlight.o
obj-$(CONFIG_LEDS_TRIGGER_GPIO)              +=ledtrig-gpio.o
obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON)        += ledtrig-default-on.o

主にleds.h、led-core.c、led-class.c、led-triggers.c.ここでled-triggersはtimer、ide-disk、heartbeat、backlight、gpio、default-onなどのアルゴリズムに分けられる.
 
例プログラムはleds-gpioであり,次に主にこの駆動実装を解析する.
 
まず、主な書類を簡単に見てみましょう.
 
Leds.h
1、enum led_brightness{
         LED_OFF           = 0,
         LED_HALF         = 127,
         LED_FULL         = 255,
};

Ledの明るさは、3段階に分けられ、オフ、真ん中、最も明るい.
 
2、struct led_classdev{
         constchar                  *name;   // Led   
         int                       brightness;   //led  
         int                       max_brightness; //led    
         int                       flags;
 
         /*Lower 16 bits reflect status */
#define LED_SUSPENDED                  (1 << 0)
         /*Upper 16 bits reflect control information */
#define LED_CORE_SUSPENDRESUME   (1 << 16)
 
         /*Set LED brightness level */
         /*Must not sleep, use a workqueue if needed */
         void           (*brightness_set)(struct led_classdev*led_cdev,
                                                 enum led_brightness brightness);   //        
         /*Get LED brightness level */
         enumled_brightness (*brightness_get)(struct led_classdev *led_cdev); //        
 
         int              (*blink_set)(struct led_classdev*led_cdev,
                                          unsigned long *delay_on,
                                          unsigned long *delay_off);  //             
 
         structdevice             *dev;
         structlist_head        node;                        //leds-list node
         constchar                  *default_trigger;     //  trigger   
 
         unsignedlong           blink_delay_on,blink_delay_off;   //       
         structtimer_list       blink_timer;                    //        
         int                       blink_brightness;                   //     
 
#ifdef CONFIG_LEDS_TRIGGERS
         /*Protects the trigger data below */
         structrw_semaphore      trigger_lock;               //trigger  
 
         structled_trigger    *trigger;                      //led trigger
         structlist_head        trig_list;                     //trigger   
         void                    *trigger_data;                     //trigger   
#endif
};
3、struct led_trigger {
         /*Trigger Properties */
         constchar        *name;           //trigger   
         void           (*activate)(struct led_classdev*led_cdev);   //  trigger
         void           (*deactivate)(struct led_classdev*led_cdev);  
 
         /*LEDs under control by this trigger (for simple triggers) */
         rwlock_t   leddev_list_lock;
         structlist_head  led_cdevs;                     //led     
 
         /*Link to next registered trigger */
         structlist_head  next_trig;
};

 
4、/* For the leds-gpiodriver */
struct gpio_led {
         constchar *name;              //led   
         constchar *default_trigger;            //   trigger
         unsigned         gpio;                            //gpio 
         unsigned  active_low : 1;       
         unsigned  retain_state_suspended : 1;
         unsigned  default_state : 2;
         /*default_state should be one of LEDS_GPIO_DEFSTATE_(ON|OFF|KEEP) */
};
 

 
5、structgpio_led_platform_data {
         int           num_leds;             led   
         conststruct gpio_led *leds;       led   
 
#define GPIO_LED_NO_BLINK_LOW       0       /*No blink GPIO state low */
#define GPIO_LED_NO_BLINK_HIGH      1       /*No blink GPIO state high */
#define GPIO_LED_BLINK                 2       /* Please, blink */
         int              (*gpio_blink_set)(unsigned gpio,int state,
                                               unsignedlong *delay_on,
                                               unsignedlong *delay_off);
};
 

 
led-core.c
DECLARE_RWSEM(leds_list_lock);
EXPORT_SYMBOL_GPL(leds_list_lock);
 
LIST_HEAD(leds_list);
EXPORT_SYMBOL_GPL(leds_list);

主にledsのチェーンテーブルとロックが宣言されています.
 
Led-class.c
1、  leds_init
主にleds_の作成class、suspendとresume、dev_の割り当てattrs.
led_class_attrs
static  struct device_attribute led_class_attrs[] = {
         __ATTR(brightness,0644, led_brightness_show, led_brightness_store),
         __ATTR(max_brightness,0444, led_max_brightness_show, NULL),
#ifdef CONFIG_LEDS_TRIGGERS
         __ATTR(trigger,0644, led_trigger_show, led_trigger_store),
#endif
         __ATTR_NULL,
};

2、led_classdev_register
classdevデバイス、すなわちLeds_の作成classクラスでは、c++のnewのようなオブジェクトをインスタンス化します.ledsには多くの種類がありますが、ここでは特定のledを登録し、カーネルのオブジェクト向け思想も極めて豊富です.
leds_に追加Listチェーンテーブルでblinktimerを初期化し、blink_を指定timerのfunctionとdataは、triggerを設定し、新しいledデバイスを登録して使用できます.
 
led-triggers.c
1、led_trigger_register
triggerチェーンテーブルに同じ名前のtriggerがあるかどうかをスキャンし、led_classdevにデフォルトのtriggerがあるので、このデフォルトを設定します.
 
では、ledサブシステムにおける比較的重要な構造体と関数を簡単に見ると、leds-gpioという駆動によってledサブシステムをさらに理解することができます.