SENSOR数据对接
SENSOR数据对接分为传感器数据算法适配和应用获取传感器数据。
传感器数据和算法
应用数据获取
数据分发
算法处理后的传感器数据会被发送到HCPU,在sensor_service.c
中sensors_msg_process_in_hcpu_cb
函数中进行数据处理和分发
void sensors_msg_process_in_hcpu_cb(uint16_t msg_id, void *data, uint16_t data_len)
{
if (SENSOR_APP_EVENT_ID_BEGIN < msg_id && msg_id < SENSOR_APP_EVENT_ID_END || SENSOR_APP_TEST_RANDOM_IND == msg_id)
{
send_msg_to_gui_thread(data, data_len, sensors_wakeup_msg_process_in_gui_thread_cb, msg_id, NEED_WAKEUP_UI); //提醒类事件,唤醒YI
}
else if (SENSOR_APP_HISTORY_ID_BEGIN < msg_id && msg_id < SENSOR_APP_HISTORY_ID_END)
{
send_msg_to_bg_thread(data, data_len, sensors_msg_process_in_bg_thread_cb, msg_id, 0); //历史数据类,在bg线程存储
}
else
{
sensors_data_splitting_process_cb(msg_id, data, data_len); //数据拆分为基本单位,使sensor数据结构和UI无关
#if defined(BSP_BLE_SIBLES) && defined(PKG_USING_NANOPB)
sensors_msg_process_in_ble_to_app(msg_id, data, data_len); //发送数据到手机
#endif
send_msg_to_gui_thread(data, data_len, sensors_no_wakeup_msg_process_in_gui_thread_cb, msg_id, DONT_NEED_WAKEUP_UI); //发送数据到UI线程,进行实时数据存储和通知
}
}
分发数据处理
HCPU会分发sensor的实时数据和提醒消息到UI线程,历史数据到bg线程,处理都在sensor_service_ui.c
中实现。
实时数据
实时数据在int sensors_no_wakeup_msg_process_in_gui_thread_cb(comm_msg_t *msg)
中处理,主要实现数据的通知和存储。
提醒消息
提示类消息在int sensors_wakeup_msg_process_in_gui_thread_cb(comm_msg_t *msg)
中进行处理,实现了消息弹窗功能。
历史数据
历史数据在int sensors_msg_process_in_bg_thread_cb(comm_msg_t *msg)
中进行数据存储。
数据存储和获取
整体数据存储和获取
整体数据存储和获取是直接通过sensor的结构进行存储和获取。
存储接口
//id 类型,见rt_info_type_t,
//rt 数据地址
//length 数据长度
void app_rt_info_update(rt_info_type_t id, void *rt, uint16_t length);
获取接口
//id 类型,见rt_info_type_t,
//return 根据类型转换为结构体指针,结构体类型见rt_info_t rt_info_db[MAX_RT_TYPE]表
void *app_rt_info_get(rt_info_type_t id);
示例
step_info_t step = {0};
app_rt_info_update(RT_STEP, (void *)&step, sizeof(step));
step_info_t *p_step = (step_info_t *)app_rt_info_get(RT_STEP);
//do someting
拆分数据存储和获取
拆分数据是将结构体的每个成员拆分后进行单独存储和获取,利于UI和sensor解耦。
存储接口
//id 类型,见rt_data_info_type_t,
//data 基本数据地址
//length 数据长度,不超过4,对于double类型需要转换为float后再进行存储
void app_rt_data_info_update(rt_data_info_type_t id, void *data, uint16_t length);
获取接口
//id 类型,见rt_data_info_type_t,
//return 转换为存储类型后进行
void *app_rt_data_info_get(rt_data_info_type_t id);
示例
step_info_t *step = (step_info_t *)data;
app_rt_data_info_update(APP_STEP_STEP, &step->step, sizeof(step->step));
app_rt_data_info_update(APP_STEP_DISTANCE, &step->distance, sizeof(step->distance));
app_rt_data_info_update(APP_STEP_CALORIE, &step->calories, sizeof(step->calories));
app_rt_data_info_update(APP_STEP_TYPE, &step->active_type, sizeof(step->active_type));
app_rt_data_info_update(APP_STEP_FREQUENCY, &step->step_frequency, sizeof(step->step_frequency));
app_rt_data_info_update(APP_STEP_LENGTH, &step->step_length, sizeof(step->step_length));
app_rt_data_info_update(APP_STEP_PACE, &step->pace, sizeof(step->pace));
uint32_t step = *(uint32_t *)app_rt_data_info_get(APP_STEP_STEP);
uint32_t distance = *(uint32_t *)app_rt_data_info_get(APP_STEP_DISTANCE);
uint32_t calorie = *(uint32_t *)app_rt_data_info_get(APP_STEP_CALORIE);
uint8_t type = *(uint8_t *)app_rt_data_info_get(APP_STEP_TYPE);
float sp = *(float *)app_rt_data_info_get(APP_STEP_FREQUENCY);
float sl = *(float *)app_rt_data_info_get(APP_STEP_LENGTH);
float pace = *(float *)app_rt_data_info_get(APP_STEP_PACE);
//do someting
数据通知
sensor数据到UI线程后通过lv_obj_datasubs_notify
接口进行通知,详细用法见数据被动更新
整体数据通知时type是唯一的,id不用填
v_obj_datasubs_notify(NULL, SENSOR_APP_RT_HR_INFO_IND, msg->data, msg->data_len, NULL);
拆分数据通知时type不是唯一的,需要用id来确保唯一
lv_obj_datasubs_notify("rt_step", LV_EVENT_REFRESH, &step->step, sizeof(step_db->step), NULL);
UI数据刷新
UI获取数据可以通过数据订阅和主动更新两种方式,使用方式参考页面数据更新