我是靠谱客的博主 专一衬衫,最近开发中收集的这篇文章主要介绍04.“battery_thread“线程,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

 /kernel-4.14/drivers/power/supply/mediatek/battery/mtk_battery_core.c 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

struct mtk_battery gm;
void mtk_battery_init(struct platform_device *dev)
{
    gm.log_level = BM_DAEMON_DEFAULT_LOG_LEVEL;
    gm.d_log_level = BM_DAEMON_DEFAULT_LOG_LEVEL;
    ... ...
    init_waitqueue_head(&gm.wait_que);  //wait_queue_head_t  wait_que;
    ... ...
    gm.gdev = get_gauge_by_name("gauge");
    fg_custom_init_from_dts(dev);   //kernel-4.14/arch/arm64/boot/dts/mediatek/bat_setting/tb8168_battery_prop_ext.dtsi
    ... ...
    kthread_run(battery_update_routine, NULL, "battery_thread");
    
    fg_drv_thread_hrtimer_init();
    alarm_init(&gm.tracking_timer, ALARM_BOOTTIME, tracking_timer_callback);
    alarm_init(&gm.one_percent_timer, ALARM_BOOTTIME, one_percent_timer_callback);
    
    mtk_power_misc_init(dev);   //这又开了一个"power_misc_thread"线程,处理异常状态(温度过高、电量过低)(这个挺重要的,下回分解)

     ->kthread_run(power_misc_routine_thread, &sdc, "power_misc_thread");
    ... ...
}

 /kernel-4.14/drivers/power/supply/mediatek/battery/mtk_battery_core.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

int battery_update_routine(void *x)
{
        battery_update_psd(&battery_main);
        while (1) {
                wait_event(gm.wait_que,(gm.fg_update_flag > 0) || (gm.tracking_cb_flag > 0) || (gm.onepercent_cb_flag > 0));
                if (gm.fg_update_flag > 0) {
                        gm.fg_update_flag = 0;
                        fg_drv_update_hw_status();
                }
                if (gm.tracking_cb_flag > 0) {
                        bm_err("%s wake by tracking_cb_flag:%dn", __func__, gm.tracking_cb_flag);
                        gm.tracking_cb_flag = 0;
                        wakeup_fg_algo(FG_INTR_FG_TIME);
                }
                if (gm.onepercent_cb_flag > 0) {
                        bm_err("%s wake by onepercent_cb_flag:%dn", __func__, gm.onepercent_cb_flag);
                        gm.onepercent_cb_flag = 0;
                        wakeup_fg_algo_cmd(FG_INTR_FG_TIME, 0, 1);
                }
                if (gm.fix_coverity == 1)
                        return 0;
        }
}

void fg_update_routine_wakeup(void)
{
    gm.fg_update_flag = 1;
    wake_up(&gm.wait_que);
}

enum hrtimer_restart fg_drv_thread_hrtimer_func(struct hrtimer *timer)
{
    fg_update_routine_wakeup();

    return HRTIMER_NORESTART;
}

