• 276查看
  • 0回复

[芯片硬件] 电源管理入门-17 Power supply子系统

[复制链接]


该用户从未签到

发表于 3-3-2024 08:45:43 | 显示全部楼层 |阅读模式

汽车零部件采购、销售通信录       填写你的培训需求,我们帮你找      招募汽车专业培训老师


电源管理入门-17 Power supply子系统w1.jpg
对于便携设备来说,电源管理更加的重要,因为电池电量有限,容易电量焦虑。除了省电管理外,还需要对电池进行监控管理和充放电管理,这样保护好电池和系统,能用的更久。

1. Power supply框架都做些什么

这里我们以安卓为例:

电源管理入门-17 Power supply子系统w2.jpg
    APP 层: 该部分属于电量上报的最后的环节。其主要工作是:监听系统广播并对 UI 作出相应更新,包括电池电量百分比,充电状态,低电提醒,led 指示灯,异常提醒等。FrameWork 层: 本层的 Battery 服务使用 Java 代码写成,运行在 FrameWork 中的SystemServer 进程。该系统服务的主要作用是:监听电池信息变化消息,并将该消息以系统广播的形式转发至 Android 系统中各处。Native 层: Healthd 守护进程属于 Android Native 层的一个系统服务,负责接受 Kernel Driver 层上报的 uevent 事件,对电池信息和充电状态实时监控。Kernel 层: 本层属于电池的驱动部分,由 Charger-manager 驱动、充电 IC 驱动、Fuel 驱动构成,负责与硬件交互,注册 Power supply 属性,并生成 uevent 上报 Native 层。包含充电状态管理、电量统计与更新。

关机充电
关机充电是单独启动的一个 linux 应用,通过系统调用直接读取 sysfs 来获取电池信息,init 进程会根据启动模式来启动 charge 服务,不会启动 android 相关进程。

我们这里只关注kernel层:

电源管理入门-17 Power supply子系统w3.jpg
power supply framework在kernel/drivers/power/下。内核抽象出来power supply子系统为驱动提供了统一的框架。功能包括:

1.抽象PSY设备的共性,向用户空间提供统一的API

2.为底层PSY驱动的编写,提供简单、统一的方式。同事封装并实现公共逻辑。

power supply class位于drivers/power/目录中,主要由3部分组成(可参考下图的软件架构):

1)power supply core,用于抽象核心数据结构、实现公共逻辑。位于drivers/power/power_supply_core.c中。

2)power supply sysfs,实现sysfs以及uevent功能。位于drivers/power/power_supply_sysfs.c中。

3)power supply leds,基于linux led class,提供PSY设备状态指示的通用实现。位于drivers/power/power_suppply_leds.c中。

最后,驱动工程师可以基于power supply class,实现具体的PSY drivers,主要处理平台相关、硬件相关的逻辑。这些drivers都位于drivers/power/目录下。

2. 相关数据结构和接口

2.1 数据结构

struct power_supply:用于抽象PSY设备
/* include/linux/power_supply.h */
struct power_supply {
        const struct power_supply_desc *desc;        //PSY描述符

        char **supplied_to;
        size_t num_supplicants;

        char **supplied_from;
        size_t num_supplies;
        struct device_node *of_node;

        /* Driver private data */
        void *drv_data;

        /* private */
        struct device dev;
        struct work_struct changed_work;
        struct delayed_work deferred_register_work;
        spinlock_t changed_lock;
        bool changed;
        bool initialized;
        bool removing;
        atomic_t use_cnt;
#ifdef CONFIG_THERMAL
        struct thermal_zone_device *tzd;
        struct thermal_cooling_device *tcd;
#endif

#ifdef CONFIG_LEDS_TRIGGERS
        struct led_trigger *charging_full_trig;
        char *charging_full_trig_name;
        struct led_trigger *charging_trig;
        char *charging_trig_name;
        struct led_trigger *full_trig;
        char *full_trig_name;
        struct led_trigger *online_trig;
        char *online_trig_name;
        struct led_trigger *charging_blink_full_solid_trig;
        char *charging_blink_full_solid_trig_name;
#endif
};

