modules: nanopb: introduce new module

Add the nanopb library and generator tools as a module.
Nanopb is a small code-size Protocol Buffers implementation in ansi C.
It is especially suitable for use in microcontrollers,
but fits any memory restricted system.

Nanopb home: https://jpa.kapsi.fi/nanopb/

Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
This commit is contained in:
Pieter De Gendt 2021-03-10 13:34:57 +01:00 committed by Carles Cufí
commit b6979736ca
13 changed files with 318 additions and 0 deletions

View file

@ -54,6 +54,9 @@ comment "hal_nordic module not available."
comment "Trusted-firmware-m module not available."
depends on !ZEPHYR_TRUSTED_FIRMWARE_M_MODULE
comment "Nanopb module not available."
depends on !ZEPHYR_NANOPB_MODULE
# This ensures that symbols are available in Kconfig for dependency checking
# and referencing, while keeping the settings themselves unavailable when the
# modules are not present in the workspace

View file

@ -0,0 +1,61 @@
# Copyright (c) 2021, Basalte bv
#
# SPDX-License-Identifier: Apache-2.0
if(CONFIG_NANOPB)
set(NANOPB_DIR ${ZEPHYR_CURRENT_MODULE_DIR})
find_program(PROTOC protoc)
if(NOT PROTOC)
message(FATAL_ERROR "'protoc' not found, please ensure protoc is installed\
and in path. See https://docs.zephyrproject.org/latest/samples/modules/nanopb/README.html")
endif()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${NANOPB_DIR}/extra)
find_package(Nanopb REQUIRED)
zephyr_library()
zephyr_include_directories(${NANOPB_DIR})
zephyr_library_sources(
${NANOPB_DIR}/pb_common.c
${NANOPB_DIR}/pb_encode.c
${NANOPB_DIR}/pb_decode.c
)
zephyr_compile_definitions(
PB_MAX_REQUIRED_FIELDS=${CONFIG_NANOPB_MAX_REQUIRED_FIELDS})
zephyr_compile_definitions_ifdef(
CONFIG_NANOPB_ENABLE_MALLOC
PB_ENABLE_MALLOC
)
zephyr_compile_definitions_ifdef(
CONFIG_NANOPB_NO_ERRMSG
PB_NO_ERRMSG
)
zephyr_compile_definitions_ifdef(
CONFIG_NANOPB_BUFFER_ONLY
PB_BUFFER_ONLY
)
zephyr_compile_definitions_ifdef(
CONFIG_NANOPB_WITHOUT_64BIT
PB_WITHOUT_64BIT
)
zephyr_compile_definitions_ifdef(
CONFIG_NANOPB_ENCODE_ARRAYS_UNPACKED
PB_ENCODE_ARRAYS_UNPACKED
)
zephyr_compile_definitions_ifdef(
CONFIG_NANOPB_VALIDATE_UTF8
PB_VALIDATE_UTF8
)
endif()

59
modules/nanopb/Kconfig Normal file
View file

@ -0,0 +1,59 @@
# Copyright (c) 2021 Basalte bv
# SPDX-License-Identifier: Apache-2.0
config ZEPHYR_NANOPB_MODULE
bool
menuconfig NANOPB
bool "Nanopb Support"
help
This option enables the Nanopb library and generator.
if NANOPB
config NANOPB_ENABLE_MALLOC
bool "Enable malloc usage"
help
This option enables dynamic allocation support in the decoder.
config NANOPB_MAX_REQUIRED_FIELDS
int "Max number of required fields"
default 64
help
Maximum number of proto2 required fields to check for presence.
Default and minimum value is 64.
config NANOPB_NO_ERRMSG
bool "Disable error messages"
help
Disable error message support to save code size. Only error
information is the true/false return value.
config NANOPB_BUFFER_ONLY
bool "Buffers only"
help
Disable support for custom streams. Only supports encoding and
decoding with memory buffers. Speeds up execution and slightly
decreases code size.
config NANOPB_WITHOUT_64BIT
bool "Disable 64-bit integer fields"
help
Disable support of 64-bit integer fields, for old compilers or
for a slight speedup on 8-bit platforms.
config NANOPB_ENCODE_ARRAYS_UNPACKED
bool "Encode arrays unpacked"
help
Encode scalar arrays in the unpacked format, which takes up more
space.
Only to be used when the decoder on the receiving side cannot
process packed arrays, such as protobuf.js versions before 2020.
config NANOPB_VALIDATE_UTF8
bool "Validate UTF-8"
help
Check whether incoming strings are valid UTF-8 sequences.
Adds a small performance and code size penalty.
endif # NANOPB

