protobuf | nanopb 在MCU平台的移植使用(小白版)

本文介绍了Nanopb,一种针对32位微控制器和低内存嵌入式系统的ProtocolBuffers轻量级C语言实现。文章重点讲解了如何为小白用户编译.proto文件并集成到项目中,以及提供了一个简单的编码和解码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概要

Nanopb 是 Google Protocol Buffers数据格式的纯 C 实现 。它针对 32 位微控制器,但也适用于内存限制严格(<10 kB ROM、<1 kB RAM)的其他嵌入式系统。用过ProtoBuf的人,再去理解nanopb就不难了。可以理解为ProtoBuf的C语言版本,适用于嵌入式的版本。

Nanopb is a plain-C implementation of Google's Protocol Buffers data format. It is targeted at 32 bit microcontrollers, but is also fit for other embedded systems with tight (<10 kB ROM, <1 kB RAM) memory constraints.

nanopb的维护还是很贴心的,即为喜欢“折腾”的人提供了源码和各种应用场景下的例程、脚本,官网也提供了适合“小白”使用的版本。

本文中,主要针对小白使用进行说明,因为你不需要给你的电脑配置任何环境和依赖库,这一点非常便捷。

基本步骤

To use the nanopb library, you need to do two things:

  1. Compile your .proto files for nanopb, using protoc.

  2. Include pb_encode.c, pb_decode.c and pb_common.c in your project.

就是两步:

  1. 把自己的proto文件编译为c语言的头文件和源文件;

  2. 把编译生成的文件和nanopb相关的头文件和源文件放到我们的项目文件中使用。

编译proto文件

WindowsLinux版本操作基本一致,以Windows为例。

首先从这里下载release版本。[Nanopb - downloads]

里,我们下载0.4.7WindowsLinux版本。

然后解压,只需要generator-bin这个文件夹即可。

然后再generator-bin的目录再新建2个文件夹,my_proto用于存放自己的待编译的proto文件,generated用于存放编译后的头文件和源文件,这样的目的是为了方便进行分类管理。

比如my_proto文件夹下面存放了2个proto文件。

然后打开终端,输入下面的命令: .\generator-bin\nanopb_generator.exe -I .\my_proto -D .\generated simple.proto simple2.proto -I制定proto文件的目录,-D是生成文件的目录。执行完成后,generated文件夹下有就生成了对应的头文件和源文件,如下图所示。

至此,编译proto的任务完成。

在项目代码中使用

把上文中编译到generated文件夹中的文件和generator-bin中的下面7个文件拷贝到项目中就可以编译了。

使用demo

examples有很多例子,这里不再赘述。

#include <stdio.h>
#include <pb_encode.h>
#include <pb_decode.h>
#include "simple.pb.h"

int main()
{
    /* This is the buffer where we will store our message. */
    uint8_t buffer[128];
    size_t message_length;
    bool status;

    /* Encode our message */
    {
        /* Allocate space on the stack to store the message data.
         *
         * Nanopb generates simple struct definitions for all the messages.
         * - check out the contents of simple.pb.h!
         * It is a good idea to always initialize your structures
         * so that you do not have garbage data from RAM in there.
         */
        SimpleMessage message = SimpleMessage_init_zero;

        /* Create a stream that will write to our buffer. */
        pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));

        /* Fill in the lucky number */
        message.lucky_number = 13;

        /* Now we are ready to encode the message! */
        status = pb_encode(&stream, SimpleMessage_fields, &message);
        message_length = stream.bytes_written;

        /* Then just check for any errors.. */
        if (!status)
        {
            printf("Encoding failed: %s\n", PB_GET_ERROR(&stream));
            return 1;
        }
    }

    /* Now we could transmit the message over network, store it in a file or
     * wrap it to a pigeon's leg.
     */

    /* But because we are lazy, we will just decode it immediately. */

    {
        /* Allocate space for the decoded message. */
        SimpleMessage message = SimpleMessage_init_zero;

        /* Create a stream that reads from the buffer. */
        pb_istream_t stream = pb_istream_from_buffer(buffer, message_length);

        /* Now we are ready to decode the message. */
        status = pb_decode(&stream, SimpleMessage_fields, &message);

        /* Check for errors... */
        if (!status)
        {
            printf("Decoding failed: %s\n", PB_GET_ERROR(&stream));
            return 1;
        }

        /* Print the data contained in the message. */
        printf("Your lucky number was %d!\n", (int)message.lucky_number);
    }

    return 0;
}

引用

code:https://github.com/nanopb/nanopb

官网: jpa.kapsi.fi/nanopb/

移植报错解决

这里使用的是c99,所以需要定义

#define PB_C99_STATIC_ASSERT

/* Test that PB_STATIC_ASSERT works
 * If you get errors here, you may need to do one of these:
 * - Enable C11 standard support in your compiler
 * - Define PB_C99_STATIC_ASSERT to enable C99 standard support
 * - Define PB_NO_STATIC_ASSERT to disable static asserts altogether
 */
PB_STATIC_ASSERT(1, STATIC_ASSERT_IS_NOT_WORKING)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流浪_彩虹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值