struct power_supply_desc:该描述符定义了psy的属性
/* Description of power supply */
struct power_supply_desc {
        const char *name;                                                //PSY name
        enum power_supply_type type;                        //PSY类型
        enum power_supply_usb_type *usb_types;        //usb类型
        size_t num_usb_types;                                        //usb类型个数
        enum power_supply_property *properties;        //该PSY具有的属性列表
        size_t num_properties;                                        //属性的个数

        /*
         * Functions for drivers implementing power supply class.
         * These shouldn't be called directly by other drivers for accessing
         * this power supply. Instead use power_supply_*() functions (for
         * example power_supply_get_property()).
         */
        int (*get_property)(struct power_supply *psy,        //用于获取psy属性的回调函数
                            enum power_supply_property psp,
                            union power_supply_propval *val);
        int (*set_property)(struct power_supply *psy,        //用于设置psy属性的回调函数
                            enum power_supply_property psp,
                            const union power_supply_propval *val);
        /*
         * property_is_writeable() will be called during registration
         * of power supply. If this happens during device probe then it must
         * not access internal data of device (because probe did not end).
         */
        int (*property_is_writeable)(struct power_supply *psy,        //返回指定的属性值是否可写(用于sysfs)
                                     enum power_supply_property psp);
        void (*external_power_changed)(struct power_supply *psy);        //当一个PSY设备存在并且属性发生改变时,power supply core会调用该回调函数,通知PSY driver,以便让它做出相应的处理
        void (*set_charged)(struct power_supply *psy);

        /*
         * Set if thermal zone should not be created for this power supply.
         * For example for virtual supplies forwarding calls to actual
         * sensors or other supplies.
         */
        bool no_thermal;
        /* For APM emulation, think legacy userspace. */
        int use_for_apm;
};

power_supply_battery_info:管理静态电池参数的推荐结构
2.2 接口

power_supply_core.c主要负责设备状态变化逻辑,power_supply_sysfs.c主要负责文件节点相关逻辑。

power_supply_changed:在驱动中检测到硬件状态发生变化,会通过该函数调度起psy中的changed_work。该工作队列负责发送notifier(内核内不同模块之间)和通过uevent进行change上报。
void power_supply_changed(struct power_supply *psy)
{
        unsigned long flags;

        dev_dbg(&psy->dev, "%s\n", __func__);

        spin_lock_irqsave(&psy->changed_lock, flags);
        psy->changed = true;
        pm_stay_awake(&psy->dev);
        spin_unlock_irqrestore(&psy->changed_lock, flags);
        schedule_work(&psy->changed_work);
}
EXPORT_SYMBOL_GPL(power_supply_changed);

power_supply_register:通过调用__power_supply_register负责注册一个psy设备,一般在设备驱动的probe流程中调用

power_supply_get_by_name:通过名字获取PSY指针

power_supply_put:释放获取到的PSY指针,与power_supply_get_by_name成对使用

3. 充电驱动

电源管理入门-17 Power supply子系统w4.jpg
    Charge Manger、Fuel Gauge、Charge IC,这三部分作为独立的设备驱动均注册到 Power-supply 中,每一个设备为单独的 PSY。PSY 之间可以通过 power supply 属性相互访问。fuel-gauge 跟 charge-ic是服务于 charge-manger,charge-manger 不需要了解硬件细节,仅通过获取相应功能的 PSY 设备实例,通过这个 PSY 的属性获取相应信息。
3.1 Charger Manager

Charger Manager 是充电的控制策略层,主要负责:
    修复并更新电量百分比。充电流程管理(charging,notcharging,discharging,full 充电状态转换管理)。安全管理(Ovp,Health,Charge Time out)。温控管理(Jeita 功能,thermal 限流)。电池电量显示策略(充放电曲线)。电池容量管理(容量自学习功能)。

