PMU HAL 接口文档#
概述#
K230 提供了 PMU HAL 接口,用于在系统运行态处理中长按关机流程,以及配置 RTC 定时关机/定时开机。
用户态 HAL 头文件:
src/rtsmart/libs/rtsmart_hal/drivers/pmu/drv_pmu.h用户态 HAL 实现:
src/rtsmart/libs/rtsmart_hal/drivers/pmu/drv_pmu.c参考示例:
src/rtsmart/examples/peripheral/pmu/test_pmu.c
PMU HAL 当前主要覆盖两类能力:
长按电源键关机通知与用户态 ACK
RTC 定时关机、定时开机(power cycle)
注意:RTC 普通读写时间、普通 alarm/tick 中断配置属于 RTC 设备接口能力,不在
drv_pmu.h这个 HAL 头文件内。
事件模型#
长按关机流程由内核驱动和用户态 HAL 协同完成:
用户态调用
drv_pmu_register_notify()注册信号通知用户长按电源键达到阈值后,驱动上报
DRV_PMU_EVENT_LONG_PRESS用户态完成保存状态、卸载文件系统等清理动作
用户松开电源键后,驱动上报
DRV_PMU_EVENT_KEY_RELEASE用户态调用
drv_pmu_ack_shutdown()发送 ACK驱动收到 ACK 后执行真正关机
如果用户态不发送 ACK,则系统会保持当前运行状态,不会自动关机。
数据结构说明#
drv_pmu_inst_t#
描述:PMU HAL 实例句柄,内部封装了 /dev/pmu_pwrkey 设备节点、信号等待集和通知注册状态。该类型对用户透明。
drv_pmu_event_t#
描述:PMU 事件位图类型。
DRV_PMU_EVENT_LONG_PRESS#
描述:检测到长按关机事件。
DRV_PMU_EVENT_KEY_RELEASE#
描述:长按之后检测到电源键松开事件。
函数接口说明#
int drv_pmu_inst_create(drv_pmu_inst_t **inst);#
功能:创建 PMU HAL 实例并打开 /dev/pmu_pwrkey。
参数:
inst:返回创建好的 PMU 实例
返回值:
0:成功-1:失败
void drv_pmu_inst_destroy(drv_pmu_inst_t **inst);#
功能:销毁 PMU HAL 实例,自动注销通知并关闭设备。
参数:
inst:PMU 实例指针的指针
int drv_pmu_register_notify(drv_pmu_inst_t *inst, int signo);#
功能:注册 PMU 事件通知。
注册成功后,驱动会向当前进程发送指定信号,用户态可通过 drv_pmu_wait_event() 等待并读取事件。
参数:
inst:PMU 实例signo:通知信号编号;小于等于0时默认使用SIGUSR1
返回值:
0:成功-1:失败
说明:
HAL 内部会自动阻塞该信号,并在销毁或注销时恢复
重复调用会先注销旧通知,再重新注册
int drv_pmu_unregister_notify(drv_pmu_inst_t *inst);#
功能:注销 PMU 事件通知。
参数:
inst:PMU 实例
返回值:
0:成功-1:失败
int drv_pmu_wait_event(drv_pmu_inst_t *inst, drv_pmu_event_t *event, int timeout_ms);#
功能:等待 PMU 事件并读取事件位图。
参数:
inst:PMU 实例event:返回的事件位图timeout_ms:等待超时,单位 ms;小于0表示永久等待
返回值:
0:成功收到事件1:超时,或等待被信号中断-1:失败
说明:
调用前必须已经执行
drv_pmu_register_notify()成功时返回的事件可能同时包含多个 bit
int drv_pmu_ack_shutdown(drv_pmu_inst_t *inst);#
功能:向驱动发送关机 ACK。
通常应在收到 DRV_PMU_EVENT_KEY_RELEASE 后调用,表示用户态清理完成并允许系统关机。
参数:
inst:PMU 实例
返回值:
0:成功-1:失败
int drv_pmu_schedule_power_cycle(drv_pmu_inst_t *inst, uint32_t shutdown_after_s, uint32_t poweron_after_s);#
功能:配置一次 RTC 定时关机/开机流程。
系统会在 shutdown_after_s 秒后关机,并在关机后再等待 poweron_after_s 秒自动开机。
参数:
inst:PMU 实例shutdown_after_s:距离关机的延迟时间,单位秒poweron_after_s:距离重新开机的延迟时间,单位秒
返回值:
0:成功-1:失败
说明:
当前驱动要求两个参数通常都不小于
2poweron_after_s是从关机时刻开始计时,不是从调用接口时刻开始计时
int drv_pmu_cancel_power_cycle(drv_pmu_inst_t *inst);#
功能:取消当前已配置的 RTC 定时关机/开机流程。
参数:
inst:PMU 实例
返回值:
0:成功-1:失败
int drv_pmu_event_has_long_press(drv_pmu_event_t event);#
功能:判断事件位图中是否包含长按事件。
参数:
event:PMU 事件位图
返回值:
非
0:包含DRV_PMU_EVENT_LONG_PRESS0:不包含
int drv_pmu_event_has_key_release(drv_pmu_event_t event);#
功能:判断事件位图中是否包含按键松开事件。
参数:
event:PMU 事件位图
返回值:
非
0:包含DRV_PMU_EVENT_KEY_RELEASE0:不包含
推荐使用流程#
长按关机场景#
调用
drv_pmu_inst_create()创建设备句柄调用
drv_pmu_register_notify()注册 PMU 事件通知循环调用
drv_pmu_wait_event()等待事件收到
DRV_PMU_EVENT_LONG_PRESS后执行用户态清理收到
DRV_PMU_EVENT_KEY_RELEASE后调用drv_pmu_ack_shutdown()退出前调用
drv_pmu_inst_destroy()释放资源
RTC 定时开关机场景#
调用
drv_pmu_inst_create()创建设备句柄调用
drv_pmu_schedule_power_cycle()配置关机与开机延时如需取消,调用
drv_pmu_cancel_power_cycle()结束后调用
drv_pmu_inst_destroy()释放资源
最小示例#
长按关机监听示例#
#include <stdio.h>
#include "drv_pmu.h"
int pmu_wait_shutdown(void)
{
drv_pmu_inst_t *pmu = NULL;
drv_pmu_event_t event;
if (drv_pmu_inst_create(&pmu) < 0)
return -1;
if (drv_pmu_register_notify(pmu, 0) < 0)
goto err;
for (;;) {
int ret = drv_pmu_wait_event(pmu, &event, -1);
if (ret < 0)
goto err;
if (ret > 0)
continue;
if (drv_pmu_event_has_long_press(event)) {
/* 执行用户态清理 */
}
if (drv_pmu_event_has_key_release(event)) {
if (drv_pmu_ack_shutdown(pmu) < 0)
goto err;
break;
}
}
drv_pmu_inst_destroy(&pmu);
return 0;
err:
drv_pmu_inst_destroy(&pmu);
return -1;
}
RTC 定时开关机示例#
#include <stdint.h>
#include "drv_pmu.h"
int pmu_schedule_cycle(uint32_t shutdown_after_s, uint32_t poweron_after_s)
{
drv_pmu_inst_t *pmu = NULL;
int ret = -1;
if (drv_pmu_inst_create(&pmu) < 0)
return -1;
if (drv_pmu_schedule_power_cycle(pmu,
shutdown_after_s,
poweron_after_s) < 0)
goto out;
ret = 0;
out:
drv_pmu_inst_destroy(&pmu);
return ret;
}
注意事项#
使用前需要确保系统已启用
RT_USING_RTC_PMU,并且存在设备节点/dev/pmu_pwrkey。drv_pmu_wait_event()依赖信号通知机制,建议由专门线程统一等待和处理。drv_pmu_ack_shutdown()应在收到DRV_PMU_EVENT_KEY_RELEASE后调用。如果应用决定不关机,可以不发送 ACK,系统会继续运行。
drv_pmu_schedule_power_cycle()依赖 RTC 当前时间正确,使用前建议先确认 RTC 时间已设置。当前 HAL 不配置“关机后长按开机”的硬件长按阈值,该阈值由底层 PMU 寄存器策略决定。
使用示例#
请参考 src/rtsmart/examples/peripheral/pmu/test_pmu.c
