Nanopb在SEE中的应用

什么是nanopb

napopb是一种新的类似pb(protocol buffer)的协议吗?

nanopb和pb有什么区别?

nanopb的基本概念 

proto file是个接口描述语言,类似android中aldl, 会发现接口描述语言很多,还有yaml, 只要有对应的解析脚本把解析后的结果能集成到使用环境就行。

protoco文件中样式如下,这里的1并不是对变量赋值为1,是说类型为uint32的变量step_count标号的fiedl_number为1, 是个键值对。

message sns_step_event{
  required uint32 step_count = 1;
}

这里有个不熟悉的概念wire type, 不是常说的数据类型,比如variint包括各种int 和bool,enum等。变量的field_number和对应的wire_type一起形成pb编码的Tag.

Stream用于编解pb码, 实际的函数是callback, ostream callback 操作需要编码的数据, istream callback 解码到xxx如 memory buffer.

pb_encode/decode callback和iostream callback有什么关系那?

pb_encode提供了encode、decode要操作的数据, 并调用iostream callback的具体实现。

nanopb在SEE的使用方式

send_data:

pb_send_event是个封装,把要编码的数据封装在sns_sensor_event中通过event进行传输,具体的细节如下:

  sns_rc
  sns_pedometer_instance_send_data(sns_sensor_instance *const this) {
      sns_rc rc = SNS_RC_SUCCESS;
      sns_pedometer_instance_state *state = 
          (sns_pedometer_instance_state*) this->state->state;
  
      sns_pedometer_step_event event = sns_pedometer_step_event_init_default;
      event.step_count = state->step_count;
 
      if (!pb_send_event(this, sns_pedometer_step_event_fields, &event,
          sns_get_system_time(), SNS_PEDOMETER_MSGID_SNS_PEDOMETER_STEP_EVENT, 
          &pedometer_suid)
          ) { 
          SNS_INST_PRINTF(ERROR, this, 
              "sns_pedometer_instance_notify_event - Error in sending event");
          rc = SNS_RC_INVALID_STATE;
      }   
  
      return rc;                                                                                                                                                                                       
  }
 

 xx.protoco -> xx.pb.h -> xx.pb.c

message -> typedef struct: default value: fields -> fields赋值

fields是什么?可能是pb编码格式相关的结构体。

要编码的数据是c_struct*, 数据的长度是:pb_get_encoded_size

pb编码后放到哪里?

sns_sensor_event 结构体的event[1]是个指针,指向分配的内存;

pb_ostream_from_buffer就是把编码后的数据写到buffer里, 具体实现就是创建 pb_ostream_t

 static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count)
  {
      size_t i;
      pb_byte_t *dest = (pb_byte_t*)stream->state;
      stream->state = dest + count;
      
      for (i = 0; i < count; i++)
          dest[i] = buf[i];
      
      return true;
  }
  
  pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize)
  {
      pb_ostream_t stream;
  #ifdef PB_BUFFER_ONLY
      stream.callback = (void*)1; /* Just a marker value */
  #else
      stream.callback = &buf_write;
  #endif
      stream.state = buf;
      stream.max_size = bufsize;
      stream.bytes_written = 0;
  #ifndef PB_NO_ERRMSG
      stream.errmsg = NULL;
  #endif
      return stream;
  }

pb_encode

pb_encode(&stream, fields, c_struct)

 

SEE中pb的解码

通过sns_sensor_event机制把传输的编码后的数据得到,创建istream得到pb_decoded后的数据

解码并没有封装好的pb_send_event对应函数,要自己创建istream, 代码有点乱,但理解了这个过程,代码就容易理解了。

发布了336 篇原创文章 · 获赞 54 · 访问量 79万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览