Charger Manager 以“battery”名字注册至 Power Supply 架构,会读写 Fuel Gauge 和 Charger IC 的 Power supply 属性。
charger-manager {
    compatible = "charger-manager";
    cm-name = "battery";
    cm-poll-mode = <2>; //”_cm_monitor”轮询模式
    cm-poll-interval = <15000>;//”_cm_monitor”轮询时间间隔
    cm-battery-stat = <2>;//电池在位检测方法,电压法

    cm-fullbatt-vchkdrop-ms = <30000>;//充满电后,检查复充条件的周期
    cm-fullbatt-vchkdrop-volt = <84000>;//满电后复充电压条件
    cm-fullbatt-voltage = <4350000>;//软件满电电压判断阈值,必须配置
    cm-fullbatt-current = <120000>;;//软件满电电流判断阈值,必须配置
    cm-fullbatt-capacity = <100>;//电池满电时百分比

    cm-num-chargers = <1>;//charger ic数量
    //cm-chargers = "sc2721_charger";
    cm-chargers = "fan54015_charger";//charger ic名字
    cm-fuel-gauge = "sc27xx-fgu";//fgu名字

    /* in deci centigrade */
    cm-battery-cold = <200>;
    cm-battery-cold-in-minus;
    cm-battery-hot = <800>;
    cm-battery-temp-diff = <100>;

    /* Allow charging for 6hr */
    cm-charging-max = <36000000>;
    /* recovery charging after stop charging 45min */
    cm-discharging-max = <2700000>;

    /* the interval to feed charger watchdog */
    cm-wdt-interval = <0>;

    /* drop voltage in microVolts to allow shutdown */
    cm-shutdown-voltage = <3470000>;//低电关机电压

    /* when 99% of the time is exceeded, it will be forced to 100% */
    cm-tickle-time-out = <1500>;

    /* how much time to allow capacity change */
    cm-one-cap-time = <60>;//允许电量增加1%最快时间

    /* when the safe charging voltage is exceeded, stop charging */
    cm-charge-voltage-max = <6500000>;//充电器过压保护电压阈值
    /* drop voltage in microVolts to restart charging */
    cm-charge-voltage-drop = <700000>;//复充电压条件
    //Jeita 温控策略
    cm-jeita-temp-table = <1000 1030 700000 4200000>,   //不同温度范围内的充电电流和充电截止电压
                    <1150 1180 2000000 4400000>,                                   //默认最大充电电流为2A
                    <1450 1420 2000000 4400000>,                                   //充电电压为4.35V
                    <1600 1570 700000 4200000>;

    regulator@0 {
            cm-regulator-name = "vddgen0";
            cable@0 {
                    cm-cable-name = "USB";
                    extcon = <&extcon_gpio>;
            };
    };
};

充电温控策略说明
电池温度T(℃)充电电流 ICC(mA)充电截止电压 VEOC(mV)
T≤07004200
0<T<1520004400
15≤T<4520004400
45≤T<607004200
T≥6004200
bat: battery {
    compatible = "simple-battery";
    charge-full-design-microamp-hours = <3900000>;//电池容量uAh
    charge-term-current-microamp = <200000>;//截止充电电流
    constant_charge_voltage_max_microvolt = <4400000>;//截止充电电压
    factory-internal-resistance-micro-ohms = <115000>;//电池内阻
    voltage-min-design-microvolt = <3561000>;        //Vocv低报警电压

    //电池容量 – 温度补偿表
    capacity-temp-table = <60 100>, <40 100>, <25 100>, <0 100>, <(-10) 80>;
    //电池内阻值 – 温度补偿表
    resistance-temp-table = <60 60>, <40 70>, <25 100>, <0 328>, <(-20) 887>;
};
3.2 Fuel Gauge

PMIC部分主要负责:
    库伦计电量积分充电器类型获取电池在位检测开机电压管理内阻 – 温度,容量 – 温度等补偿算法

sc27xx_fuel_gauge 以“sc27xx-fgu”名字注册至 Power supply 架构,提供属性给 Charger Manager 读写。
pmic_fgu: fgu@a00 {
    compatible = "sprd,sc27xx-fgu", "sprd,sc2731-fgu";
    reg = <0xa00>;
    bat-detect-gpio = <&pmic_eic 9 0>;
    nvmem-cell-names = "fgu_calib";
    nvmem-cells = <&fgu_calib>;
    io-channels = <&pmic_adc 0>, <&pmic_adc 14>, <&pmic_adc 16>;
    io-channel-names = "bat-temp", "charge-vol", "charger-cur";
    interrupt-parent = <&sc2721_pmic>;
    interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
    monitored-battery = <&bat>;
    sprd,calib-resistance-real = <20000>;        //库仑计芯片真实采样电阻
    sprd,calib-resistance-spec = <20000>;        //库仑计芯片规格电阻
};

3.3 Charger IC

Charger IC 主要负责以下具体内容:
    打开/关闭充电设置充电电流设置截止充电电压点打开/关闭 OTG

