ssc sam

https://www.jianshu.com/u/8dba4c15ff52

image.png

[图片上传失败...(image-7da7d8-1534316650184)]

image.png

https://blog.csdn.net/liuei633/article/details/81706189

四:Sensor SLPI层SAM Sensor实例分析

上文中,我们大致了解了物理sensor driver整个流程,但在项目中,一般写这种sensor driver的情况很少。这种sensor driver基本上都是各个vendor厂商提供的,我们也只需要看懂即可。

但是SAM sensor我们完全是可以自己写的,根据一些物理sensor的数据,来实现一些算法。

比如,实现拿起唤醒功能,这个功能在oem手机中非常常见。

基本功能就是:当用户拿起手机时,手机屏幕亮起,此时可以通过脸部识别,来解锁手机等等。

这时好多人可能会说,这不是很简单吗?在framework层就可以做,注册一个加速度传感器,并根据data做一定算法处理。根本不需要再SLPI侧再实现一个SAM sensor。这种思维就是典型的应用层程序员的思想,系统层程序员如果有这种思想,那就很危险了。

为什么不能再framework层上做算法处理呢?

framework层进行算法处理,当系统睡下去怎么办?若是注册Non-Wakeup的sensor的话,在系统suspend时,不会有任何数据上报,如何唤醒系统呢?若是注册Wakeup的sensor的话,系统会被wakelock住,根本睡不下去,这时系统功耗非常高。

可见在framework层做的想法是在系统层面不可能实施的。

那么在SLPI侧实现pick up sensor的思路是什么呢?

pick up sensor在LPSS侧是work的,APSS侧是可以suspend的,当pick up Sensor获取accel sensor的数据满足算法时,会publish event给APSS中client,此时会唤醒系统。唤醒系统后,framework层会根据该sensor type,做相应的操作,比如亮屏、震动等等。。。

Ok,下面我们以该pickup sensor为例,解析下SLPI 侧 SAM Sensor driver。

高通给我们参考的oem sensor实例,下面我们在oem sensor实例上实现pickup sensor。

1:build脚本

根据上文中介绍。各个sensor都是通过xxxx.scons静态添加sensor的。

oem sensor的source code在/slpi/ssc/sensors/oem1中。

if 'USES_SSC_STATIC_LIB_BUILDER' in env:

  env.AddSSCSU(inspect.getfile(inspect.currentframe()),

              register_func_name = "sns_oem1_register",

              clean_pack_list = oem1_clean_pack_list,

              binary_lib = oem1_binary_lib,

              add_island_files = oem1_island_enable,

              diag_ssid = ssid)

1

2

3

4

5

6

7

build脚本会通过register_func_name = “sns_oem1_register”,调到sns_oem1_register函数。

2:Initialization

sns_rc sns_oem1_register(sns_register_cb const *register_api)

{

  register_api->init_sensor(sizeof(sns_oem1_sensor_state),

                            &sns_oem1_api,

                            &sns_oem1_sensor_instance_api);

  return SNS_RC_SUCCESS;

}

sns_sensor_api sns_oem1_api =

{

    .struct_len = sizeof(sns_sensor_api),

    .init = &sns_oem1_init,

    .deinit = &sns_oem1_deinit,

    .get_sensor_uid = &sns_oem1_get_sensor_uid,

    .set_client_request = &sns_oem1_set_client_request,

    .notify_event = &sns_oem1_notify_event,

};

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

根据前文介绍。sns_register_sensor()注册函数后,会执行sns_sensor_api的init函数。

.init

sns_rc

sns_oem1_init(sns_sensor *const this)

