一、什么是protobuf
protobuf数据在数据传输的过程中需要编码和解码。如下的一个 control.proto 文件就是一个protobuf文件:
control.proto
syntax = "proto3";
package XGrobot;
enum MoveMode {
highSpeed = 0;
mediumSpeed = 1;
lowSpeed = 2;
}
message MoveCmd {
MoveMode movemode = 1; //机器人的移动速度挡位
int32 moveSpeed = 2;//速度
int32 direction = 3;//方向
}
在先不考虑语法的基础下,可以看到protobuf文件和类似的jons已经HTML文件等完全不同。
protobuf文件更类似于C的头文件,并且可以定义数据变量。
在实际使用的过程中,可以将control.proto文件作为小车的单片机和上位机进行通信的传输协议。但是最不同的点在于protobuf的使用需要进行编码和解码。数据发送前将数据按照格式编码,拿到数据后按照格式解码。而编解码的格式基础就是control.proto文件内容。
二、常用的probuf函数
单片机端一般安装nanopb来生成代码
linux 上一使用protobuf3点几版本以上的来使用。通过指令生成对应的代码。
protobuf仓库:
https://github.com/protocolbuffers/protobuf
protobuf-c仓库: protobuf-c是对于protobuf的仓库的补充
https://github.com/protobuf-c/protobuf-c
不错的参考文章
干货 | protobuf-c之嵌入式平台使用
Protobuf:一种更小、更快、更高效的协议
STM32 | protobuf在STM32平台的移植使用
【嵌入式Nanopb协议】——[1]总览
三、重要函数
linux上使用:
Protobuf protobufmessage; // 一个储存protobuf数据的实例
protobufmessage.set_movespeed(666); // 给一个数据的元素赋值
protobufmessage.set_movemode(XGrobot::lowSpeed);
protobufmessage.set_direction(66);
bool
SerializeToString(string* output) const;把message编码进output。
bool ParseFromString(const string& data);从string解码到message
bool SerializeToArray(char* buf,int size) const;把message编码进数组buf.
bool ParseFromArray(const char* buf,int size);把buf解码到message。
///此解码方法效率较ParseFromString高很多,所以一般用这种方法解码,而且IO函数一般是以char交流的,不是string。
bool SerializeToOstream(ostream output) const;把message编码进ostream
bool ParseFromIstream(istream* input);从istream解码到message
单片机上使用
uint8_t buffer[64] = {0};
Protobuf protobufmessage; // 一个储存protobuf数据的实例
pb_ostream_t o_stream = {0};
pb_istream_t i_stream = {0};
// 组包
movecmd.movemode = XGrobot_MoveMode_lowSpeed;
movecmd.moveSpeed = 100;
movecmd.direction = 99;
o_stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
pb_encode(&o_stream, protobufmessage_fields, &protobufmessage);
for(int i=0; i<64; i++)
{
printf("%x ",buffer[i]);
}
printf("\r\n");
// 解包
i_stream = pb_istream_from_buffer(buffer, sizeof(buffer));
pb_decode(&i_stream, protobufmessage_fields, &protobufmessage);
printf("movemode = %d\r\n", protobufmessage.movemode);
printf("moveSpeed = %d\r\n", protobufmessage.moveSpeed);
printf("direction = %d\r\n", protobufmessage.direction);
相关文章:
浅浅的 C++ 11
浅浅的 Protobuf通信协议
浅浅的 linux 串口驱动应用
浅浅的 linux开发板 驱动的使用 SPI IIC IO
浅浅的 Cmake