以 Fan54015 为例,将“fan54015_charger”名字注册至 Power supply 架构。提供属性给 Charger Manager读写。
&i2c3 {
   status = "okay";
   clock-frequency = <400000>;

   fan54015_chg: charger@6a {
           compatible = "fairchild,fan54015_chg";
           reg = <0x6a>;
           phys = <&hsphy>;
           monitored-battery = <&bat>;
           extcon = <&extcon_gpio>;
           vddvbus:otg-vbus {
                   regulator-name = "vddvbus";
           };
   };
};

4. 怎样基于power supply class编写PSY driver

最后从PSY driver的角度,说明一下怎么基于power supply class编写驱动:

(1)根据硬件spec,确定PSY设备具备哪些特性,并把他们和enum power_supply_property对应。

(2)根据实际情况,实现这些properties的get/set接口。

(3)定义一个struct power_supply 变量,并初始化必要字段后,调用power_supply_register或者power_supply_register_no_ws,将其注册到kernel中。

(4)根据实际情况,启动设备属性变化的监控逻辑,例如中断,轮询等,并在发生改变时,调用power_supply_changed,通知power suopply core。

power supply子系统的引入 以市面上一款常见的的平板方案来看一看,进入平板的sys/class/power_supply/目录下

电源管理入门-17 Power supply子系统w5.jpg
可以看到这里有三个****PSY 设备,分别对应 USB 充电器 DC 充电器,和电池。

进入battery目录下,发现下面有各种各样的属性,另外两个atc260x-usb 、atc260x-wall目录下分别也是这样。
电源管理入门-17 Power supply子系统w6.jpg
然后在内核中找到对应的代码,进行学习,然后仿制一个出来就可以。以battery 驱动为例来分析。
    static int __init atc260x_gauge_init(void)atc260x_gauge_probe(struct platform_device *pdev)soc_post_process(struct atc260x_gauge_info *info)power_supply_register(struct device *parent, struct power_supply *psy)power_supply_changed(struct power_supply *psy)

在相关的函数上打点断点,然后就可以学习了。

参考资料:

    https://blog.csdn.net/Numeral_Life/article/details/124244654https://blog.csdn.net/weixin_46376201/article/details/125201962

后记:

Linux内核博大精深,里面的机制太多了,不调试或者工作涉及根本学不精。可以了解了解概念和数据结构。遇到了先调试,必须知道了再去查资料研究,学不完,根本学不完。。。

干啥都能干,干啥啥不是,

专业入门劝退,堪称程序员杂家”。

欢迎各位有自己公众号的留言:申请转载,多谢!

后续会继续更新,纯干货分析,欢迎分享给朋友,欢迎点赞、收藏、在看、划线和评论交流!


该用户从未签到

发表于 14-3-2025 16:58:01 | 显示全部楼层
关于电源管理入门,特别是针对电源供应子系统(Power supply subsystem),在便携设备中至关重要。Power supply框架主要作用包括管理和监控电池状态、执行充放电策略并优化电量使用。在安卓系统中,APP层负责电量上报的最后环节,包括显示电池电量百分比、充电状态等,并作出相应UI更新。而Framework层的Battery服务则通过Java代码实现,运行在Framework中,扮演着桥梁的角色,向上层APP传递电池状态信息,同时对底层硬件的充放电进行管理。为保障电源供应系统的正常运行和电池寿命,应定期进行维护和检查。
回复 支持 反对

使用道具 举报



该用户从未签到

发表于 14-3-2025 16:58:00 | 显示全部楼层
针对您关于电源管理入门的问题,以下是专业回复:

电源管理对于便携设备至关重要,涉及电力供应、监控管理和电池保护。在Power supply框架中,APP层负责电量上报的最后环节,包括电量百分比、充电状态等UI更新。而Framework层的Battery服务则通过Java代码运行,负责系统级的电量管理。此外,内核层及驱动层对电池状态进行实时监控并上报数据。为了延长电池寿命,还需进行充放电管理和保护。总之,电源管理涉及多个层面和方面,需综合考虑以实现高效、安全的电力管理。
回复 支持 反对

使用道具 举报



该用户从未签到

发表于 14-3-2025 16:58:01 | 显示全部楼层
针对您关于电源管理入门的问题,以下是专业回复:

