电池服务 Battery Servcie¶
小技巧
如果图片看不清楚。你可以 在图片上点击鼠标右键 –> 在新标签页中打开图片 ,然后你可以放大、缩小、移动图片。
battery_service.h , battery_service.c , voltage_monitor.h , voltage_monitor.c , battery_example.c 。
概述¶
电池服务 Battery Service,是 外设服务 Periph Service 的子类。
- 前者完全是按后者的框架实现的。
- 后者实现时基本上完全覆盖(或继承)前者的方法。
- 除了创建 Create 与特殊 API 要调用外设子服务的API;一般都调用音频服务的 API。
类图¶
我们用类图的形式,描述电池服务 Battery Service 的实现(实际上代码是用 C 语言实现的):
Battery_Servcie 类¶
结构体
battery_service_t,是内部私有数据。.serv_q: API 等向内部任务battery_task发送消息的消息队列。.sync_events:battery_task向 API 等发送事件的 Event Group 。.vol_monitor: 也就是 class Voltage_Monitor 。 电池服务内部的另一个用于监测电池电压的定时器任务。见下文 Voltage_Monitor 类 。
private method 部分,是 Battery Servcie 内部函数。这些函数的实现大部分都很简单:
battery_task(): 内部任务。_battery_start(): 启动 Battery Service。_battery_stop(): 停止 Battery Service。_battery_destroy(): 销毁 Battery Service。
public method 部分,是 DuerOS Servcie 的提供的 API 函数。这些函数的实现大部分都很简单:
battery_service_create()的实现略微复杂一点,看这里 API 。battery_service_vol_report_switch()开关电量上报。battery_service_set_vol_report_freq()设置电量上报频率。
Voltage_Monitor 类¶
结构体
vol_monitor_ctx_t,是内部私有数据。.mutex: 锁,用于保护结构体内的其它字段,防止 API 与 定时器同时访问/修改这些变量。.config: 一些配置,如下所示:/** * @brief Battery adc configure */ typedef struct { bool (*init)(void *); /*!< Voltage read init */ bool (*deinit)(void *); /*!< Voltage read deinit */ int (*vol_get)(void *); /*!< Voltage read interface */ void *user_data; /*!< Parameters for callbacks */ int read_freq; /*!< Voltage read frequency, unit: s*/ int report_freq; /*!< Voltage report frequency, voltage will be report with a interval calculate by (`read_freq` * `report_freq`) */ int vol_full_threshold; /*!< Voltage threshold to report, unit: mV */ int vol_low_threshold; /*!< Voltage threshold to report, unit: mV */ } vol_monitor_param_t;.event_cb: 事件回调,用于与battery_task()通信 。.user_ctx: 事件回调上下文参数 。.check_timer: 定时器 。
private method 部分,是 Voltage Monitor 内部函数。
vol_check_timer_hdlr(): 定时器任务。
public method 部分,是 Voltage Monitor 的提供的 API 函数。这些函数的实现大部分都很简单:
vol_monitor_create(vol_monitor_param_t *config)创建电压监测功能 。vol_monitor_destroy()销毁电压监测能。vol_monitor_set_event_cb()设置电压监测事件回调。vol_monitor_start_freq_report()下始电压监测周期上报。vol_monitor_stop_freq_report()停止电压监测周期上报。vol_monitor_set_report_freq()设置电压监测上报频率。
序列图¶
对像说明:
- battery_example.c: 某个应用程序
- battery_service.c: 电池服务
- battery_task(): 电池服务的内部任务
- voltage_monitor.c:电量监测
- vol_check_timer_hdlr():电量监测内部的定时器
流程说明:
- 应用程序 battery_example.c 调用 voltage_monitor.c 电量检测
vol_monitor_create()。同时传入与电量检测相关的三个函数。 - voltage_monitor.c 调用初始函数
.config->init()。 - 创建锁。
- 创建定时器
.check_timer。该定时器超时后会调用vol_check_timer_hdlr()。 - 启动定时器
.check_timer。该定时器超时每.config->read_freq会超时一次。
- 应用程序 battery_example.c 调用 Battery Service 电池服务
battery_service_create()。 - 创建内部通信的消息队列。
- 创建内部通信的事件组。
- battery_service.c 调用
periph_service_create(), 并会将.service_destroy,.service_start,.service_stop, 等回调函数作为参数的字段传入。 同时也会将自已的地址,作为.user_data参数字段传入。 因 Battery Service 需要创建内部任务,也会将内部任务函数 battery_task() 作为.task_func参数字段传入。 - periph_service.c 将上述回调函数和
.user_data保存下来。因为.task_func不为空(实际上是.task_stack > 0),故同时创建内部任务。 - battery_service.c 调用
periph_service_set_callback({.evt_cb})注册事件回调函数。
- battery_example.c 调用
periph_service_start()开始电池服务。 .service_start不为空,被执行( 实际上是执行_battery_start())。- battery_service.c 发送消息
BATTERY_SERVICE_START给内部任务。 - 内部任务 battery_task() 调用
vol_monitor_set_event_cb(battery_vol_monitor_cb)设置电量监测的事件回调函数。battery_vol_monitor_cb()就是该事件回调函数。 - voltage_monitor.c 保存该事件回调函数。
- battery_example.c 调用
battery_service_vol_report_switch(true)开始电量上报。 - battery_service.c 发送消息
BATTERY_VOL_REPORT_START给内部任务。 - 内部任务 battery_task() 调用
vol_monitor_start_freq_report()开始周期上报。 - voltage_monitor.c 保存新的电量上报周期。
- battery_example.c 调用
battery_service_set_vol_report_freq(freq)修改电量上报周期。 - battery_service.c 发送消息
BATTERY_VOL_SET_REPORT_FREQ给内部任务。 - 内部任务 battery_task() 调用
vvol_monitor_set_report_freq(freq)修改电量上报周期。 - voltage_monitor.c 保存新的电量上报周期。
定时器周期超时。
定时器调用
.event_cb(VOL_MONITOR_EVENT_FREQ_REPORT)(实际上是调用battery_vol_monitor_cb()) 周期上报电量。battery_service.c 向内部任务 battery_task 发送消息
BATTERY_VOL_REPORT_FREQ,携带电量信息 。内部任务 battery_task 调用 periph_service_callback(BAT_SERV_EVENT_VOL_REPOR).
periph_service.c 调用应用的事件回调函数
battery_service_cb()。45~48, 49~52 的流程与 40~44 完全类似,只不过是携带的信息不同: 电量低或电量满。
- battery_example.c 调用
battery_service_vol_report_switch(false)开始电量上报。 - battery_service.c 发送消息
BATTERY_VOL_REPORT_STOP给内部任务。 - 内部任务 battery_task() 调用
vol_monitor_stop_freq_report()开始周期上报。 - voltage_monitor.c 保存新的电量上报周期。
- 应用调用(实际上无些调用)
periph_service_stop()停止电池服务。 .service_stop不为空,被执行( 实际上是执行_battery_stop())。- battery_service.c 发送消息
BATTERY_SERVICE_STOP给内部任务。 - 内部任务 battery_task() 调用
vol_monitor_set_event_cb(NULL)清除电量监测的事件回调函数。 - voltage_monitor.c 清除该事件回调函数。
- battery_example.c 调用
periph_service_destroy(), 销毁 Battery Service。 - 因
.service_destroy不为空, 其被 periph_service.c 调用( 实际上是执行_battery_destory())。 - battery_server.c 发送
BATTERY_SERVICE_DESTROY消息给内部任务。 - 内部任务 battery_task() 调用
vol_monitor_set_event_cb(NULL)清除电量监测的事件回调函数。 - voltage_monitor.c 清除该事件回调函数。。
- battery_service.c 中止内部任务 battery_task() 。
- battery_service.c 清除消息队列。
- battery_service.c 清除事件组。
- 应用程序 battery_example.c 调用 voltage_monitor.c 电量检测
vol_monitor_destory()。 - voltage_monitor.c 停止定时器
.check_timer。 - voltage_monitor.c 销毁定时器
.check_timer。 - voltage_monitor.c 调用反初始化函数
.config->deinit()。 - voltage_monitor.c 删除锁 。
API¶
vol_monitor_create()
battery_service_create()
periph_service_start()
battery_service_vol_report_switch(true)
battery_service_set_vol_report_freq()
battery_service_cb() (事件回调)
battery_service_vol_report_switch(false)
periph_service_stop()
periph_service_destroy()
vol_monitor_destroy()