View file

@ -24,6 +24,7 @@ Samples and Demos
posix/*
kernel/*
tfm_integration/tfm_integration.rst
modules/*
.. comment
To add a new sample document, please use the template available under

10
samples/modules/index.rst Normal file
View file

@ -0,0 +1,10 @@
.. _module-samples:
External Module Samples
#######################
.. toctree::
:maxdepth: 1
:glob:
**/*

View file

@ -0,0 +1,15 @@
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.13.1)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(nanopb_sample)
nanopb_generate_cpp(proto_sources proto_headers RELPATH .
src/simple.proto
)
# we need to be able to include generated header files
zephyr_library_include_directories(${CMAKE_CURRENT_BINARY_DIR})
FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${proto_sources} ${app_sources})

View file

@ -0,0 +1,55 @@
.. _nanopb_sample:
Nanopb sample
#############
Overview
********
A simple protocol buffer sample using Nanopb for serializing structured data
to platform independent raw buffers or streams.
Requirements
************
Nanopb uses the protocol buffer compiler to generate source and header files,
make sure the ``protoc`` executable is intalled and available.
.. tabs::
.. group-tab:: Ubuntu
Use ``apt`` to install dependency:
.. code-block:: bash
sudo apt install protobuf-compiler
.. group-tab:: macOS
Use ``brew`` to install dependency:
.. code-block:: bash
brew install protobuf
.. group-tab:: Windows
Use ``choco`` to install dependency:
.. code-block:: console
choco install protoc
Building and Running
********************
This application can be built as follows:
.. zephyr-app-commands::
:zephyr-app: samples/modules/nanopb
:host-os: unix
:board: qemu_x86
:goals: run
:compact:

View file

@ -0,0 +1 @@
CONFIG_NANOPB=y

View file

@ -0,0 +1,13 @@
sample:
description: Nanopb sample, with a simple proto
buffer
name: Simple nanopb
common:
harness: console
harness_config:
type: one_line
regex:
- "Your lucky number was 13!"
tests:
sample.modules.nanopb:
tags: samples nanopb

View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2011 Petteri Aimonen
* Copyright (c) 2021 Basalte bv
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <sys/printk.h>
#include <pb_encode.h>
#include <pb_decode.h>
#include "src/simple.pb.h"
bool encode_message(uint8_t *buffer, size_t *message_length)
{
bool status;
/* 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;
if (!status) {
printk("Encoding failed: %s\n", PB_GET_ERROR(&stream));
}
return status;
}
bool decode_message(uint8_t *buffer, size_t message_length)
{
bool status;
/* 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) {
/* Print the data contained in the message. */
printk("Your lucky number was %d!\n", (int)message.lucky_number);
} else {
printk("Decoding failed: %s\n", PB_GET_ERROR(&stream));
}
return status;
}
void main(void)
{
/* This is the buffer where we will store our message. */
uint8_t buffer[SimpleMessage_size];
size_t message_length;
/* Encode our message */
if (!encode_message(buffer, &message_length)) {
return;
}
/* 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. */
decode_message(buffer, message_length);
}

View file

@ -0,0 +1,8 @@
// A very simple protocol definition, consisting of only
// one message.
syntax = "proto2";
message SimpleMessage {
required int32 lucky_number = 1;
}

View file

@ -17,3 +17,6 @@ Pillow
# can be used to sign a Zephyr application binary for consumption by a bootloader
imgtool>=1.7.1
# used by nanopb module to generate sources from .proto files
protobuf

View file

@ -145,6 +145,9 @@ manifest:
repo-path: mcuboot
path: modules/tee/tfm-mcuboot
revision: v1.7.2
- name: nanopb
path: modules/lib/nanopb
revision: d148bd26718e4c10414f07a7eb1bd24c62e56c5d
self:
path: zephyr