Android電源管理系統調研報告-(5)

來源:互聯網
上載者:User

2

kernel

sysfs
介面函數的建立

這裡所分析的代碼基於三星公司的手機產品
i5700
。涉及到電源管理的裝置,該裝置驅動應該增添相應的代碼以支援相應的電源管理,如
suspend

resume
。同時應該有相應的代碼向
sysfs
提供相應的
entry
供使用者使用。由於該流程分析的是
Lcd
亮度的調節,所以涉及到
Lcd
驅動向
sysfs
提供的
entry

suspend

resume
等功能在
android
層調用

int release_wake_lock(const char* id);

int acquire_wake_lock(int lock, const char* id);

時起作用。

 


i5700
中,
Lcd
驅動包括兩個檔案,一個是與特定硬體相關的
s3cfb_s6d05a.c
,該檔案實現了與硬體相關的操作,包括
GPIO
口的初始化和電源管理的相關功能函數等;一個是三星通用的
s3cfb.c
,作為橋樑作用聯絡著向

sysfs
提供的
entry

s3cfb_s6d05a.c
中相關功能函數

 

1
)、
/drivers/video/samsung/s3cfb.c

該檔案向
sys
提供了三個
entry
,讓我們來看看這三個
entry
的建立流程。

 

(1)

entry
對應的讀、寫功能函數:

三個
entry
分別是
lcd_power

backlight_power

backlight_level
,這幾個
entry

android
系統起來後,在終端通過
adb shell
,敲入如下命令就可以看到:

# ls /sys/devices/platform/s3c-lcd

其中
*show*
表示讀操作的功能函數,
*store*
表示寫操作的功能函數。在後面會對其中一個函數有進行詳細的分析。

static int s3cfb_sysfs_show_lcd_power(struct device *dev, struct device_attribute *attr, char *buf)

static int s3cfb_sysfs_store_lcd_power(struct device *dev, struct device_attribute *attr, const char *buf, size_t len)

static int s3cfb_sysfs_show_backlight_power(struct device *dev, struct device_attribute *attr, char *buf)

static int s3cfb_sysfs_store_backlight_power(struct device *dev, struct device_attribute *attr, const char *buf, size_t len)

static int s3cfb_sysfs_show_backlight_level(struct device *dev, struct device_attribute *attr, char *buf)

static int s3cfb_sysfs_store_backlight_level(struct device *dev, struct device_attribute *attr, const char *buf, size_t len)

 

(2)

entry
屬性的建立:


核心



中,
sysfs 
屬性一般是由
 __ATTR 
系列的宏來聲明的,如對裝置的使用
 DEVICE_ATTR 
,對匯流排使用
 BUS_ATTR 
,對驅動使用
DRIVER_ATTR 
,對類別
(class)
使用
 CLASS_ATTR, 
這四個進階的宏來自於
<include/linux/device.h>
。在
s3cfb.c
裡,使用的是
DEVICE_ATTR
來建立
entry

sysfs
中的屬性。

static DEVICE_ATTR(lcd_power, 0666,

                     
s3cfb_sysfs_show_lcd_power,

                     
s3cfb_sysfs_store_lcd_power);

 

static DEVICE_ATTR(backlight_power, 0666,

                     
s3cfb_sysfs_show_backlight_power,

                     
s3cfb_sysfs_store_backlight_power);

 

static DEVICE_ATTR(backlight_level, 0644,

                     
s3cfb_sysfs_show_backlight_level,

                     
s3cfb_sysfs_store_backlight_level);

 

DEVICE_ATTR 
宏聲明有四個參數,分別是名稱、許可權位、讀函數、寫函數。其中讀函數和寫函數是讀寫功能函數的函數名。

 

(3)

entry
的建立

entry
的建立是通過函數
device_create_file
完成,在
static int __inits3cfb_probe(struct platform_device *pdev)
函數內實現的。

       
ret = device_create_file(&(pdev->dev), &dev_attr_backlight_power);

 

       
if (ret < 0)

              
printk(KERN_WARNING "s3cfb: failed to add entries/n");

 

       
ret = device_create_file(&(pdev->dev), &dev_attr_backlight_level);

 

       
if (ret < 0)

              
printk(KERN_WARNING "s3cfb: failed to add entries/n");

 

       
ret = device_create_file(&(pdev->dev), &dev_attr_lcd_power);

 

       
if (ret < 0)

              
printk(KERN_WARNING "s3cfb: failed to add entries/n");

 

通過以上簡單的三個步驟,就可以在
shell
終端查看到這三個
entry
了。當我們將資料
echo
到這幾個
entry
中時,在上層實際上完成了一次
write
操作,對應到
kernel
,分別調用了
lcd
驅動中的三個
*store*
。同理,當我們
cat
一個
entry
時則會調用
*show*
。通過在
*show*

*store*
中插樁就可以看到效果。到這裡,只是簡單的建立了
android
層到
kernel
的橋樑,真正實現對硬體操作的,還是在
*show*

*store*
中完成的。

 

 

 

 

 

(4)

backlight_level

 entry
寫函數分析

static int s3cfb_sysfs_store_backlight_level(struct device *dev, struct device_attribute *attr, const char *buf, size_t len)

{

       
unsigned long value = simple_strtoul(buf, NULL, 10);

 

       
if (value < s3c_fimd.backlight_min || value > s3c_fimd.backlight_max)

              
return -ERANGE;

 

       
s3cfb_set_backlight_level(value);

 

       
return len;

}

 

這裡調用了
s3cfb_set_backlight_level(value);

static void s3cfb_set_backlight_level(int to)

{

       
backlight_level = to;

 

       
if (s3c_fimd.set_brightness)

              
(s3c_fimd.set_brightness)(to);

}

 

 

在這個函數裡,
s3c_fimd.set_brightness
是一個函數指標,如果不為空白,剛調用
(s3c_fimd.set_brightness)(to);
。在這裡還看不到到底調用了哪個函數,在
s3cfb_s6d05a.c
中有能該函數指標的初始化以及最終功能函數的實現。

 

 

2
)、
/drivers/video/samsung/s3cfb_s6d05a.c

上文提到的函數介面的初始化是在
static voids3cfb_set_fimd_info(void)
中完成的:

       
s3c_fimd.set_lcd_power             
 = lcd_power_ctrl;

       
s3c_fimd.set_backlight_power = backlight_power_ctrl;

       
s3c_fimd.set_brightness     
 
= backlight_level_ctrl;

 

因此
(s3c_fimd.set_brightness)(to);
實際上是調用了
backlight_level_ctrl(to);

void backlight_level_ctrl(s32 value)

{

       
if ((value < BACKLIGHT_LEVEL_MIN) ||      
/* Invalid Value */

              
(value > BACKLIGHT_LEVEL_MAX) ||

              
(value == backlight_level))  
/* Same Value */

              
return;

 

       
if (backlight_power)

              
backlight_ctrl(value);   

       

       
backlight_level = value;      

}

 

這個函數實現的是
LCD
背光的調節,可以參考程傑SX的部落格:

http://hi.baidu.com/aokikyon/blog/item/ea947e36e42949d0a2cc2b55.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.