void fg_drv_thread_hrtimer_init(void)
{
    ktime_t ktime = ktime_set(10, 0);  //10s

    hrtimer_init(&gm.fg_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
    gm.fg_hrtimer.function = fg_drv_thread_hrtimer_func;
    hrtimer_start(&gm.fg_hrtimer, ktime, HRTIMER_MODE_REL);
}

 /kernel-4.14/drivers/power/supply/mediatek/battery/mtk_battery_core.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

/* ============================================================ */
/* periodic */
/* ============================================================ */
void fg_drv_update_hw_status(void)
{
    static bool fg_current_state;
    signed int chr_vol;
    int fg_current, fg_coulomb, bat_vol;
    int plugout_status, tmp, bat_plugout_time;
    int fg_current_iavg;
    bool valid = false;
    static unsigned int cnt;
    ktime_t ktime = ktime_set(60, 0);

    bm_debug("[%s]=>n", __func__);


    if (gauge_get_hw_version() >= GAUGE_HW_V1000 &&
    gauge_get_hw_version() < GAUGE_HW_V2000)
        fg_int_event(gm.gdev, EVB_PERIODIC_CHECK);

    fg_update_sw_iavg();

    gauge_dev_get_boot_battery_plug_out_status(
        gm.gdev, &plugout_status, &bat_plugout_time);

    fg_current_state = gauge_get_current(&fg_current);
    fg_coulomb = gauge_get_coulomb();
    bat_vol = pmic_get_battery_voltage();
    chr_vol = battery_get_vbus();
    tmp = force_get_tbat(true);

    bm_err("lbat %d %d %d %dn",
        gm.sw_low_battery_ht_en,
        gm.sw_low_battery_ht_threshold,
        gm.sw_low_battery_lt_en,
        gm.sw_low_battery_lt_threshold);

    bm_err("car[%d,%ld,%ld,%ld,%ld, cycle_car:%d,ncar:%d] c:%d %d vbat:%d vbus:%d soc:%d %d gm3:%d %d %d %dn",
        fg_coulomb, gm.coulomb_plus.end,
        gm.coulomb_minus.end, gm.soc_plus.end,
        gm.soc_minus.end,
        gm.bat_cycle_car, gm.bat_cycle_ncar,
        fg_current_state, fg_current, bat_vol, chr_vol,
        battery_get_soc(), battery_get_uisoc(),
        gm.disableGM30, fg_cust_data.disable_nafg,
        gm.ntc_disable_nafg, gm.cmd_disable_nafg);

    if (bat_get_debug_level() >= 7)
        gauge_coulomb_dump_list();

    fg_current_iavg = gauge_get_average_current(&valid);
    fg_nafg_monitor();

    bm_err("tmp:%d %d %d hcar2:%d lcar2:%d time:%d sw_iavg:%d %d %d nafg_m:%d %d %dn",
        tmp, gm.fg_bat_tmp_int_ht, gm.fg_bat_tmp_int_lt,
        gm.fg_bat_int2_ht, gm.fg_bat_int2_lt,
        fg_get_system_sec(), gm.sw_iavg, fg_current_iavg, valid,
        gm.last_nafg_cnt, gm.is_nafg_broken, gm.disable_nafg_int);

    if (cnt % 10 == 0)
        gauge_dev_dump(gm.gdev, NULL, 0);
    cnt++;

    gm3_log_dump(false);
    gm3_log_dump_nafg(1);

    wakeup_fg_algo_cmd(
        FG_INTR_KERNEL_CMD,
        FG_KERNEL_CMD_DUMP_REGULAR_LOG, 0);

    if (bat_get_debug_level() >= BMLOG_DEBUG_LEVEL)
        ktime = ktime_set(10, 0);
    else
        ktime = ktime_set(60, 0);

    hrtimer_start(&gm.fg_hrtimer, ktime, HRTIMER_MODE_REL);

}

gm.log_level在mtk_battery_init()被初始化为3,所以ktime被设置为60s

(我觉得这里逻辑有问题),因为log数字越小,等级越高,所以应该写成:

    if (bat_get_debug_level() < BMLOG_DEBUG_LEVEL)
        ktime = ktime_set(10, 0);  //log_level小于7,说明等级高,从而应该更频繁地打印log
    else
        ktime = ktime_set(60, 0);

 /kernel-4.14/drivers/power/supply/mediatek/battery/mtk_battery.c

1
2
3
4

int bat_get_debug_level(void)
{
    return gm.log_level;
}

 /kernel-4.14/drivers/power/supply/mediatek/battery/mtk_battery_internal.h

1
2
3
4
5
6
7
8
9
10
11

/* ============================================================ */
/* typedef and Struct*/
/* ============================================================ */
#define BMLOG_ERROR_LEVEL   3
#define BMLOG_WARNING_LEVEL 4
#define BMLOG_NOTICE_LEVEL  5
#define BMLOG_INFO_LEVEL    6
#define BMLOG_DEBUG_LEVEL   7
#define BMLOG_TRACE_LEVEL   8

#define BM_DAEMON_DEFAULT_LOG_LEVEL 3

另外,以下两个定时器也可以唤醒线程battery_update_routine:

  /kernel-4.14/drivers/power/supply/mediatek/battery/mtk_battery_core.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

/* ============================================================ */
/* alarm timer handler */
/* ============================================================ */
static enum alarmtimer_restart tracking_timer_callback(
    struct alarm *alarm, ktime_t now)
{
    gm.tracking_cb_flag = 1;
    wake_up(&gm.wait_que);
    return ALARMTIMER_NORESTART;
}

static enum alarmtimer_restart one_percent_timer_callback(
    struct alarm *alarm, ktime_t now)
{
    gm.onepercent_cb_flag = 1;
    wake_up(&gm.wait_que);
    return ALARMTIMER_NORESTART;
}

void bmd_ctrl_cmd_from_user(void *nl_data, struct fgd_nl_msg_t *ret_msg)
{
    ... ...
    case FG_DAEMON_CMD_SET_FG_TIME:
    {
        int secs;
        struct timespec time, time_now, end_time;
        ktime_t ktime;

        memcpy(&secs, &msg->fgd_data[0], sizeof(secs));

        if (secs != 0 && secs > 0) {
            get_monotonic_boottime(&time_now);
            time.tv_sec = secs;
            time.tv_nsec = 0;

            end_time = timespec_add(time_now, time);
            ktime = ktime_set(end_time.tv_sec, end_time.tv_nsec);

            if (msg->fgd_subcmd_para1 == 0)
                alarm_start(&gm.tracking_timer, ktime);
            else
                alarm_start(&gm.one_percent_timer, ktime);
        } else {
            if (msg->fgd_subcmd_para1 == 0)
                alarm_cancel(&gm.tracking_timer);
            else
                alarm_cancel(&gm.one_percent_timer);
        }

        bm_err("[fr] FG_DAEMON_CMD_SET_FG_TIME = %d cmd:%d %dn",
            secs,
            msg->fgd_subcmd, msg->fgd_subcmd_para1);
    }
    break;
    ... ...
}

最后

以上就是专一衬衫为你收集整理的04.“battery_thread“线程的全部内容,希望文章能够帮你解决04.“battery_thread“线程所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部