[单片机框架][device层] charger 电源管理
通过 DEVICE_INITCALL(“dev-chg”, charger_dev_init); 注册驱动,自动在main初始化中运行。
优点:耦合少,可移植性强,适用大团队模块化开发
缺点:抽象度高,小团队开发时间耗时久
-
CPU在运行时根据系统负载进行动态电压和频率变换的CPUFreq
-
CPU在系统空闲时根据空闲的情况进行低功耗模式的CPUIdle
-
多核系统下CPU的热插拔支持
-
系统和设备对于延迟的特别需求而提出申请的PM QoS,它会作用于CPUIdle的具体策略
-
设备驱动针对系统Suspend to RAM/Disk的一系列入口函数
-
SoC进入suspend状态、SDRAM自刷新的入口
-
设备的runtime(运行时)动态电源管理,根据使用情况动态开关设备
-
底层的时钟、稳压器、频率/电压表(OPP模块完成)支撑,各驱动子系统都可能用到
模拟linux的电源管理
APP层使用方法:app – power – power_charger.c
#include "charger_dev.h"
#include "charger.h"
#include "power_charger.h"
static device_t* g_charger_dev = NULL;
int32_t charger_init(void){
int32_t ret;
g_charger_dev = device_find("dev-chg");
if (g_charger_dev == NULL) {
POWER_CHARGER_LOG_E("[power][charger]:device_find fail\r\n");
return RETVAL(E_NULL);
}
ret = device_open(g_charger_dev, DEVICE_OFLAG_RDWR);
if (ret != RETVAL(E_OK))
POWER_CHARGER_LOG_E("[power][charger]:device_open fail\r\n");
return ret;
}
int32_t charger_enable(uint32_t enable) {
int32_t ret;
charger_property_t prop;
prop.charger_prop = CHARGER_ENABLE_CHARGING;
prop.val = enable;
ret = device_ioctl(g_charger_dev, CHARGER_DEV_SET_PROPERTY, &prop);
if (ret != RETVAL(E_OK))
POWER_CHARGER_LOG_E("[power][charger]:charger_enable fail\r\n");
return ret;
}
int32_t charger_set_current(uint32_t current) {
int32_t ret;
charger_property_t prop;
prop.charger_prop = CHARGER_SET_CHARGE_CURRENT;
prop.val = current;
ret = device_ioctl(g_charger_dev, CHARGER_DEV_SET_PROPERTY, &prop);
if (ret != RETVAL(E_OK))
POWER_CHARGER_LOG_E("[power][charger]:set_current fail\r\n");
return ret;
}
int32_t charger_set_voltage(uint32_t voltage) {
int32_t ret;
charger_property_t prop;
prop.charger_prop = CHARGER_SET_CHARGE_VOLTAGE;
prop.val = voltage;
ret = device_ioctl(g_charger_dev, CHARGER_DEV_SET_PROPERTY, &prop);
if (ret != RETVAL(E_OK))
POWER_CHARGER_LOG_E("[power][charger]:set_voltage fail\r\n");
return ret;
}
int32_t charger_set_terminal_current(uint32_t current) {
int32_t ret;
charger_property_t prop;
prop.charger_prop = CHARGER_SET_TERMINAL_CURRENT;
prop.val = current;
ret = device_ioctl(g_charger_dev, CHARGER_DEV_SET_PROPERTY, &prop);
if (ret != RETVAL(E_OK))
POWER_CHARGER_LOG_E("[power][charger]:set_terminal_current fail\r\n");
return ret;
}
int32_t charger_set_watchdog(uint32_t value) {
int32_t ret;
charger_property_t prop;
prop.charger_prop = CHARGER_SET_FEEDING_WATCHDOG;
prop.val = value;
ret = device_ioctl(g_charger_dev, CHARGER_DEV_SET_PROPERTY, &prop);
if (ret != RETVAL(E_OK))
POWER_CHARGER_LOG_E("[power][charger]:feeding watchdog fail\r\n");
return ret;
}
int32_t charger_get_vbus_status(uint32_t* status) {
int32_t ret;
charger_property_t prop;
prop.charger_prop = CHARGER_GET_VBUS_STATUS;
ret = device_ioctl(g_charger_dev, CHARGER_DEV_GET_PROPERTY, &prop);
if (ret != RETVAL(E_OK))
POWER_CHARGER_LOG_E("[power][charger]:get_vbus_status fail\r\n");
*status = prop.val;
return ret;
}
int32_t charger_get_usb_status(void) {
int32_t ret;
charger_property_t prop;
prop.charger_prop = CHARGER_GET_USB_STATUS;
ret = device_ioctl(g_charger_dev, CHARGER_DEV_GET_PROPERTY, &prop);
if (ret != RETVAL(E_OK))
POWER_CHARGER_LOG_E("[power][charger]:get_usb_status fail\r\n");
return ret;
}
int32_t charger_get_charger_status(uint32_t* status) {
int32_t ret;
charger_property_t prop;
prop.charger_prop = CHARGER_GET_CHARGE_STATUS;
ret = device_ioctl(g_charger_dev, CHARGER_DEV_GET_PROPERTY, &prop);
if (ret != RETVAL(E_OK))
POWER_CHARGER_LOG_E("[power][charger]:get_charger_status fail\r\n");
*status = prop.val;
return ret;
}
int32_t charger_register_callback(charger_event_cb_t cb) {
int32_t ret;
ret = device_ioctl(g_charger_dev, CHARGER_DEV_SET_CALLBACK, cb);
if (ret != RETVAL(E_OK))
POWER_CHARGER_LOG_E("[power][charger]:register_callback fail\r\n");
return ret;
}
驱动初始化代码:
#include "typedefs.h"
#include "log.h"
#include "modules.h"
extern initcall_t __initcall_start;
extern initcall_t __initcall_end;
void modules_setup(void)
{
initcall_t *call;
for (call = &__initcall_start; call < &__initcall_end; call++)
{
// LOG_C("[modules]:%s init\r\n", call->name);
call->initcall();
}
}
/**
* @brief Main function.
*/
int main(void) {
hardware_init();
modules_setup(); // 将驱动、设备、app层依次初始化
LOG_C("[main]:kernel start...\r\n");
start_kernel();
while (1) {
}
}
驱动代码:
#include <string.h>
#include "typedefs.h"
#include "errorno.h"
#include "modules.h"
#include "log.h"
#include "charger_dev.h"
static char* charger_drv_match_ids[] = {
"bq25601",
};
static int32_t charger_dev_open(device_t *dev)
{
uint8_t i = 0;
charger_driver_t *pdrv_charger;
if (dev == NULL)
{
return RETVAL(E_NULL);
}
if (dev->dev_drv != NULL)
{
return RETVAL(E_OK);
}
for (i=0; i<ARRAY_SIZE(charger_drv_match_ids); i++)
{
pdrv_charger = charger_driver_find(charger_drv_match_ids[i]);
if (pdrv_charger)
{
if (charger_driver_probe(pdrv_charger) == RETVAL(E_OK))
{
dev->dev_drv = (void*)pdrv_charger;
charger_driver_init(pdrv_charger);
return RETVAL(E_OK);
}
}
}
return RETVAL(E_FAIL);
}
static xssize_t charger_dev_read(device_t *dev, char *buffer, xsize_t size, xloff_t *pos)
{
xssize_t ret = 0;
ret = charger_driver_read_data((charger_driver_t*)dev->dev_drv, (charger_data_t*)buffer);
if (ret != RETVAL(E_OK))
{
LOG_E("[charger_dev][charger_dev_read] charger dev read data failed!!!\r\n");
}
return ret;
}
static xssize_t charger_dev_write(device_t *dev, const char *buffer, xsize_t size, xloff_t *pos)
{
xssize_t ret = 0;
ret = charger_driver_write_data((charger_driver_t*)dev->dev_drv, (charger_data_t*)buffer);
if (ret != RETVAL(E_OK))
{
LOG_E("[charger_dev][charger_dev_write] charger dev read write failed!!!\r\n");
}
return ret;
}
static int32_t charger_dev_ioctl(device_t *dev, uint32_t cmd, void *args)
{
switch (cmd)
{
case CHARGER_DEV_GET_PROPERTY:
return charger_driver_get_property((charger_driver_t*)dev->dev_drv, args);
case CHARGER_DEV_SET_PROPERTY:
return charger_driver_set_property((charger_driver_t*)dev->dev_drv, args);
case CHARGER_DEV_SET_CALLBACK:
return charger_driver_set_callback((charger_driver_t*)dev->dev_drv, args);
default:
break;
}
return RETVAL(E_OK);
}
const device_ops_t charger_dev_ops =
{
/* (*open) */ charger_dev_open,
/* (*close) */ NULL,
/* (*read) */ charger_dev_read,
/* (*write) */ charger_dev_write,
/* (*ioctl) */ charger_dev_ioctl,
};
static void charger_dev_init(void)
{
static device_t charger_dev;
int32_t ret;
memset(&charger_dev, 0, sizeof(device_t));
charger_dev.type = DEVICE_CLASS_CHAR;
charger_dev.dev_ops = &charger_dev_ops;
ret = device_register(&charger_dev, "dev-chg", DEVICE_FLAG_WRONLY);
if (ret < 0)
{
LOG_E("[charger_dev][init]:register failed ret=%d\r\n", ret);
}
}
DEVICE_INITCALL("dev-chg", charger_dev_init);
#ifndef _CHARGER_DEV_H_
#define _CHARGER_DEV_H_
#include "../../object/device.h"
#include "charger.h"
#endif // _CHARGER_DEV_H_