关于电源管理系统的框架,以安卓为例,主要包括APP层和Framework层。APP层负责电量上报的最后环节,如监听系统广播并更新UI,包括电池电量百分比、充电状态等信息的显示。Framework层的Battery服务则通过Java代码实现,运行于系统框架中,负责监控电池状态并执行相应的管理操作。此外,还需对电池进行监控管理和充放电管理,以延长电池和系统使用寿命。电源管理在便携设备中尤为重要,有效的电源管理能显著提高设备的续航能力和用户体验。
回复 支持 反对

使用道具 举报



该用户从未签到

发表于 14-3-2025 16:58:00 | 显示全部楼层
对于电源管理系统的入门者来说,理解Power supply框架是基础。以安卓系统为例,Framework层的Battery服务负责管理电池状态信息,包括电量百分比、充电状态等。它通过与硬件层交互获取实时数据,并经由APP层展现给用户。为了保证电源供应子系统的稳定性和效率,除了电池监控管理,还需关注充放电管理、电量预估和节能策略等。对电池的良好管理不仅能延长设备使用时间,还能提高系统安全性。建议进一步学习电源管理相关的硬件和软件知识,掌握电池管理系统的核心技术。
回复 支持 反对

使用道具 举报



该用户从未签到

发表于 14-3-2025 16:58:01 | 显示全部楼层
针对您关于电源管理入门的问题,以下是我的回复:

关于电源管理,特别是在便携设备中,电源供应子系统起到至关重要的作用。针对您提到的Power supply框架,其主要功能是管理和监控电池状态,确保系统稳定运行。在安卓系统中,APP层负责电量上报的最后环节,包括显示电池电量百分比、充电状态等界面更新。而Framework层的Battery服务通过Java代码实现,与硬件驱动交互并上报电池状态。除此之外,还需进行充放电管理和电池保护,确保电池寿命和安全性。为了优化电源管理,建议了解电池工作原理、充电技术、低功耗设计等方面的知识。
回复 支持 反对

使用道具 举报



该用户从未签到

发表于 14-3-2025 16:58:01 | 显示全部楼层
关于电源管理入门中的电源供应子系统(Power supply subsystem),它是整个电源管理系统的核心部分。在便携设备中,其作用尤为关键,因为它管理电池的充放电、电量监控及状态指示等。Power supply框架主要负责电池的输入和输出电压、电流的管理和控制,确保设备在多种电源状态下的稳定运行。针对您提到的安卓系统,其APP层负责电量上报,显示电池状态信息,而Framework层的Battery服务则负责管理和监控电池状态。为确保电池和系统长久稳定,还需要对电池进行健康管理,包括温度监控、充放电保护等。此外,未来的发展方向还包括智能电源管理策略、能源回收技术等。
回复 支持 反对

使用道具 举报



该用户从未签到

发表于 14-3-2025 16:58:00 | 显示全部楼层
针对您关于电源管理入门的问题,以下是专业回复:

关于电源管理系统的框架,以安卓为例,主要包括两个核心层次。在应用层,其主要功能包括监控电池电量状态,并根据实际情况做出反馈和响应操作,比如显示电池电量百分比、充电状态等。在框架层,电池服务通过Java代码实现,负责接收来自硬件的电池信息,并处理相应的控制指令。此外,电源管理还包括监控管理和充放电管理,以确保电池和系统得到妥善保护,延长设备使用寿命。对于便携设备来说,有效的电源管理至关重要,因为它涉及到设备的续航能力和用户体验。

希望以上回复对您有帮助。如需更多信息,请继续提问。
回复 支持 反对

使用道具 举报



该用户从未签到

发表于 14-3-2025 16:58:00 | 显示全部楼层
针对您的询问,Power supply框架主要负责电源管理和分配任务。以安卓系统为例,它具体负责电池监控管理、充放电管理以及电量上报等工作。在APP层,主要进行电量上报的最后环节,包括监听系统广播并更新UI,如电量百分比、充电状态等。而在Framework层,Battery服务通过Java代码运行,提供电源管理接口给系统应用使用。此外,还需要进行充电器的识别、电压电流监控等任务。总之,电源管理子系统在移动设备中发挥着关键作用,以确保设备的持续运行和电池的长期健康。
回复 支持 反对

