在keil中使用protobuf

什么是protobuf

ProtocolBuffer是Google提出的一种轻量级、跨语言的数据序列化格式,它用于结构化数据的序列化,适用于数据存储和RPC数据交换。相比JSON,protobuf在性能和数据大小上更具优势,通过.proto文件编译成不同语言的代码,实现跨语言通信。protobuf的之所以可以跨语言,就是因为数据定义的格式为.proto格式,需要基于protoc编译为对应的语言。
在这里插入图片描述

protobuf 2 语法

protobuf协议文件名后缀名为.proto。一个简单的protobuf协议如下:

syntax="proto3";
package protobuf.addressbook;

 enum PhoneType
{
	MOBILE = 0;
	HOME = 1;
	WORK = 2;
}
message Person
{
	optional string name = 1;
	optional uint32 age = 2;
	optional string email = 3;

	message PhoneNumber
	{
		optional string number = 1;
		optional PhoneType type = 2;
	}
	repeated PhoneNumber phone = 4;                                                                                                                                                                                                                                                 
}                                                             
message AddressBook          
{                            
repeated Person person = 1;
}

标识符

  • syntax:标识使用的protobuf是哪个版本。上面表示使用的是3.x版本。

  • package:标识生成目标文件的包名。在C++中表示的是命名空间。上面。表示生成的类和函数在protobuf命名空间的addressbook命令空间下。

  • enum:表示一个枚举类型。会在目标.h文件中自动生成一个枚举类型。 message:标识一条消息。会在目标文件中自动生成一个类。

字段

  • required:该字段必须给值,不能为空。否则message被认为是未初始化的。如果试图建立一个未初始化的message将会抛出RuntimeException异常,解析未初始化的message会抛出IOException异常。

  • optional:表示该字段是可选值,可以为空。如果不设置,会设置一个默认值。也可以自定义默认值。如果没有自定义默认值,会是用系统默认值。

  • repeated:表示该字段可以重复,可等同于动态数组。

    注意:required字段是永久性的,如果之后不使用该字段,或者该字段标识改为optional或repeated,那么使用就接口读取新协议时,如果发现没有该字段,会认为该消息不完整,会拒收或者丢弃该消息。

nanopb

Nanopb 是一个轻量级的 Protocol Buffers 实现,专为嵌入式系统和资源受限的环境设计。它允许开发者在这些环境中使用 Protocol Buffers 进行数据序列化和反序列化。在C语言以及一些嵌入式设备使用protobuf要用nanopb进行编译。
下载地址:添加链接描述
在这里插入图片描述

Nanopb运行库:

pb.h
pb_common.h和pb_common.c(始终需要)
pb_decode.h和pb_decode.c(用于解码消息)
pb_encode.h和pb_encode.c(编码消息所需)

协议描述:

person.proto(仅作为示例)
person.pb.c(自动生成,包含const数组的初始化程序)
person.pb.h(自动生成,包含类型声明

proto2和proto3区别

总的来说proto3比proto2支持跟多语言,但是更加简洁。去除了复杂的语法和特性。
必须指明版本

syntax = "proto3";

语法和字段定义:

版本2: 允许字段的默认值,并且每个字段可以使用optional、required和repeated关键字来定义其可选性。
版本3: 取消了required关键字,所有字段默认为optional,并且没有默认值的概念,字段值为未设置则默认是类型的零值(如数字为0,字符串为空等)。

keil中使用

1.先拿到 nanopb 的window 版本

解压 ,然后到如下目录,将其添加到系统环境变量
在这里插入图片描述

2.将文件添加到keil 工程目录

主要就是这7个
在这里插入图片描述
创建 student.proto 文件

syntax = "proto3"; 
package protobuf; // 编译命令带-v 的时候不能加这个,原因不知
message Person {  
    string name = 1;  
    int32 id = 2;  
    string email = 3;  
}  

string 类型有些特殊,在此创建一个student.options 文件,在里面为string类型指定其大小,不然会给string 生成为一个回调类型的 字段,用起来很麻烦 参考:添加链接描述

# student.options
Person.name max_size:16
Person.email  max_size:16

最后在当前目录运行cmd 执行 protoc --nanopb_opt=-v --nanopb_out=. student.proto,
即可生成student.pb.h 、student.pb.c
在这里插入图片描述
在student.pb.h 会生成一个结构体,后续就是操作这个结构体

/* Struct definitions */
typedef struct _Person {
    char name[16];
    int32_t id;
    char email[16];
} Person
	while(1)
	{
//		my_uart_dev->Send_Data((uint8_t *)&i, 1, 100);
//		osDelay(1000);
//		i++;
		Person my_preson = {0};
		Person my_input_preson = {0};
		memcpy(my_preson.email, "www.baidu.com", 16);
		memcpy(my_preson.name, "li xue dong", 16);
		my_preson.id = 1;

		o_stream = pb_ostream_from_buffer((pb_byte_t *)buff, sizeof(buff));
		pb_encode(&o_stream, Person_fields, &my_preson); // 编码
		
		i_stream = pb_istream_from_buffer((pb_byte_t *)buff, sizeof(buff));
		pb_decode(&i_stream, Person_fields, &my_input_preson);// 解码
		printf("email : %s , id :%d, name : %s \r\n",(uint8_t *)my_input_preson.email,
		my_input_preson.id, (uint8_t *)my_input_preson.name);
		osDelay(1000);
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值