当前位置:操作系统 > 安卓/Android >>

Android模拟器学framework和driver之battery & backlight-----1.battery in linux

在linux中battery驱动主要是去处理供电方面的东西,大家看下driver在bsp中的路径就可以知道,android模拟器使用的goldfish内核中battery驱动的位置是:
android/common/drivers/power/goldfish_battery.c
目前手机,平板电脑日益普及,在嵌入式领域battery的续航能力也一直制约着手机等嵌入式设备的发展,iphone比android手机做的好多了,希望android可以再处理上下功夫,赶超apple,废话不多说,这里battery主要是处理,电池供电、插上充电器充电、USB供电等事情的发生,还有就是一些电池的信息管理,比如说电量、温度等状态可以使用户知道。
OK,这边我们主要是使用goldfish中的battery驱动来分析一下linux中的power模块是如何工作的。
在这之前我们首先要来看一下power_supply这个device driver 子系统是如何建立的,这边我们涉及到的代码都在/common/drivers/power/下:
power_supply_core.c
power_supply_sysfs.c
goldfish_battery.c
power_supply_core.c是power_supple subsystem的核心函数,在power_supply子系统在linux启动的时候会先调用到里面的饿init函数:
[cpp]
static int __init power_supply_class_init(void) 

    power_supply_class = class_create(THIS_MODULE, "power_supply"); 
 
    if (IS_ERR(power_supply_class)) 
        return PTR_ERR(power_supply_class); 
 
    power_supply_class->dev_uevent = power_supply_uevent; 
 
    return 0; 

 
subsys_initcall(power_supply_class_init); 

这个函数比较简单首先是在class中创建了一个power_supply的class,启动模拟器后可以看到在sys/class/下会有一个power_supply文件夹生成,然后是
power_supply_class->dev_uevent = power_supply_uevent;这句话把power_supply_uevent挂到power_supply_class的dev_uevent上,这里说明下,就是说power_supply子系统都是使用uevent机制把信息传到user space的,当battery的状态发生改变的时候会向用户空间上报一个uevent,这样的话用户空间就可以知道什么时候去抓信息。
这个power_supply_uevent是个回调函数,被定义在power_supply_sysfs.c中:
[cpp]
int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env) 

    struct power_supply *psy = dev_get_drvdata(dev); 
    int ret = 0, j; 
    char *prop_buf; 
    char *attrname; 
 
    dev_dbg(dev, "uevent\n"); 
 
    if (!psy || !psy->dev) { 
        dev_dbg(dev, "No power supply yet\n"); 
        return ret; 
    } 
 
    dev_dbg(dev, "POWER_SUPPLY_NAME=%s\n", psy->name); 
 
    ret = add_uevent_var(env, "POWER_SUPPLY_NAME=%s", psy->name); 
    if (ret) 
        return ret; 
 
    prop_buf = (char *)get_zeroed_page(GFP_KERNEL); 
    if (!prop_buf) 
        return -ENOMEM; 
 
    for (j = 0; j < ARRAY_SIZE(power_supply_static_attrs); j++) { 
        struct device_attribute *attr; 
        char *line; 
 
        attr = &power_supply_static_attrs[j]; 
 
        ret = power_supply_show_static_attrs(dev, attr, prop_buf); 
        if (ret < 0) 
            goto out; 
 
        line = strchr(prop_buf, '\n'); 
        if (line) 
            *line = 0; 
 
        attrname = kstruprdup(attr->attr.name, GFP_KERNEL); 
        if (!attrname) { 
            ret = -ENOMEM; 
            goto out; 
        } 
 
        dev_dbg(dev, "Static prop %s=%s\n", attrname, prop_buf); 
 
        ret = add_uevent_var(env, "POWER_SUPPLY_%s=%s", attrname, prop_buf); 
        kfree(attrname); 
        if (ret) 
            goto out; 
    } 
 
    dev_dbg(dev, "%zd dynamic props\n", psy->num_properties); 
 
    for (j = 0; j < psy->num_properties; j++) { 
        struct device_attribute *attr; 
        char *line; 
 
        attr = &power_supply_attrs[psy->properties[j]]; 
 
        ret = power_supply_show_property(dev, attr, prop_buf); 
        if (ret == -ENODEV) { 
            /* When a battery is absent, we expect -ENODEV. Don't abort;
               send the uevent with at least the the PRESENT=0 property */ 
            ret = 0; 
            continue; 
        } 
 
        if (ret < 0) 
            goto out; 
 
        line = strchr(prop_buf, '\n'); 
        if (line) 
            *line = 0; 
 
        attrname = kstruprdup(attr->attr.name, GFP_KERNEL); 
        if (!attrname) { 
            ret = -ENOMEM; 
            goto out; 
        } 
 
        dev_dbg(dev, "prop %s=%s\n", attrname, prop_buf); 
 
        ret = add_uevent_var(env, "POWER_SUPPLY_%s=%s", attrname, prop_buf); 
        kfree(attrname); 
        if (ret) 
            goto out; 
    } 
 
out: 
    free_page((unsigned long)prop_buf); 
 
    return ret; 

稍微有点

补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,