【Zephyr电源与功耗专题】13_PMU电源驱动介绍

文章目录

  • 前言
  • 一、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驱动的完整架构与实现方案。通过五大部分驱动的协同工作,实现了高效的电源管理功能。
该设计方案具有良好的可扩展性和可靠性,能够满足各种低功耗应用场景的需求,为产品提供稳定高效的电源管理解决方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/96768.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/96768.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华清远见25072班网络编程学习day5

作业0> 将IO多路复用实现TCP并发服务器实现一遍程序源码&#xff1a;#include <25072head.h> #define SER_IP "192.168.153.128" //服务器ip地址 #define SER_PORT 8888 //服务器端口号 int main(int argc, const char *argv[]) {//1、创建一个…

【数据结构--顺序表】

顺序表和链表 1.线性表&#xff1a; 线性表是n个具有相同特性&#xff08;相同逻辑结构&#xff0c;物理结构&#xff09;的数据元素的有限序列。常见的线性表有&#xff1a;顺序表&#xff0c;链表&#xff0c;栈&#xff0c;队列&#xff0c;字符串…线性表在逻辑上是线性结构…

【PyTorch】图像多分类部署

如果需要在独立于训练脚本的新脚本中部署模型&#xff0c;这种情况模型和权重在内存中不存在&#xff0c;因此需要构造一个模型类的对象&#xff0c;然后将存储的权重加载到模型中。加载模型参数&#xff0c;验证模型的性能&#xff0c;并在测试数据集上部署模型from torch imp…

FS950R08A6P2B 双通道汽车级IGBT模块Infineon英飞凌 电子元器件核心解析

一、核心解析&#xff1a;FS950R08A6P2B 是什么&#xff1f;1. 电子元器件类型FS950R08A6P2B 是英飞凌&#xff08;Infineon&#xff09; 推出的一款 950A/800V 双通道汽车级IGBT模块&#xff0c;属于功率半导体模块。它采用 EasyPACK 2B 封装&#xff0c;集成多个IGBT芯片和二…

【系列文章】Linux中的并发与竞争[05]-互斥量

【系列文章】Linux中的并发与竞争[05]-互斥量 该文章为系列文章&#xff1a;Linux中的并发与竞争中的第5篇 该系列的导航页连接&#xff1a; 【系列文章】Linux中的并发与竞争-导航页 文章目录【系列文章】Linux中的并发与竞争[05]-互斥量一、互斥锁二、实验程序的编写2.1驱动…

TensorRT 10.13.3: Limitations

Limitations Shuffle-op can not be transformed to no-op for perf improvement in some cases. For the NCHW32 format, TensorRT takes the third-to-last dimension as the channel dimension. When a Shuffle-op is added like [N, ‘C’, H, 1] -> [‘N’, C, H], the…

Python与Go结合

Python与Go结合的方法Python和Go可以通过多种方式结合使用&#xff0c;通常采用跨语言通信或集成的方式。以下是几种常见的方法&#xff1a;使用CFFI或CGO进行绑定Python可以通过CFFI&#xff08;C Foreign Function Interface&#xff09;调用Go编写的库&#xff0c;而Go可以通…

C++ 在 Visual Studio Release 模式下,调试运行与直接运行 EXE 的区别

前言 在 Visual Studio (以下简称 VS) 中开发 C 项目时&#xff0c;我们常常需要在 Debug 和 Release 两种构建模式之间切换。Debug 模式适合开发和调试&#xff0c;而 Release 模式则针对生产环境&#xff0c;进行代码优化以提升性能。然而&#xff0c;即使在 Release 模式下&…

南京方言数据集|300小时高质量自然对话音频|专业录音棚采集|方言语音识别模型训练|情感计算研究|方言保护文化遗产数字化|语音情感识别|方言对话系统开发

引言与背景 随着人工智能技术的快速发展&#xff0c;语音识别和自然语言处理领域对高质量方言数据的需求日益增长。南京方言作为江淮官话的重要分支&#xff0c;承载着丰富的地域文化和语言特色&#xff0c;在语言学研究和方言保护方面具有重要价值。本数据集精心采集了300小时…

基于LSTM深度学习的电动汽车电池荷电状态(SOC)预测

基于LSTM深度学习的电动汽车电池荷电状态&#xff08;SOC&#xff09;预测 摘要 电动汽车&#xff08;EV&#xff09;的普及对电池管理系统&#xff08;BMS&#xff09;提出了极高的要求。电池荷电状态&#xff08;State of Charge, SOC&#xff09;作为BMS最核心的参数之一&am…

