SENSOR数据对接

SENSOR数据对接分为传感器数据算法适配和应用获取传感器数据。

传感器数据和算法

传感器与算法适配

应用数据获取

数据分发

算法处理后的传感器数据会被发送到HCPU,在sensor_service.csensors_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获取数据可以通过数据订阅和主动更新两种方式,使用方式参考页面数据更新