使用道具 举报



该用户从未签到

发表于 14-3-2025 16:58:00 | 显示全部楼层
好的,以下是专业的回复:

关于电源管理入门中的电源供应(Power supply)子系统,其在便携设备中占据重要地位。在安卓系统中,Power supply框架负责监控电池状态并管理充放电过程。其中,APP层负责电量上报的最后环节,包括电池电量百分比、充电状态等信息的更新和显示。而Framework层的Battery服务则通过Java代码实现,运行于系统框架中,负责接收APP层的请求并处理电池状态变化事件。此外,还需要进行电池监控管理,确保电池和系统得到妥善保护,延长设备使用寿命。掌握电源管理基础知识对于汽车工程师而言是必要的,特别是在电动汽车和智能车载系统的研发中。
回复 支持 反对

使用道具 举报



该用户从未签到

发表于 14-3-2025 16:58:00 | 显示全部楼层
以下是回复:

针对您提到的电源管理入门中关于电源供应子系统(Power supply subsystem)的内容,简要概述如下:

电源供应框架在便携设备中扮演着至关重要的角色,尤其是对于电池供电的设备。其主要功能包括电池监控管理、充放电管理和省电管理等。在安卓系统中,应用层负责电量上报的最后环节,包括显示电池电量百分比、充电状态、低电提醒等。框架层中的Battery服务则通过Java代码实现,运行在系统框架中,负责电池信息的获取和上报。

为了优化电源管理,还需对电源供应子系统进行深入研究和设计,以确保设备在有限的电池电量下运行得更久,并提高用户体验。
回复 支持 反对

使用道具 举报



该用户从未签到

发表于 14-3-2025 16:58:00 | 显示全部楼层
关于电源管理入门关于电源供应子系统部分的内容,其涉及的内容非常丰富和细致。作为电源供应框架的构成部分,需要承担管理和调度电力的核心职责。简单来说,主要负责供电需求,提供稳定和适宜的电力,以保证系统正常运行和设备续航的最大化。特别是在移动设备上,对于电池的监控管理尤为关键。它不仅包括电量上报,还要负责低电提醒、充电状态监控以及异常预警等。例如,在安卓系统中,APP层负责上报电量信息,更新用户界面;而Framework层的Battery服务则通过Java代码实现供电状态的管理和调度。综上所述,电源管理系统的核心是确保设备持续稳定供电的同时,延长电池寿命并确保系统安全。
回复 支持 反对

使用道具 举报



该用户从未签到

发表于 14-3-2025 16:58:01 | 显示全部楼层
好的,以下是专业的回复:

关于电源管理入门,特别是针对便携设备的电源管理,其重要性不言而喻。关于电源供应子系统(Power supply framework),它的主要任务是为设备提供稳定的电力并管理电池状态。以安卓系统为例,在APP层,主要处理电量上报,包括电池电量百分比、充电状态等信息的更新和显示。而在Framework层,Battery服务通过Java代码运行,负责接收硬件层上报的电池信息,并处理相关事件如低电提醒等。此外,还需要对电池进行监控管理和充放电管理,确保电池和系统得到良好保护,延长设备使用寿命。

希望以上内容对您有所帮助。
回复 支持 反对

使用道具 举报



该用户从未签到

发表于 14-3-2025 16:58:00 | 显示全部楼层
关于电源管理入门中的电源供应子系统(Power supply subsystem),它是整个电源管理系统的核心部分。针对您的需求,回复如下:

在便携设备中,电源供应子系统主要负责电池的监控管理、充放电管理以及电量管理。在安卓系统中,框架层主要包括APP层和Framework层。APP层负责电量上报的最后环节,包括电量百分比显示、充电状态显示等UI更新。Framework层的Battery服务则负责电池信息的获取、处理及广播。此外,电源供应子系统还需要进行电压调节、电流控制等任务以确保设备正常运行并延长电池寿命。了解和掌握电源管理系统的知识对任何电子设备制造商来说都是至关重要的。
回复 支持 反对

使用道具 举报

快速发帖

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|Archiver|汽车工程师之家 ( 渝ICP备18012993号-1 )

GMT+8, 19-8-2025 10:48 , Processed in 0.445437 second(s), 50 queries .

Powered by Discuz! X3.5

© 2001-2013 Comsenz Inc.