{

  sns_oem1_sensor_state *state = (sns_oem1_sensor_state*)this->state->state;

  struct sns_service_manager *smgr = this->cb->get_service_manager(this);

  float data[3];

  state->diag_service = (sns_diag_service*)

        smgr->get_service(smgr, SNS_DIAG_SERVICE);

  // set default output value corresponding to OEM1_FACING_DOWN to 50. will

  // rewrite if registry sensor is available

  state->config.down_value = 50.0;

  state->first_pass = true;

  // determine encoded output event size

  state->config.encoded_data_event_len =

      pb_get_encoded_size_sensor_stream_event(data, 3);

  SNS_SUID_LOOKUP_INIT(state->suid_lookup_data, NULL);

  sns_suid_lookup_add(this, &state->suid_lookup_data, "accel");//No.1

  sns_suid_lookup_add(this, &state->suid_lookup_data, "amd");  //No.2

#ifndef SUPPORT_DIRECT_SENSOR_REQUEST

  sns_suid_lookup_add(this, &state->suid_lookup_data, "resampler");//No.3

#endif

  publish_attributes(this); //No.4

  SNS_PRINTF(MED, this, "OEM1 init success and attributes published");

  return SNS_RC_SUCCESS;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

No.1:sns_suid_look_add添加所需要的sensor。

No.2:添加amd sensor。

No.3:添加resampler sensor。

No.4:并pushlish atrribute。比如sensor name、type、vendor等,Client层会根据该attribute,设置sensor的一些属性,比如on_change、streaming等等

.get_sensor_uid

static sns_sensor_uid const*

sns_oem1_get_sensor_uid(sns_sensor const *this)

{

  UNUSED_VAR(this);

  static const sns_sensor_uid oem1_suid = OEM1_SUID;

  return &oem1_suid;

}

1

2

3

4

5

6

7

oem1_suid是指定的,返回的是oem_suid。

.notify

sns_rc

sns_oem1_notify_event(sns_sensor *const this)

{

  sns_oem1_sensor_state *state = (sns_oem1_sensor_state*)this->state->state;

  SNS_PRINTF(LOW, this, "sns_oem1_notify_event");

  sns_suid_lookup_handle(this, &state->suid_lookup_data);

#ifdef SUPPORT_REGISTRY

  if(NULL != state->registry_stream)

  {

    handle_oem1_registry_event(this);

  }

#endif

  if(sns_suid_lookup_complete(&state->suid_lookup_data))

  {

#ifdef SUPPORT_REGISTRY

    if(state->first_pass == true){

      state->first_pass = false;

      sns_oem1_registry_req(this);

    }

#endif

    publish_available(this);

    sns_suid_lookup_deinit(this, &state->suid_lookup_data);

  }

  return SNS_RC_SUCCESS;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

该notify,主要处理init中的event。

通过sns_suid_lookup_handle(),handle一个suid或者attribute event。

通过sns_suid_lookup_complete(),来返回所有sensor data 的suid是否找到。

Initialization分析完毕,Initialization重要东西不多,主要是添加所需要的dependency sensor,比如accel、amd、resampler等等,并获取oem1_suid。然后通过notify_event来查看sensor type的suid是否找到。

3: Activation

sns_sensor_instance_api sns_oem1_sensor_instance_api =

{

    .struct_len = sizeof(sns_sensor_instance_api),

    .init = &sns_oem1_inst_init,

    .deinit = &sns_oem1_inst_deinit,

    .set_client_config = &sns_oem1_inst_set_client_config,

    .notify_event = &sns_oem1_inst_notify_event

};

1

2

3

4

5

6

7

8

9

当client发送request时,先进入sns_sensor_api中的.set_client_config。

.set_client_config

sns_sensor_instance*

sns_oem1_set_client_request(sns_sensor *const this,

    sns_request const *curr_req,

    sns_request const *new_req,

    bool remove)

{

  sns_sensor_instance *curr_inst =

      sns_sensor_util_find_instance(

          this,

          curr_req,

          this->sensor_api->get_sensor_uid(this));

  sns_sensor_instance *rv_inst = NULL;

  SNS_PRINTF(MED, this, "sns_oem1_set_client_request");

  if((NULL != curr_inst) && (NULL != new_req) &&    //No.1

  (SNS_STD_MSGID_SNS_STD_FLUSH_REQ == new_req->message_id))

  {

  SNS_PRINTF(HIGH, this, "Received Flush Request");

  this->instance_api->set_client_config(curr_inst, new_req);

  rv_inst = curr_inst;

  }

  else if(remove)  //No.2

  {

    if(NULL != curr_inst)

    {

      curr_inst->cb->remove_client_request(curr_inst, curr_req);

    }

  }

  else                        //No.3

  {

    pb_istream_t stream;

    sns_std_sensor_config config = {0};

    sns_std_request request = sns_std_request_init_default;

    pb_simple_cb_arg arg =

    { .decoded_struct = &config, .fields = sns_std_sensor_config_fields };

    request.payload = (struct pb_callback_s)

          { .funcs.decode = &pb_decode_simple_cb, .arg = &arg };

    stream = pb_istream_from_buffer(new_req->request, new_req->request_len);

    if(pb_decode(&stream, sns_std_request_fields, &request))

    {

      sns_request decoded_req = {.message_id = new_req->message_id,

          .request_len = sizeof(config), .request = &config };

      sns_sensor_instance *match_inst = sns_sensor_util_find_instance_match(

          this, &decoded_req, &find_instance_match);

      if(NULL == curr_inst)

      {

        // If this is a request from a new client

        if(NULL == match_inst)

        {

          rv_inst = this->cb->create_instance(this,

              (sizeof(sns_oem1_inst_state)));

        }

        else

        {

          rv_inst = match_inst;

        }

      }

      else

      {

        if(NULL != curr_req)

        {

          curr_inst->cb->remove_client_request(curr_inst, curr_req);

        }

        if(NULL != match_inst)

        {

          rv_inst = match_inst;

        }

        else

        {

          rv_inst = this->cb->create_instance(this,

              (sizeof(sns_oem1_inst_state)));

        }

      }

      if(NULL != rv_inst)

      {

        rv_inst->cb->add_client_request(rv_inst, new_req);

        this->instance_api->set_client_config(rv_inst, &decoded_req);

      }

    }

    else

    {

      SNS_PRINTF(ERROR, this, "failed to decode request");

    }

  }

  if(NULL != curr_inst && NULL == curr_inst->cb->get_client_request(

      curr_inst, this->sensor_api->get_sensor_uid(this), true))

  {

    this->cb->remove_instance(curr_inst);

  }

  return rv_inst;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

该函数很简单,

No.1:处理message_id=SNS_STD_MSGID_SNS_STD_FLUSH_REQ ,此时会将该message_id传送给sns_oem1_inst_set_client_config,并做相应的处理。

No.2:为remove分支

No.3:正常情况下走的流程。

(1)先判断是否有与new_req匹配的sns_sensor_instance,若有直接用match的;

(2)若无,判断是否有当前的curr_inst即旧的sns_sensor_instance存在。若有,则通过curr_inst->cb->remove_client_request函数remove掉旧的curr_req client。,并通过this->cb->create_instance()创建一个新的sns_sensor_instance。若无,则直接创建一个新的sns_sensor_instance即rv_inst。

(3)创建好的sns_sensor_instance叫rv_inst,然后通过rv_inst->cb->add_client_request添加新的client request。

(4)并通过this->instance_api->set_client_config处理该新建的sns_sensor_instance ,即rv_inst。

(5)若curr_inst不为空,并且curr_inst还可以获取到client_reqeust。这时要remove掉curr_inst即当前的sns_sensor_instance。

Ok,create_instance()执行后便进入sns_sensor_instance_api.init()。

set_client_config()执行后便进入sns_sensor_instance_api.set_client_config()。

.init

sns_rc

sns_oem1_inst_init(sns_sensor_instance *this,

    sns_sensor_state const *state)

{

  sns_rc rc = SNS_RC_SUCCESS;

  sns_oem1_inst_state *inst_state =

      (sns_oem1_inst_state*)this->state->state;

  sns_oem1_sensor_state *sensor_state =

      (sns_oem1_sensor_state*)state->state;

  sns_service_manager *service_mgr = this->cb->get_service_manager(this);

#ifdef SUPPORT_DIRECT_SENSOR_REQUEST

  sns_stream_service *stream_service = (sns_stream_service*)

        service_mgr->get_service(service_mgr, SNS_STREAM_SERVICE);

#endif

#ifdef SUPPORT_DIRECT_SENSOR_REQUEST

  sns_suid_lookup_get(&sensor_state->suid_lookup_data, "accel", &inst_state->accel_suid);

#else

  sns_suid_lookup_get(&sensor_state->suid_lookup_data, "resampler", &inst_state->resampler_suid);

  sns_suid_lookup_get(&sensor_state->suid_lookup_data, "accel", &inst_state->accel_suid);

#endif

  inst_state->diag_service = (sns_diag_service*)

          service_mgr->get_service(service_mgr, SNS_DIAG_SERVICE);

  inst_state->down_value = sensor_state->config.down_value;

#ifdef SUPPORT_DIRECT_SENSOR_REQUEST

  // start regular stream for accel

  stream_service->api->create_sensor_instance_stream(

      stream_service,

      this,

      inst_state->accel_suid,

      &inst_state->accel_stream);

#endif

  inst_state->inst_config.previous_state = OEM1_UNKNOWN;

  inst_state->inst_config.current_state = OEM1_UNKNOWN;

  // read platform specific configuration

  sns_memscpy(&inst_state->config,

      sizeof(inst_state->config),

      &sensor_state->config,

      sizeof(sensor_state->config) );

  return rc;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

该函数,主要是获取resampler、accel等的suid。将suid放到inst_state->xxxx_suid中。

.set_client_config

sns_rc

sns_oem1_inst_set_client_config(sns_sensor_instance *const this,

    sns_request const *client_request)

{

  sns_rc rc = SNS_RC_SUCCESS;

  sns_oem1_inst_state *state = (sns_oem1_inst_state*)this->state->state;

  SNS_INST_PRINTF(LOW, this, "sns_oem1_inst_set_client_config");

  if(SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_CONFIG == client_request->message_id)

  {

    // initialize state here

    sns_std_sensor_config *client_req =

        (sns_std_sensor_config *)(client_request->request);

    sns_memscpy(&state->client_config,

        sizeof(state->client_config),

        client_request->request,

        client_request->request_len);

    state->config.sample_rate = client_req->sample_rate;

#ifndef SUPPORT_DIRECT_SENSOR_REQUEST

    // start streaming from resampler

    SNS_INST_PRINTF(LOW, this, "Enable resampler at rate %f", client_req->sample_rate);

    sns_service_manager *manager =

        this->cb->get_service_manager(this);

    sns_stream_service *stream_service =

        (sns_stream_service*)manager->get_service(manager, SNS_STREAM_SERVICE);

    sns_resampler_config resampler_config = sns_resampler_config_init_default;

    size_t encoded_len;

    uint8_t buffer[100];

    client_req->sample_rate = 25.0f;

    sns_memscpy(&resampler_config.sensor_uid, //No.1

        sizeof(resampler_config.sensor_uid),

        &state->accel_suid,

        sizeof(state->accel_suid));

    resampler_config.resampled_rate = client_req->sample_rate;

    resampler_config.rate_type = SNS_RESAMPLER_RATE_MINIMUM;

    resampler_config.filter = false;

    // create connection with resampler sensor

    stream_service->api->create_sensor_instance_stream(  //No.2

        stream_service,

        this,

        state->resampler_suid,

        &state->resampler_stream);

    if(NULL != state->resampler_stream)

    {

      encoded_len = pb_encode_request(buffer, sizeof(buffer),

          &resampler_config, sns_resampler_config_fields, NULL);

      if(0 < encoded_len)

      {

        sns_request request = (sns_request){

          .message_id = SNS_RESAMPLER_MSGID_SNS_RESAMPLER_CONFIG,

              .request_len = encoded_len, .request = buffer };

        rc = state->resampler_stream->api->send_request(state->resampler_stream, &request);

        SNS_INST_PRINTF(MED, this, "oem1 sent accel request to resampler at rate %f", client_req->sample_rate);

      }

      else

      {

        SNS_INST_PRINTF(ERROR, this, "oem1 failed to encode resampler config");

      }

    }

    else

    {

      SNS_INST_PRINTF(ERROR, this, "oem1 resampler stream creation failed");

    }

#else // not using the resampler, request accel directly

    size_t encoded_len;

    uint8_t buffer[20];

    // enable accel here

    sns_memset(buffer, 0, sizeof(buffer));

    client_req->sample_rate = 25.0f;

    sns_std_sensor_config accel_config = {.sample_rate = client_req->sample_rate};

    SNS_INST_PRINTF(LOW, this, "Enable accel at rate %f", client_req->sample_rate);

    encoded_len = pb_encode_request(buffer,

        sizeof(buffer),

        &accel_config,

        sns_std_sensor_config_fields,

        NULL);

    if(0 < encoded_len && NULL != state->accel_stream )

    {

      sns_request request = (sns_request){

        .message_id = SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_CONFIG,

            .request_len = encoded_len, .request = buffer };

      state->accel_stream->api->send_request(state->accel_stream, &request);

    }

    else

    {

      SNS_INST_PRINTF(ERROR, this, "Error in creating accel stream OR encoding failed");

      rc = SNS_RC_NOT_SUPPORTED;

    }

    SNS_INST_PRINTF(LOW, this, "Processed oem1 config request: enabled accel with"

        "sample rate %f, result: %u", state->client_config.sample_rate, rc);

#endif

  }

  else if(client_request->message_id ==  SNS_STD_MSGID_SNS_STD_FLUSH_REQ)

  {

    sns_sensor_util_send_flush_event(NULL, this);

  }

  else

  {

    SNS_INST_PRINTF(ERROR, this, "Unsupported request message id %u",

        client_request->message_id);

    rc = SNS_RC_NOT_SUPPORTED;

  }

  return rc;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

该函数,首先根据client传入的msg_id做处理。

当message_id = SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_CONFIG时,这时,我们就需要发送accel的request,来获取accel的data了。

这里面有个宏SUPPORT_DIRECT_SENSOR_REQUEST,这里我们不support这个宏,走的是resampler。若support这个宏,则直接发送request给accel。

这里用resampler后,会先发送request给resampler sensor,resampler sensor再获取accel的数据。

No.1中,填充sns_resampler_config。并将state->accel_suid赋给resampler_config.sensor_uid。

No.2中,create_sensor_instance_stream会创建data stream,以后resampler request和event都会走该data stream。

然后通过pb_encode_request,将sns_resampler_config 编码成buffer。

最后填充sns_request request,可以看到request message_id = SNS_RESAMPLER_MSGID_SNS_RESAMPLER_CONFIG ,.request = buffer。然后通过send_request发送出去。

sns_oem1_inst_set_client_config发送完毕后,接下来就是接收event了。

.notify_event

static sns_rc

sns_oem1_inst_notify_event(sns_sensor_instance *const this)

{

  sns_rc rc = SNS_RC_SUCCESS;

  sns_oem1_process_resampler_event(this);

  return rc;

1

2

3

4

5

6

static sns_rc sns_oem1_process_resampler_event(sns_sensor_instance *const this)

{

  sns_rc rc = SNS_RC_SUCCESS;

  sns_oem1_inst_state *state = (sns_oem1_inst_state*)this->state->state;

  sns_sensor_event *resampler_event_in = NULL;

  SNS_INST_PRINTF(LOW, this, "sns_oem1_inst_process_resampler_event");

  resampler_event_in = state->resampler_stream->api->peek_input(state->resampler_stream);

  while( NULL != resampler_event_in )

  {

    if(SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_EVENT == resampler_event_in->message_id) //No.1

    {

      float data[3] = { 0 };

      float oem1_payload[OEM1_NUM_ELEMS];

      uint8_t arr_index = 0;

      pb_float_arr_arg arg = {

          .arr = data,

          .arr_len = ARR_SIZE(data),

          .arr_index = &arr_index

      };

      pb_istream_t stream = pb_istream_from_buffer((pb_byte_t*)resampler_event_in->event,resampler_event_in->event_len);

      sns_std_sensor_event resampler_data = sns_std_sensor_event_init_default;

      resampler_data.data = (struct pb_callback_s) {

        .funcs.decode = &pb_decode_float_arr_cb, .arg = &arg

      };

      if(!pb_decode(&stream, sns_std_sensor_event_fields, &resampler_data)) //No.2

      {

        SNS_INST_PRINTF(ERROR, this, "Error in decoding resampler event");

      }

      else

      {

        if (SNS_STD_SENSOR_SAMPLE_STATUS_UNRELIABLE == resampler_data.status)

        {

          SNS_INST_PRINTF(LOW, this, " OEM1 received unreliable accel data"

              " from resampler ignoring..");

          resampler_event_in = state->resampler_stream->api->get_next_input(state->resampler_stream);

          continue;

        }

        //This is dummy logic for OEM1 demonstration purposes

        //OEMs can replace with their algo logic

        oem1_facing_state current_state = OEM1_UNKNOWN;

        SNS_INST_PRINTF(LOW, this,

            "resampler accel data: x %d/1000, y %d/1000, z %d/1000",

          (int) (1000*data[0]),(int)( 1000*data[1]),(int)(1000*data[2]));

        //sns_oem1_procces(this, &input);

        state->inst_config.previous_state = state->inst_config.current_state;

        if(0 < data[2])                          //No.3

        {

          current_state = OEM1_FACING_UP;

          oem1_payload[0]=100;

          oem1_payload[1]=data[1];

          oem1_payload[2]=data[2];

        }

        else

        {

          current_state = OEM1_FACING_DOWN;

          oem1_payload[0]= state->down_value;

          oem1_payload[1]=data[1];

          oem1_payload[2]=data[2];

        }

        state->inst_config.current_state = current_state;

        SNS_INST_PRINTF(LOW, this, "OEM1 output:  x %d/1000, y %d/1000, z %d/1000",

            (int) (1000*oem1_payload[0]),(int)( 1000*oem1_payload[1]),(int)(1000*oem1_payload[2]));

#ifdef SUPPORT_EVENT_TYPE

        if(state->inst_config.current_state != state->inst_config.previous_state)

        {

#endif

          SNS_INST_PRINTF(MED, this,

              "OEM1 last %d current %d",

              state->inst_config.current_state,

              state->inst_config.previous_state);

          rc = pb_send_sensor_stream_event(this,      //No.4

              NULL,

              resampler_event_in->timestamp,

              SNS_OEM1_MSGID_SNS_OEM1_DATA,

              SNS_STD_SENSOR_SAMPLE_STATUS_ACCURACY_HIGH,

              oem1_payload,

              OEM1_NUM_ELEMS,

              state->config.encoded_data_event_len);

          if(SNS_RC_SUCCESS != rc)

          {

            SNS_INST_PRINTF(ERROR, this, "sns_oem1_inst_notify_event - Error in sending event");

          }

#ifdef SUPPORT_EVENT_TYPE

        }

#endif

      }

    }

    // check next sample

    resampler_event_in = state->resampler_stream->api->get_next_input(state->resampler_stream);

  }

  return rc;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

No.1:接收到accel的message_id。

No.2:将stream解码成resampler_data的格式。resampler_data.data.arr即为accel的sensor data。

No.3:该处是根据accel数据做算法处理。比如panel朝向,panel加速度等等。

No.4:pb_send_sensor_stream_event来publish event,若算法满足,可以通过该函数publish event,client便接收到event来唤醒系统,最终实现wake up。

Ok,SAM sensor分析完毕,该文与上一篇文章流程基本相似,唯一不同点就是SAM Sensor会Dependency other sensor,并在sns_sensor_instance_api.set_client_config中发送Dependency sensor的request,然后在sns_sensor_instance_api.notify_event中处理获取到的dependency sensor 数据

---------------------

版权声明:本文为CSDN博主「汉克233」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/liuei633/article/details/81706189

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,961评论 5 473
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,444评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,009评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,082评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,101评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,271评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,738评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,395评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,539评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,434评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,481评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,160评论 3 317
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,749评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,816评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,038评论 1 256
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,548评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,140评论 2 341