Golang语言之数组、切片与子切片

一、数组先记住数组的核心特点&#xff1a;盒子大小一旦定了就改不了&#xff08;长度固定&#xff09;&#xff0c;但盒子里的东西能换&#xff08;元素值可变&#xff09;。就像你买了个能装 3 个苹果的铁皮盒&#xff0c;想多装 1 个都不行&#xff0c;但里面的苹果可以换成…

速通ACM省铜第四天 赋源码(G-C-D, Unlucky!)

目录 引言&#xff1a; G-C-D, Unlucky! 题意分析 逻辑梳理 代码实现 结语&#xff1a; 引言&#xff1a; 因为今天打了个ICPC网络赛&#xff0c;导致坐牢了一下午&#xff0c;没什么时间打题目了&#xff0c;就打了一道题&#xff0c;所以&#xff0c;今天我们就只讲一题了&…

数据链路层总结

目录 &#xff08;一&#xff09;以太网&#xff08;IEEE 802.3&#xff09; &#xff08;1&#xff09;以太网的帧格式 &#xff08;2&#xff09;帧协议类型字段 ①ARP协议 &#xff08;横跨网络层和数据链路层的协议&#xff09; ②RARP协议 &#xff08;二&#xff…

Scala 新手实战三案例:从循环到条件,搞定基础编程场景

Scala 新手实战三案例&#xff1a;从循环到条件&#xff0c;搞定基础编程场景 对 Scala 新手来说&#xff0c;单纯记语法容易 “学完就忘”&#xff0c;而通过小而精的实战案例巩固知识点&#xff0c;是掌握语言的关键。本文精选三个高频基础场景 ——9 乘 9 乘法口诀表、成绩等…

java学习笔记----标识符与变量

1.什么是标识符?Java中变量、方法、类等要素命名时使用的字符序列&#xff0c;称为标识符。 技巧:凡是自己可以起名字的地方都叫标识符。 比如:类名、方法名、变量名、包名、常量名等 2.标识符的命名规则由26个英文字母大小写&#xff0c;0-9&#xff0c;或$组成 数字不可以开…

AI产品经理面试宝典第93天:Embedding技术选型与场景化应用指南

1. Embedding技术演进全景解析 1.1 稀疏向量:关键词匹配的基石 1.1.1 问:请说明稀疏向量的适用场景及技术特点 答:稀疏向量适用于关键词精确匹配场景,典型实现包括TF-IDF、BM25和SPLADE。其技术特征表现为50,000+高维向量且95%以上位置为零值,通过余弦或点积计算相似度…

【Mermaid.js】从入门到精通:完美处理节点中的空格、括号和特殊字符

文章标签&#xff1a; Mermaid, Markdown, 前端开发, 数据可视化, 流程图 文章摘要&#xff1a; 你是否在使用 Mermaid.js 绘制流程图时&#xff0c;仅仅因为节点文本里加了一个空格或括号&#xff0c;整个图就渲染失败了&#xff1f;别担心&#xff0c;这几乎是每个 Mermaid 新…

多技术融合提升环境生态水文、土地土壤、农业大气等领域的数据分析与项目科研水平

一&#xff1a;空间数据获取与制图1.1 软件安装与应用1.2 空间数据介绍1.3海量空间数据下载1.4 ArcGIS软件快速入门1.5 Geodatabase地理数据库二&#xff1a;ArcGIS专题地图制作2.1专题地图制作规范2.2 空间数据的准备与处理2.3 空间数据可视化&#xff1a;地图符号与注记2.4 研…

【音视频】Android NDK 与.so库适配

一、名词解析 名词全称核心说明Android NDKNative Development Kit在SDK基础上增加“原生”开发能力&#xff0c;支持使用C/C编写代码&#xff0c;用于开发需要调用底层能力的模块&#xff08;如音视频、加密算法等&#xff09;.so库Shared Object即共享库&#xff0c;由NDK编…

SpringBoot 轻量级一站式日志可视化与JVM监控

一、项目初衷Java 应用开发的同学都知道&#xff0c;项目上线后&#xff0c;日志的可视化查询与 JVM 的可视化监控是一件非常重要的事。 市面上成熟方案一般是采用 ELK/EFK 实现日志可视化&#xff0c;采用 Actuator Prometheus Grafana 实现 JVM 监控。 这两套都是非常优秀的…