当前位置: 首页 > 工具软件 > nanopb > 使用案例 >

【嵌入式Nanopb协议】——[1]总览

栾鸣
2023-12-01

Nanopb:具有小代码量的协议缓冲区

Nanopb是一个ANSI-C库,用于以Google的协议缓冲区格式编码和解码消息,而对RAM和代码空间的要求最低。

它主要适用于32位微控制器。

文档版本

本文档适用于nanopb 0.4.0及更高版本。有关旧版本的文档,请参见此处

整体结构

对于运行时程序,对于类型声明,始终需要pb.h,对于基本函数,始终需要pb_common.h / c。根据您是否要编码,解码还是同时进行编码,还需要pb_encode.h / cpb_decode.h / c

高级编码和解码功能采用指向pb_msgdesc_t结构的指针,结构描述了消息结构的字段。通常,您希望这些文件从.proto文件自动生成。工具脚本nanopb_generator.py完成了此任务。

因此,典型的项目可能包含以下文件:

  1. Nanopb运行库:

    • pb.h
    • pb_common.h和pb_common.c(始终需要)
    • pb_decode.h和pb_decode.c(用于解码消息)
    • pb_encode.h和pb_encode.c(编码消息所需)
  2. 协议描述(可以有很多):

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

特点和局限性

特征

  1. 纯C运行
  2. 小代码量(5–10 kB,取决于处理器和编译选项,以及任何消息定义)
  3. 小型ram用法(通常为〜300字节堆栈,加上任何消息结构)
  4. 允许指定字符串和数组的最大大小,以便可以静态分配它们。
  5. 不需要malloc:所有内容都可以静态分配或在堆栈上分配。可选的malloc支持。
  6. 您可以单独使用编码器或解码器将代码大小减半。
  7. 支持大多数protobuf功能,包括:所有数据类型,嵌套子消息,默认值,重复和可选字段,一个,打包数组,扩展字段。
  8. 回调机制,用于处理大于可用RAM容量的消息。
  9. 广泛的测试集。

局限性

  1. 为了缩减代码大小,已经牺牲了一些速度。
  2. 编码侧重于写入流。仅对于内存缓冲区,可以使其效率更高。
  3. 不支持不赞成使用的协议缓冲区功能,称为“组”。
  4. 生成的结构中的字段按标记号排序,而不是.proto文件中的自然排序。
  5. 解码和重新编码消息时,不会保留未知字段。
  6. 不支持反射(运行时自省)。例如,您不能通过在字符串中给出名称来请求字段。
  7. 数字数组始终被编码为压缩,即使未在.proto中标记为压缩。
  8. 仅在回调和malloc模式下支持消息之间的循环引用。
  9. Nanopb在版本之间没有稳定的ABI(应用程序二进制接口),因此将其用作共享库(.so / .dll)需要格外小心。

入门

对于初学者,请考虑以下简单消息:

message Example {
   required int32 value = 1;
}

将其保存在message.proto中并进行编译:

user@host:~$ python nanopb/generator/nanopb_generator.py message.proto

您现在应该在message.pb.h中

typedef struct {
   int32_t value;
} Example;

extern const pb_msgdesc_t Example_msg;
#define Example_fields &Example_msg

然后,您必须包括nanopb头文件和生成的头文件:

#include <pb_encode.h>
#include "message.pb.h"

现在在您的主程序中执行以下操作以对消息进行编码:

Example mymessage = {42};
uint8_t buffer[10];
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
pb_encode(&stream, Example_fields, &mymessage);

之后,缓冲区将包含编码后的消息。消息中的字节数存储在stream.bytes_write中。您可以将消息提供给protoc --decode = Example message.proto以验证其有效性。

有关简单案例的完整示例,请参见examples / simple / simple.c。有关具有网络接口的更复杂示例,请参见examples / network_server子目录。

编译器要求

Nanopb应该使用大多数与ansi-C兼容的编译器进行编译。但是,它需要一些头文件才能使用:

  1. string.h,具有以下功能:strlenmemcpymemset
  2. stdint.h,用于int32_t等的定义。
  3. stddef.h,用于定义size_t
  4. stdbool.h,用于定义bool
  5. limits.h,用于定义CHAR_BIT

如果编译器没有随附这些头文件,则可以使用extra / pb_syshdr.h文件。它包含有关如何提供依赖关系的示例。您可能需要对其进行一些修改以适合您的自定义平台。

要使用pb_syshdr.h,请将 PB_SYSTEM_HEADER定义为“ pb_syshdr.h”(包括引号)。同样,您可以提供一个自定义包含文件,该文件应提供上面列出的所有依赖项。

运行测试用例

广泛的单元测试和测试用例包含在测试文件夹下。

要构建测试,您将需要scons构建系统。这些测试应可在大多数平台上运行。Windows和Linux版本均经过定期测试。这些测试还支持嵌入式目标:定期测试STM32(ARM Cortex-M)和AVR版本。

除了构建系统之外,您还需要有效的Google Protocol Buffers 协议编译器以及Protocol Buffers的Python绑定。

安装依赖项的最简单方法是使用Python软件包管理器pip,该软件包可在Python支持的所有平台上运行:

pip install scons protobuf grpcio-tools
 类似资料: