文章目錄
- 前言
- 一、PMU系統介紹
- 二、Zephyr系統下驅動PMU的組成
- 2.1:PMU系統在Zephyr上包括五大部分:
- 2.2:功能說明
- 2.3:B-core功能說明(Freertos)
- 三、PMU各驅動API詳解
- 3.1:Power_domain
- 3.1.1:初始化
- 3.1.2:rpmsg回調函數
- 3.2:regulate
- 3.2.1:電壓范圍設置
- 3.2.2:PMU芯片各路的使能與失能:
- 3.2.3:PMU芯片各路電壓的設置:
- 3.2.4:PMU芯片各路電壓的獲取:
- 3.3:charger
- 3.3.1:配置電池各參數
- 3.3.2:獲取當前充放電管理參數
- 3.3.3:初始化與通訊回調函數
- 3.4:fuel_gague驅動
- 3.4.1:獲取當前電池電量狀態與電壓
- 3.4.2:回調函數
- 總結
前言
電源管理系統是低功耗設備和芯片正常運行的基石,選擇合適的電源管理單元(PMU)芯片能夠顯著提高電量檢測精度和電源管理算法效率。本文介紹的PMU芯片包含2路DCDC和6路LDO,在Zephyr實時操作系統下實現了完整的電源管理解決方案。
一、PMU系統介紹
PMU(Power Management Unit)是專用于系統電源管理的集成電路,負責電壓調節、電池充電管理、電量監測等功能。本文所述的PMU芯片具有以下特性:
-
2路高效DCDC轉換器
-
6路低噪聲LDO穩壓器
-
集成電池充電管理
-
高精度電量計量功能
-
雙核通信架構(M-Core和B-Core)
二、Zephyr系統下驅動PMU的組成
2.1:PMU系統在Zephyr上包括五大部分:
-
Power_domain驅動 - 電源域管理
-
regulator驅動 - 電壓調節器控制
-
charger驅動 - 電池充電管理
-
fuel_gauge驅動 - 電量計量功能
-
soc驅動 - 芯片級系統集成
2.2:功能說明
Power_domain:
該驅動是用在確定小核(B-Core)初始化好pmu相關的rpmsg的端點,大核(M-Core)當接收到小核發來的初始化狀態即完成初始化。
regulator:
該驅動用來設置PMU芯片各路電源的電壓,具體實現是通過rpmsg發命令在B-Core實現的(pmu操作除剛開機的初始化操作在Main_Core上外,其他全部由B-Core操作)。
charger:
該驅動有兩個功能,一個功能把設備樹中的滿電電壓、終止充電電流等信息發送給B-Core,方便其初始化電池的充電信息。另一個功能是B-Core將vbus的拔插信息發送給M-Core,然后由M-Core上傳該信息。
fuel_gague:
該驅動主要是上傳電池的電量和電源信息到InPut子系統。
soc:
該驅動是芯片的主驅動,主要完成芯片相關的初始化配置。
2.3:B-core功能說明(Freertos)
具體操作邏輯如下:
- 初始化pmu相關的rpmasg端點
- 與M-Core確定雙方有關于rpmsg信息是否都準備好
- 接收M-Core所傳的pmu初始化相關的信息并初始化pmu
- 判斷電池狀態并上傳給M-Core
- normal模式下不斷檢測電流、電壓信息估算電量,低功耗模式下使用最低功耗估算電量
- 接收M-Core配置pmu信息
三、PMU各驅動API詳解
3.1:Power_domain
3.1.1:初始化
rpmsg_lite_mgr_create_ept(RPMSG_LITE_MGR_EPT_ADDR_M_Core_PMU, M_Core_rpmsg_pmu_cb, (void *)dev);while (!data->B_Core_pmu_init_flag) {k_sleep(K_MSEC(1));}
說明:
- M-Core創建與B-Core的雙核通訊節點,并設置回調函數
- 等待B-Core返回初始化成功標志位
3.1.2:rpmsg回調函數
static int Main_Core_rpmsg_pmu_cb(void *payload, uint32_t payload_len, uint32_t src, void *priv)
{data->c400_pmu_init_flag = true;rpmsg_lite_mgr_send(RPMSG_LITE_MGR_EPT_ADDR_Main_Core_PMU, RPMSG_LITE_MGR_EPT_ADDR_B_Core_PMU, (uint8_t *)&data- >B_Core_pmu_init_flag, sizeof(data->B_Core_pmu_init_flag));return 0;
}
說明:
- 觸發回調說明B-core初始化成功
- 再次返回ACK給B-core
3.2:regulate
3.2.1:電壓范圍設置
static const struct linear_range dcdc1_ranges[] = {LINEAR_RANGE_INIT(400000, 20000, 0, 48),
};static const struct linear_range dcdc2_ranges[] = {LINEAR_RANGE_INIT(840000, 20000, 0, 63),
};
說明:
- 由于PMU電源芯片,無法識別一些無限小數電壓和大數值電壓,因此做了限制
- 根據用戶輸入的配置電源,選擇一個合適且接近的電壓
3.2.2:PMU芯片各路的使能與失能:
static int pmu_enable/Disable(const struct device *dev)
{rpmsg_send_event_to_B_Core_regulator(config->id,PMU_REGULATOR_PMU_ENABLE, &config->id, sizeof(config->id));LOG_DBG("Regulator %d enabled", config->id);return 0;
}
說明:
- 發消息到B-core進行各路的開啟與關閉
3.2.3:PMU芯片各路電壓的設置:
static int pmu_set_voltage(const struct device *dev, int32_t min_uv, int32_t max_uv)
{if (ret == 0) {linear_range_get_value(config->desc->voltage_ranges, idx, &voltage_uv);voltage_mv = voltage_uv / 1000;rpmsg_send_event_to_B_Core_regulator(config->id, PMU_REGULATOR_SET_VOLTAGE, &voltage_mv, sizeof(voltage_mv));LOG_DBG("Regulator %d voltage set to %d uV", config->id, voltage_uv);} else {LOG_ERR("Failed to get voltage for regulator %d: %d", config->id, ret);}return ret;
}
說明:
- 獲取用戶輸入電壓,解析為一個數值接近且可配置的電壓
- 發送信息到B_Core設置各路的電壓信息
3.2.4:PMU芯片各路電壓的獲取:
static int pmu_get_voltage(const struct device *dev, int32_t *volt_uv)
{rpmsg_send_event_to_B_Core_regulator(config->id,PMU_REGULATOR_GET_VOLTAGE, NULL, 0);while (!data->voltage_get_flag) {k_sleep(K_MSEC(10));LOG_INF("Regulator %d get voltage wait", config->id);}data->voltage_get_flag = false;*volt_uv = data->current_uv;LOG_DBG("Regulator %d voltage is %d uV", config->id, data->current_uv);return 0;
}
說明:
- 直接發送請求信息到B-Core
- 在回調函數進行解析并設置Flag
3.3:charger
3.3.1:配置電池各參數
struct Main-core_charger_data {/** CHARGER_PROP_CONSTANT_CHARGE_CURRENT_UA - 恒流充電電流(微安) */uint32_t const_charge_current_ua;/** CHARGER_PROP_PRECHARGE_CURRENT_UA - 預充電電流(微安) */uint32_t precharge_current_ua;/** CHARGER_PROP_CHARGE_TERM_CURRENT_UA - 終止充電電流(微安) */uint32_t charge_term_current_ua;/** CHARGER_PROP_CONSTANT_CHARGE_VOLTAGE_UV - 恒壓充電電壓(微伏) */uint32_t const_charge_voltage_uv;/** CHARGER_PROP_LOW_VOLTAGE_UV - 低電壓(微伏) */uint32_t low_voltage_uv;/** CHARGER_PROP_STATUS - 充電狀態 */
};
說明:
- 從設備樹中獲取電池充放電管理參數
- 對充電時進行算法控制,涓流、恒壓等
3.3.2:獲取當前充放電管理參數
static int pmu_charger_get_prop(const struct device *dev, charger_prop_t prop,union charger_propval *val)
{switch(prop) {case CHARGER_PROP_ONLINE:break;case CHARGER_PROP_PRESENT:break;......break;default:return -ENOTSUP;}return 0;
}
說明
- 向用戶提供API獲取已經配置的各項參數
3.3.3:初始化與通訊回調函數
static int pmu_charger_init(const struct device *dev)
{k_work_init(&data->work, harger_work_handler);data->charger_status_notifier = charger_status_notifier;rpmsg_lite_mgr_create_ept(RPMSG_LITE_MGR_EPT_ADDR_Main_Core_CHARGER, Main_Core_thread_ipc_charger_cb, (void *)dev);return 0;
}
說明;
- 初始化并創建通訊節點
- 等待B-core發送接受參數命令
static int c500_thread_ipc_charger_cb(void *payload, uint32_t payload_len, uint32_t src, void *priv)
{switch (msg->cmd) {case PMU_CHARGE_INIT_INFO_GET:rpmsg_send_event_to_c400_charger(PMU_CHARGE_INIT_INFO_GET_ACK, (uint8_t *)&data->const_charge_current_ua, 20);break;case PMU_CHARGE_VBUS_STATUS:if (msg->payload[0] == CHARGER_STATUS_CHARGING) {LOG_INF("vbus in")} else {LOG_INF("vbus out")}break;rpmsg_send_event_to_c400_charger(PMU_CHARGE_INIT_STATUS_ACK, NULL, 0);break;default:break;}return 0;
}
說明:
- 回調函數中根據B-Core發送的命令進行操作
- 傳輸電池充放電管理信息
- 接受VBUS狀態與上報到INPUT子系統
3.4:fuel_gague驅動
3.4.1:獲取當前電池電量狀態與電壓
static int sl5803_get_prop()
{switch(prop){case FUEL_GAUGE_ABSOLUTE_STATE_OF_CHARGE:val->absolute_state_of_charge = data->battery_precent;break;case FUEL_GAUGE_VOLTAGE:pmu_send_event_to_B-Core_battery(PMU_BATTERY_VOLTAGE_GET, NULL, 0);k_sem_take(&data->fuel_gauge_sem, K_FOREVER);val->voltage = data->battery_voltage;break;default:break;}return 0;
}
- 提供用戶API獲取當前電池電量或電壓
3.4.2:回調函數
static int Main_Core_thread_ipc_battery_cb(void *payload, uint32_t payload_len, uint32_t src, void *priv)
{switch (msg->cmd) {case PMU_BATTERY_PERCENT_SET:k_work_submit(&data->work);}} else {data->battery_precent = 100;LOG_ERR("battery payload error: %d", msg->payload[0]);}break;case PMU_BATTERY_PERCENT_GET:pmu_send_event_to_B_core_battery(PMU_BATTERY_PERCENT_GET_ACK, (uint8_t *)&data->battery_precent, sizeof(data->battery_precent));break;case PMU_BATTERY_VOLTAGE_GET_ACK:data->battery_voltage = *(uint16_t *)&msg->payload[0] * 1000;k_sem_give(&data->fuel_gauge_sem);break;default:break;}return 0;
}
- 更新電量并上報INPUT系統
總結
本文詳細介紹了在Zephyr實時操作系統下PMU驅動的完整架構與實現方案。通過五大部分驅動的協同工作,實現了高效的電源管理功能。
該設計方案具有良好的可擴展性和可靠性,能夠滿足各種低功耗應用場景的需求,為產品提供穩定高效的電源管理解決方案。