ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

RT-Thread GPIO Charger 驱动详解:以 `rt_power_supply` 模型接入充电器状态与限流控制

RT-Thread GPIO Charger 驱动详解:以 `rt_power_supply` 模型接入充电器状态与限流控制 操作系统嵌入式物联网嵌入式OSRTOS【免费下载链接】rt-threadRT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/项目地址https://gitcode.com/gh_mirrors/rt/rt-thread点击查看免费下载RT-Thread 的电源管理框架将充电器Charger统一建模为rt_power_supply属性对象而不是单独的设备类别。本文以 components/drivers/power/supply/gpio-charger.c 的实现为线索完整讲解 GPIO 型充电器驱动的使能方式、注册流程、设备树配置、属性读写语义以及模拟器用法帮助读者在实际 BSP 中快速接入 USB/市电充电状态检测并实现充电电流档位切换。充电器即rt_power_supply不是独立类在 RT-Thread 电源管理框架中充电器Charger不是一个独立于电源供应类的设备类别。一个充电器就是一个struct rt_power_supply实例只是它的type被设为 USB/市电mains相关类型并通过ONLINE、STATUS、CONSTANT_CHARGE_CURRENT_MAX等属性对外暴露充电状态与能力。核心注册流程复用电源供应类见 supply.mdref page_device_power_supply。属性枚举定义在 power_supply.hcomponents/drivers/include/drivers/power_supply.h。GPIO 充电器的 Kconfig 开关为RT_POWER_SUPPLY_CHARGER_GPIO对应实现文件components/drivers/power/supply/gpio-charger.c。使能配置在 Kconfigcomponents/drivers/power/supply/Kconfig中GPIO 充电器开关的依赖条件如下config RT_POWER_SUPPLY_CHARGER_GPIO bool GPIO charger depends on RT_USING_POWER_SUPPLY depends on RT_USING_DM depends on RT_USING_OFW depends on RT_USING_PIN default y即启用它需要同时开启RT_USING_POWER_SUPPLY电源供应类基础框架自动选中RT_USING_ADT、RT_USING_ADT_REF、RT_USING_SYSTEM_WORKQUEUERT_USING_DM与RT_USING_OFW设备模型与 Open Firmware设备树解析支持RT_USING_PIN引脚驱动用于读取/输出 GPIO。充电器支持的type取值定义于enum rt_power_supply_type包括RT_POWER_SUPPLY_TYPE_UNKNOWN、BATTERY、UPS、MAINS、USB_SDP、USB_DCP、USB_CDP、USB_ACA、USB_TYPE_C、USB_PD、USB_PD_DRP、USB_PD_PPS、WIRELESS对应 USB 标准口SDP、专用充电口DCP、充电下行口CDP、配件充电适配器ACA等场景。注册流程gpio-charger驱动通过RT_PLATFORM_DRIVER_EXPORT(gpio_charger_driver)导出一个平台驱动绑定设备树compatible gpio-charger在probe阶段完成电源供应的注册。整体流程如下RT_PLATFORM_DRIVER_EXPORT(gpio_charger_driver) | v gpio_charger_probe(pdev) | -- rt_pin_get_named_pin (VBUS / status GPIOs) -- optional charge-current-limit GPIOs mapping table -- parse charger-type → psy-type -- build gpio_charger_properties[] (only supported props) -- psy-dev pdev-parent; psy-ops gpio_charger_ops -- rt_power_supply_register(gpioc-parent) -- GPIO IRQ → gpio_charger_isr → rt_power_supply_changed()对应源码components/drivers/power/supply/gpio-charger.c中的关键步骤gpio_charger_probe首先调用rt_calloc分配struct gpio_charger其内嵌struct rt_power_supply parent通过rt_pin_get_named_pin(dev, RT_NULL, ...)获取默认VBUSGPIO、通过rt_pin_get_named_pin(dev, charge-status, ...)获取充电状态 GPIO并把引脚的有效电平写入flags调用init_charge_current_limit解析charge-current-limit引脚与charge-current-limit-mapping映射表读取charger-type字符串并转换为psy-type枚举动态构建gpioc-gpio_charger_properties[]只有实际存在的硬件才会暴露对应属性详见下文填充parent.dev pdev-parent、parent.ops gpio_charger_ops后调用rt_power_supply_register(gpioc-parent)注册成功后为 VBUS 与charge-status两个引脚挂接上升沿中断中断服务函数gpio_charger_isr调用rt_power_supply_changed(gpioc-parent)通知框架刷新。平台驱动声明位于同一文件末尾static const struct rt_ofw_node_id gpio_charger_ofw_ids[] { { .compatible gpio-charger }, { /* sentinel */ } }; static struct rt_platform_driver gpio_charger_driver { .name gpio-charger, .ids gpio_charger_ofw_ids, .probe gpio_charger_probe, }; RT_PLATFORM_DRIVER_EXPORT(gpio_charger_driver);rt_power_supply_register的核心要求见 supply.c 的rt_power_supply_registerpsy-dev必填通常为pdev-parentpsy-ops、properties、properties_nr必须给出除非走battery_info静态电池描述路径psy-type需在注册前设置。注册成功后电源供应被插入全局链表若设备节点带ofw_node还会调用rt_dm_dev_bind_fwdata(psy-dev, NULL, psy)完成设备树数据绑定并初始化changed_work工作项。设备树配置典型示例以 gpio-charger.c 为参考的典型设备树节点如下charger { compatible gpio-charger; charger-type usb-dcp; gpios gpio0 12 GPIO_ACTIVE_HIGH; /* online */ charge-status-gpios gpio0 13 GPIO_ACTIVE_LOW; charge-current-limit-gpios gpio0 14, gpio0 15; charge-current-limit-mapping 100000 0, 500000 1, 1500000 3; };各属性含义与底层对应关系设备树属性用途对应源码逻辑compatible gpio-charger匹配平台驱动gpio_charger_ofw_idscharger-type指定充电器类型映射到psy-typert_dm_dev_prop_read_string 字符串比对gpiosVBUS/在线检测引脚ONLINE属性数据来源rt_pin_get_named_pin(dev, RT_NULL, ...)charge-status-gpios充电状态引脚STATUS属性数据来源rt_pin_get_named_pin(dev, charge-status, ...)charge-current-limit-gpios限流控制输出引脚可多个组成二进制码init_charge_current_limitcharge-current-limit-mapping限流值与 GPIO 编码的映射表成对出现电流、编码解析进current_limit_mapcharger-type的取值与psy-type的对应关系源码gpio_charger_probe中的分支unknown→RT_POWER_SUPPLY_TYPE_UNKNOWNbattery→RT_POWER_SUPPLY_TYPE_BATTERYups→RT_POWER_SUPPLY_TYPE_UPSmains→RT_POWER_SUPPLY_TYPE_MAINSusb-sdp→RT_POWER_SUPPLY_TYPE_USB_SDPusb-dcp→RT_POWER_SUPPLY_TYPE_USB_DCPusb-cdp→RT_POWER_SUPPLY_TYPE_USB_CDPusb-aca→RT_POWER_SUPPLY_TYPE_USB_ACA其余未识别字符串 →RT_POWER_SUPPLY_TYPE_UNKNOWN实际暴露哪些属性取决于设备树中给出了哪些 GPIO/映射——驱动在probe中动态构建properties[]数组gpios存在则加入ONLINEcharge-status-gpios存在则加入STATUScharge-current-limit-mapping解析成功则加入CONSTANT_CHARGE_CURRENT_MAX。属性数组上限为 3struct gpio_charger中的enum rt_power_supply_property gpio_charger_properties[3]。get_property/set_property语义充电器对外提供三个核心属性的读写行为属性行为ONLINE读取 VBUS GPIO与flags配置的有效电平比对返回是否在线STATUS读取charge-statusGPIO与flags比对返回CHARGING或NOT_CHARGINGCONSTANT_CHARGE_CURRENT_MAX依据映射表 限流 GPIO 计算set_property根据传入电流值选择限流档位读取实现gpio_charger_get_propertycase RT_POWER_SUPPLY_PROP_ONLINE: rt_pin_mode(gpioc-gpiod.pin, PIN_MODE_INPUT); val-intval rt_pin_read(gpioc-gpiod.pin) gpioc-gpiod.flags; break; case RT_POWER_SUPPLY_PROP_STATUS: rt_pin_mode(gpioc-charge_status.pin, PIN_MODE_INPUT); if (rt_pin_read(gpioc-charge_status.pin) gpioc-charge_status.flags) { val-intval RT_POWER_SUPPLY_STATUS_CHARGING; } else { val-intval RT_POWER_SUPPLY_STATUS_NOT_CHARGING; } break; case RT_POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: val-intval gpioc-charge_current_limit; break;ONLINE与STATUS每次读取都会先把引脚配置为输入模式再读取电平保证状态实时性对应 supply.md 中“Stale SOC cache在get_property中重新读取硬件”的实践。CONSTANT_CHARGE_CURRENT_MAX返回驱动当前保存的charge_current_limit单位 µA该值由set_charge_current_limit写入。未支持的属性返回-RT_ENOSYS。写入实现gpio_charger_set_propertyset_property仅支持CONSTANT_CHARGE_CURRENT_MAX其余属性返回-EINVALcase RT_POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: return set_charge_current_limit(gpioc, val-intval);限流映射与档位选择set_charge_current_limitfor (i 0; i gpioc-current_limit_map_size; i) { if (gpioc-current_limit_map[i].limit_ua val) { break; } } mapping gpioc-current_limit_map[i]; for (i 0; i gpioc-current_limit_gpios_nr; i) { rt_bool_t val (mapping.gpiodata i) 1; struct gpio_desc *gpio gpios[gpioc-current_limit_gpios_nr - i - 1]; rt_pin_mode(gpio-pin, PIN_MODE_OUTPUT); rt_pin_write(gpio-pin, val ? gpio-flags : !gpio-flags); } gpioc-charge_current_limit mapping.limit_ua;要点映射表项struct gpio_mapping由limit_ua限流值与gpiodataGPIO 二进制编码组成解析自设备树charge-current-limit-mapping每两个 u32 为一组。驱动按电流值从小到大扫描映射表选择第一个limit_ua val的档位因此映射表必须按限流值单调不减排列否则init_charge_current_limit返回-RT_EINVAL。多根限流 GPIO 按从低位到高位组合成编码gpiodata的第i位对应charge-current-limit-gpios列表中的倒数第i1根引脚。输出引脚时编码位为 1 则写gpio-flags如GPIO_ACTIVE_HIGH时为高电平为 0 则写!gpio-flags。安全默认值init_charge_current_limit解析成功后默认调用set_charge_current_limit(gpioc, 最小档位电流)——即默认取映射表中最小限流值从源码注释看这是出于安全考虑/* Default to smallest current limitation for safety reasons */避免上电瞬间以最大电流充电。属性校验rt_power_supply_get_property只有在prop出现在psy-properties[]中时才回调ops-get_property否则走battery_info静态属性路径两者都不满足则返回-RT_ENOSYS见 supply.c 的power_supply_have_property与rt_power_supply_get_property。因此设备树中缺失某组 GPIO 时对应属性虽然不在properties[]中但get_property会直接失败不会产生未定义行为。状态变化通知GPIO 中断 →rt_power_supply_changed当 VBUS 插入/拔出或充电状态跳变时GPIO 上升沿触发中断static void gpio_charger_isr(void *args) { struct gpio_charger *gpioc args; rt_power_supply_changed(gpioc-parent); }rt_power_supply_changed只是提交一个工作项rt_work_submit(psy-changed_work, 0)见 supply.c。工作函数power_supply_changed_work依次完成若psy-led_dev已绑定且开启RT_USING_LED更新 LED 指示电池类按STATUS调亮度非电池类按ONLINE亮灭遍历并回调所有rt_power_supply_notifier注册的回调。因此应用侧可以通过rt_power_supply_notifier_register注册监听回调例如在充电器上线时调整系统运行模式。若开启RT_POWER_SUPPLY_DAEMON默认y内置守护通知器会依据电量/电压在低电量时请求 PM 睡眠模式或直接关机见 supply-daemon.c 的daemon_power_supply_notify。注意rt_power_supply_changed从 ISR 调用是安全的但不要在 ISR 中直接调用get_propertyGPIO 型虽不阻塞通用电量计可能走 I2C应将读操作推迟到工作队列。模拟器emu-power.c与emu_charger命令在没有真实硬件时可以启用RT_POWER_SUPPLY_EMU使用电源模拟器实现见 emu-power.c。它的依赖条件Kconfigconfig RT_POWER_SUPPLY_EMU bool Emulator battery(thermal)/charger depends on RT_USING_POWER_SUPPLY depends on RT_USING_PM depends on RT_USING_CONSOLE depends on RT_USING_MSH depends on RT_USING_CPU_USAGE_TRACER default n模拟器在emu_power_initINIT_DEVICE_EXPORT中注册一个模拟电池rt_power_supplyRT_POWER_SUPPLY_TYPE_BATTERY暴露STATUS、HEALTH、PRESENT、TECHNOLOGY、CAPACITY、VOLTAGE_NOW、TEMP、CHARGE_COUNTER、CURRENT_NOW、CURRENT_AVG、CHARGE_FULL、CYCLE_COUNT、SCOPE等属性并附带battery_info静态描述如 3000mWh/3000mAh、3.0V~4.2V、恒流 2000mA、温度区间 -10°C~40°C 等注册一个模拟充电器rt_power_supplyRT_POWER_SUPPLY_TYPE_USB_SDP暴露ONLINE、VOLTAGE_MAX、CURRENT_MAX启动一个 3 秒周期的rt_timer定时器emu_power_poll根据 CPU 负载rt_cpu_self()-cpu_stat与ac_online状态模拟充放电曲线——接入电源时按快充80%、正常95%、涓流≥95%三档步进充电断开时按 CPU 平均负载放电同时更新电压、电流与温度并调用rt_power_supply_changed通知电池与充电器。MSH 控制命令emu_charger用于切换充电器开关状态供 thermal/PM 相关测试使用Usage: emu_charger [on|off]emu_charger onac_online 1状态置为CHARGINGcurrent_max恢复为恒流上限2000mAemu_charger offac_online 0状态置为DISCHARGINGcurrent_max清零。配合RT_POWER_SUPPLY_DAEMON与RT_USING_PM可借此在无硬件环境下验证“低电量 → 请求睡眠/降频 → 临界电量关机”等整条电源管理链路。此外开启 MSH 后还可使用power_supply命令族见 supply_cmd.c查看系统中所有电源供应的实时属性power_supply list power_supply show name power_supply get name property例如对 GPIO 充电器可执行power_supply get charger-name online、power_supply get charger-name status、power_supply get charger-name constant_charge_current_max属性名定义于 supply_cmd.c 的属性描述表数值单位分别为无单位、无单位、µA。消费侧读取示例其他设备如 PM 组件、应用线程可通过rt_power_supply_get按设备树 phandle 或设备名查找电源供应再读取属性struct rt_power_supply *psy rt_power_supply_get(consumer_dev, power-supply); if (rt_is_err(psy)) ... rt_power_supply_get_property(psy, RT_POWER_SUPPLY_PROP_ONLINE, val); rt_power_supply_put(psy);其中id是消费设备设备树上的phandle 属性名如power-supply charger→power-supply。get之后务必put释放引用计数否则rt_power_supply_unregister会因引用计数 1 返回-RT_EBUSY见 supply.c 的rt_power_supply_unregister。参考与延伸阅读supply.md电源供应类整体架构与通用注册流程ref page_device_power_supplypower.md电源管理栈总览gpio-charger.c本文核心驱动实现supply.crt_power_supply_register/ 属性访问 / 通知机制power_supply.h类型、状态与属性枚举定义KconfigRT_POWER_SUPPLY_CHARGER_GPIO、RT_POWER_SUPPLY_EMU等开关emu-power.c模拟电池/充电器实现supply_cmd.cpower_supplyMSH 命令实现赞分享操作系统嵌入式物联网嵌入式OSRTOS【免费下载链接】rt-threadRT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/项目地址https://gitcode.com/gh_mirrors/rt/rt-thread点击查看免费下载相关推荐RT-Thread SDIO/MMC 设备模型DM基于 Device Model 的宿主控制器驱动框架详解RT Thread SDIO/MMC 设备模型DM基于 Device Model 的宿主控制器驱动框架详解 RT Thread 的 SDIO/MMC 设备操作系统嵌入式物联网嵌入式OSRTOSRT-Thread 冷却设备Cooling Devices驱动详解PWM 风扇、GPIO 风扇与 DVFS 降温RT Thread 冷却设备Cooling Devices驱动详解PWM 风扇、GPIO 风扇与 DVFS 降温 本文以 RT Thread 仓库中 co操作系统嵌入式物联网嵌入式OSRTOSRT-Thread 板级关机与重启DM 电源回调机制、GPIO/SYSCON 驱动与 Reboot Mode 实战解析RT Thread 板级关机与重启DM 电源回调机制、GPIO/SYSCON 驱动与 Reboot Mode 实战解析 RT Thread 的设备驱动模型D操作系统嵌入式物联网嵌入式OSRTOS创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表